I just made a fool of myself: I wanted to trace the execution of a process, and in order to do this, I had written a function trace(), which contains the following line of code:
printf("%s[%s:%d], %s\n", __FUNCTION__, __FILE__, __LINE__, s_message);
I hoped to see in which function I was, what file and what line within that file, but I just saw that information of the file where I programmed that trace() function.
Is it possible, is there some #define or so, to tell the C compiler to take the mentioned macros from the parent of the calling function?
You need to wrap it in a macro, e.g.:
void _trace(char const *function, char const *file, long line, char const *message) {
printf("%s[%s:%ld], %s\n", function, file, line, message);
}
#define trace(message) _trace(__FUNCTION__, __FILE__, __LINE__, (message))
As others have stated, you should have a macro for that.
The reason for this is that all 3 used macros get expanded at pre-processing stage of compilation, and they will be replaced by the corresponding information, as it is encountered. That's the reason your actual output is where the trace() is implemented.
You could change your current trace() implementation to receive const char * for function name, file, and line. Then, have a macro, say mTrace, that expands to calling the initial trace function, passing exactly __FUNCTION__,__FILE__, __LINE__. Of course, your mTrace could get another parameter, the actual message you want to add, and pass it further to trace().
Hth
Related
I'm using this statement now to switch between small and slightly more extensive error messages in my C code:
#ifdef COMPACTC
error_code ((uint16_t) init_cascade, 5);
#else
error_message (__func__, "cascades malloc failed");
#endif
(it's part of an embedded C code library, so I often don't have the memory available to store the error message strings).
In the first case (COMPACTC defined) I output only a function address and and error number. In the second case I output the full function name and a human-readable error message.
Since I'm copying this snippet all over my code now, I hope I can replace it with a single macro, which I can use like this:
error (init_cascade, "cascades malloc failed", 5)
and provides the correct C code depending on COMPACTC being defined or not.
Maybe it's even possible to have the current function (or some unique identifier) automatically derived from the current location, though I think the preprocessor doesn't know which function's scope it's currently in.
Another improvement would be if a unique error code (5 in this case, which is based on the return value) could be automatically generated from the error message (like a hash value or something).
Then the macro call could be as simple as this:
error ("cascades malloc failed")
Of course, when using hashes, I would need some sort of reference (file/comment) to its original message.
Context: error messages on AVR 8-bits MCU
About the context of this question: This code is written for the ATmega168 (having only 2k of RAM), and AFAIK there's no good/recent emulator available for Linux. So I'm trying to find a good way to produce error messages/codes without the strings eating all of my memory.
Alternative: C function?
A completely different, probably more flexible solution would be to define a C function error (function, message, code) and move the #if/#else/#endif construction to its body.
I'm not sure though whether a string literal is compiled in by gcc if it is referred to in a function call but never used inside the function body.
Edit: I just tested this idea: using a string literal in a call but not in the body still has it added to the executable by gcc, so this "alternative" doesn't seem to work.
This should actually be fairly easy:
#ifdef COMPACTC
# define COMBINED_ERROR(function, message, size) error_code((uint16_t)function, size)
#else
# define COMBINED_ERROR(function, message, size) error_message (__func__, message)
#endif
and now you can write:
COMBINED_ERROR(init_cascade, "cascades malloc failed", 5);
For the first part I suggest:
#ifdef COMPACTC
# define error(par1, ...) error_code((uint16_t)par1, __VA_ARGS__)
#else
# define error(par1, ...) error_message (__func__, par1, __VA_ARGS__)
#endif
With this solution you can define as many params as you like.
For the second requirements consider to use macro to insert specific code. Consider the following macro:
#define CallWithError(fnc, ...) { \
int RetCode = fnc(__VA_ARGS__); \
if (RetCode) \
error(init_cascade, "cascades malloc failed", RetCode); \
}
In this case you can use the macro to call the function foo and automatically generate error:
CallWithError(foo, 1, "hello");
This will expand in:
{
int RetCode = foo(1, "hello");
if (RetCode)
error(init_cascade, "cascades malloc failed", RetCode);
}
It seems that for printf-style debugging people always use preprocessor macros. Is there anything wrong with a solution similar to this one?
void debug(char *msg) {
#ifdef DEBUG
printf("%s", msg);
#endif
}
Usually so that they can do something like this:
#define DEBUG(MSG) printf("[%s:%i] %s\n", __FILE__, __LINE__, (MSG))
Since it's so useful to have the exact source of a debug message right there in the log, this is a pretty common pattern. But if you used a function, like so:
void DEBUG(const char *MSG) {
printf("[%s:%i] %s\n", __FILE__, __LINE__, (MSG));
}
Then you'd only ever get to see the filename and line number corresponding to the printf() call in DEBUG(), and never those of the code that called DEBUG().
1) Your code will break if msg is %d or such, because printf expects a format string. printf("%s", msg); is better.
2) Not really. Macros are overused unless you're micro-optimizing (e.g. for code size). Functions are easier to debug with since you can do stuff like stop in debug in your debugger. There's a zillion other things that are tricky with macros. See http://www.brainbell.com/tutors/c/Advice_and_Warnings_for_C/Macros_and_Miscellaneous_Pitfalls.html
3) As #Jonathan Grynspan pointed out - the macro form is easier to use with FILE , LINE . In my opinion developers like taking shortcuts in typing that make their code harder to maintain for others later, and ironically harder to debug themselves later. Best practice IMO: type extra, make your code easy to debug and easy to run in a debugger, and use a function with signature debug(const char* msg, const char* FILE_LOC, unsigned LINE_NUMBER)
If one uses a DEBUG macro, then changing a single #define statement or compilation option and recompiling can make all of the debug code vanish from the executable. By contrast, if one uses a DEBUG() function, then every invocation will generate code to call the function, whether or not the function itself does anything.
As well as the use of __FILE__, __LINE__, you should also compare the following:
#ifdef NDEBUG
#define DEBUG_PRINT(...) ((void)0)
#else
#define DEBUG_PRINT(...) printf(__VA_ARGS__)
#endif
Against your function:
void debug(const char* msg) {
#ifndef NDEBUG
printf("%s", msg);
#endif
}
With the macro, I can write:
DEBUG_PRINT("Expected %d, got %d\n", correct_value, result);
With the function, I have to go to some effort to construct one or more strings using my integers, and call the function one or more times. In release mode the function does nothing, so the string is unused. The optimizer might manage to eliminate the code to construct it, or then again it might not. With the macro there's no doubt.
That said, you could write your debug function to do the right thing with varargs. But your function as written will hit this problem eventually, and you'll have to add a debugf.
I have the following macro function in vanilla C:
#define GLOG(format_string, ...) { \
const char *file = strrchr(__FILE__, '/'); \
char format[256] = "%s:%s!%d\t"; \
strncat(format, format_string, 248); \
strcat(format, "\n"); \
printf(format, __FUNCTION__, file ? file : __FILE__, __LINE__, ##__VA_ARGS__); \
}
which lets me print a debug message containing the current function, file and line number, e.g.
GLOG("count=%d", count);
might print
do_count:counter.c!123 count=456
How can I modify the function to print all local variables if caller omits format_string? e.g.
GLOG();
might print
do_count:counter.c!123 count=456, message="Hello world", array=[7, 8] structure={ptr=0xACE0FBA5E, coord={x=9, y=0}}
If that's not possible, how can I modify it to print just the current function, file and line number? e.g.
do_count:counter.c!123
As is, this returns an error:
error: expected expression before ‘,’ token
as the strncat line is simply
strncat(format, , 248);
First, inspecting all the local variables at runtime by the process itself seems impossible because C doesn't have any means for reflection.
Second, you would be much better off if you wrote the logging macro like that:
#include <stdio.h>
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define GLOGF(fmt, ...) \
printf("%s:%s " fmt "\n", __func__, __FILE__ "!" TOSTRING(__LINE__), ##__VA_ARGS__)
int main (void) {
/* main:test.c!xx count=5 */
GLOGF("count=%d", 5);
/* main:test.c!xx */
GLOGF();
return 0;
}
It is simpler and doesn't incur any additional runtime overhead since the string is concatenated at compile-time.
Also note that I have used __func__ instead of __FUNCTION__, because the latter is non-standard.
I found this link in this answer. It might help you with the first part of the question.
The second, how to get all local variables, is much harder, if not impossible. The reason is that the code, when compiled, doesn't actually have variables, it just have offsets into a memory area (the stack.) It might be possible that your compiler have internal functions that can be used to inspect the stack, but then you only have possible values not the names of the variables. The only solution I see it to use special pre-processor macros to declare local variables, and then a list of structures to represent them for introspection, which will be a lot of both runtime and memory overhead.
As others here have mentioned, C does not have reflection features, and therefore you are not going to be capable of capturing the local variables in a macro call. That being said, if you want something to conditionally happen with a macro depending on if there are or are not any arguments to the macro invocation (i.e., your "non-null" and "null" arguments), then you can do something like the following:
#include <string.h>
#define NULL_IDENT ""
#define IDENT(ident_name) #ident_name
#define MACRO(ident_name) \
if (strcmp(NULL_IDENT, IDENT(ident_name)) == 0) { \
/* add code for a null argument passed to the macro */ } \
else { \
/* add code for a non-null argument passed to the macro */ }
Based on Blagovest Buyukliev's answer, I've come up with the following solution for part 2:
#define GLOG(fmt, ...) do { const char *fn = strrchr(__FILE__, '/'); \
printf("%s:%s!%d\t"fmt"\n",__func__,fn?++fn:__FILE__,__LINE__,##__VA_ARGS__);\
} while(0)
using the preprocessor's string concatenation to simply concatenate a null string if the parameter is omitted.
Additionally, I added the do {...} while(0) to swallow the trailing semicolon so that the following if...else works:
if (...)
GLOG();
else
/* do something else */
(idea from http://gcc.gnu.org/onlinedocs/cpp/Swallowing-the-Semicolon.html ).
What MACRO can be used to switch off printf statements, rather than removing them all for deployment builds, I just want to switch them off, skip them, ignore them.
EDIT: I personally use gcc, but code is part of a larger project which will be compiled on a Panda board running Ubuntu.
Not exactly what you ask for, but I use this construct in my code for debug output when I do not have a proper logging system handy:
#if 1
#define SPAM(a) printf a
#else
#define SPAM(a) (void)0
#endif
So I can do this all over my code
SPAM(("foo: %d\n", 42));
and then disable all of them by changing 1 to 0 in #if above.
But if you have variadic macro support in all compilers that you write code for, then you may go for other answers and just redefine printf. (That being said, I find it useful to distinct debugging prints from regular ones in code — using a different function name helps readability.)
Note that you also can redirect stdout to the /dev/null, but I assume that you want to get rid from runtime overhead as well.
#ifdef IGNORE_PRINTF
#define printf(fmt, ...) (0)
#endif
See also C #define macro for debug printing which discusses some important issues closely related to this.
Two options, either:
#define printf(...)
(requires C99 variadic macro parameters), you need to put it in some common header file which is never included before stdio.h, if there is one..
Or you can tell the linker to link it to something else, in GCC you would define
int wrap_printf(void) {return 0;}
and link using
--wrap printf
All that said, you should probably not be using printf for printing debug output, but rather a macro or utility function (which in turn can use printf if you'd like) which you have better control over.
Hope that helps.
If you want to avoid the potential warning that Jonathan's answer may give you and if you don't mind an empty call to printf you could also do something like
#define printf(...) printf("")
This works because C macros are not recursive. The expanded printf("") will just be left as such.
Another variant (since you are using gcc) would be something like
inline int ignore_printf(char const*, ...)
__attribute__ ((format (printf, 1, 2)));
inline int ignore_printf(char const*, ...) { return 0; }
#define printf ignore_printf
and in one compilation unit
int ignore_printf(char const*, ...)
I use to prefix the debug printf()s (not all of them) with PDEB.
For the debug builds, I compile with -DPDEB= (nothing)
For the release builds, I compile with -DPDEB="0&&" or -DPDEB="0 && "
That way, the following code (test.c):
#include <stdio.h>
void main(void) {
printf("normal print\n");
PDEB printf("debug print\n");
}
outputs:
either (in release mode):
normal print
either (in debug mode):
normal print
debug print
Ideally, one could aim for turning the PDEB into the "//" (comments mark), except that this is not possible under the standard pre-/processing chain.
Another possibility would be something like freopen("/dev/null", "w", stdout);
This doesn't exactly disable printf though -- it's roughly equivalent to running your program with stdout redirected to /dev/null, like: ./myprog > /dev/null at the shell prompt.
I included #define printf // in common header file. It will suppress all the printf.
Below simple function serves the purpose, I use the same.
int printf(const char *fmt, ...)
{
return (0)
}
Use this macro to enable or disable the printf.
//Uncomment the following line to enable the printf function.
//#define ENABLE_PRINTF
#ifdef ENABLE_PRINTF
#define DEBUG_PRINTF(f,...) printf(f,##__VA_ARGS__)
#else
#define DEBUG_PRINTF(f,...)
#endif
Then call "DEBUG_PRINTF" instead of "printf".
For example:
DEBUG_PRINTF("Hello world: %d", whateverCount);
I have used two macros for this. The first one defines the condition to print. In this simple example we print any time the parameter is not zero. More complex expressions can be used.
The second one determines, based on the first macro, to call or not printf.
If the condition can be determined by the compiler (with the right optimization settings) no code is generated.
If the condition cannot be determined at compile time then will be at run time. One of the advantages of this method is that if printf is not going to happen then the whole printf is not evaluated avoiding many conversions to string that can happen in a complex printf statement.
#define need_to_print(flag) ((flag) != 0))
#define my_printf(debug_level, ...) \
({ \
if(need_to_print(debug_level)) \
printf(__VA_ARGS__); \
})
to use it call my_printf instead of printf and add a parameter at the beginning for the print condition.
my_printf(0, "value = %d\n", vv); //this will not print
my_printf(1, "value = %d\n", vv); //this will print
my_printf(print_debug, "value = %d\n", vv); //this will print if print_debug != 0
the ( ... ) parenthesis surrounding the macro make it a single statement.
I wanna know if there is any way to know where the function currently in execution was called, this is, in what file and line.
I'm using C language, and I'm looking for something similar to __FUNCTION__, __LINE__ or __FILE__ macros.
Rename your function
void Function(param1)
{
}
to
void Function_debug(param1, char * file, char * func, unsigned long line)
{
}
Then #define a macro like this:
#define Function(param1) Function_debug(param1, __FILE__, __FUNCTION__, __LINE__)
There's nothing in C itself that would give you this information. You could either trace the information yourself (upon entry/exit) or rely on platform specific APIs to walk the call stack and determine the calling function, but not much more.
__FILE__, __LINE__ etc are preprocessor macros which can easily be expanded to the correct value at compile time. A function may get called from many possible places, so that can't be done via the preprocessor. Finding out the caller's name would be very difficult; it involves walking the stack and matching addresses to symbols.
If you can live with a small hack, this might work (untested):
/* Add a called argument to your function */
void _myFunction(char *caller, int more_args)
/* And define a macro that adds it automagically */
#define myFunction(a) _myFunction(__FUNCTION__, a)
There isn't anything that is supported in all implementations that will do what you want. I have occasionally found myself in the same situation, where I needed to track callers for a few methods and did something like the following:
#ifdef TRACKBACK
int foo(int arg1, int arg2, const char * file, int line)
{
SEND_TO_LOG("foo", file, line);
#else
int foo(int arg1, int arg2)
{
#endif
...
...
Of course, it makes for a bit of a headache at the calling end, so you'll want to do something like:
#ifdef TRACKBACK
#define TRACKING, __FILE__, __LINE__
#else
#define TRACKING
#endif
Then the call:
foo(arg1, arg2 TRACKING); //note the lack of the comma
It does the trick when all else fails.
If you need to know it at runtime, I don't think it's possible.
If you need to know it at debugtime, you can place a breakpoint on the function you want, and then, using GDB (using bt command) or Vistual Studio's debugger, inspect the current STACK TRACE.
This is actually a bit more complicated to do. Your best bet is to get a backtrace on a debugger, or find something similar to pstack for your platform. The manual way would involve traversing the call stack and using debug symbols to translate that to files and lines.
You can use logs .
#define BEGIN_FUNC(X,Y,Z) printf("Function %s Entered at line %d from file %s",X,Z,Y)
#define END_FUNC(X) printf("Function %s Exited at line %d from file %s",X,Z,Y)
foo()
{
BEGIN_FUNC(__func__,__FILE__,__LINE__);
//Your code here
END_FUNC(__func___FILE__,__LINE__);
}
OR
Use bt in gdb. I call it backtrace.