How to redefine print function at runtime in C - c

I'm currently using a simple preprocessor switch to disable/enable my debug statements. I have printf retargeted to the UART output, and then define my print function in a globally included header (globals.h) to make it easy to disable all debugging like this:
#ifdef USE_UART
#define MY_PRINT(...) printf(__VA_ARGS__)
#else
#define MY_PRINT(...)
#endif
All my application files can then print debug messages over UART like this:
MY_PRINT("\t<<Battery Voltage: %d>>\r\n", vBat);
What I'm trying to do is have this be switched by external input (ie a button press) during run time. For example something like this:
void my_print(const char * pString){
if (uart_mode == UART_ON){
printf(pString);
}
}
Where uart_mode could be toggled via the external input. I'm having trouble figuring out how to pass variable arguements properly into printf through this function. Is this possible? Is there a better way to do it?

A decent approach that avoids conditionals at runtime (though it's still dynamic dispatch) and mimics function calls precisely (because it is a function call) would be:
typedef int (*printf_func_t)(const char *, ...);
int dummy_printf(const char *format, ...) {
return 0;
}
/* Set initial value based on initial uart_mode */
printf_func_t dynamic_printf = uart_mode == UART_ON ? &printf : &dummy_printf;
In some other toggle code (where uart_mode is changed), you'd just test and reassign:
dynamic_printf = uart_mode == UART_ON ? &printf : &dummy_printf;
Actual users then always call dynamic_printf in place of printf, and it calls whichever function is currently assigned to the function pointer. No read or test of uart_mode occurs when printing, it just calls whatever function is found at the time.

How about something like this:
#define MY_PRINT(...) \
do { \
if (uart_mode == UART_ON) \
printf(__VA_ARGS__); \
} while(0)

As David Schwartz said, that's what vprintf is for.
#include <stdarg.h>
void my_print(const char * pString, ...){
va_list args;
va_start(args, pString);
if (uart_mode == UART_ON){
vprintf(pString, args);
}
va_end(args);
}

Related

Printing Debug statements at runtime in C per function

I want to understand if there is a way to print debug statements for Particular method in C program.
For example:
Say I have a main function which calls other 3 functions abc(), def() and xyz(). Each of these methods has some print statements for debug logging purpose. If I enable the debug macro currently all the functions debug messages are getting printed, ehich creates a large log file. Say I am having some issue in function xyz() and I just want to turn on the debug statements of this function, how I can achieve this in C?
For a very simple solution, you might be able to do it with conditional compilation and naming your macros differently depending on what they will be use for (or from).
For example you could have something like (pseudo-code):
#ifdef ENABLE_LOG_ABC
# define LOG_ABC(...) real_logging_function(...)
#else
# define LOG_ABC(...) /* empty */
#endif
Then add something similar for the def and xyz functions.
To enable logging for only the abc function, only define ENABLE_LOG_ABC but no other when building. To enable for abc and xyz then define both ENABLE_LOG_ABC and ENABLE_LOG_XYZ.
With that said, if you want more advanced control and possibly by able to change such things at rtun-time, then I really recommend you try to find a third-part library which can do it for you.
A solution without macros but requiring C coding and using an environment variable that avoids to recompile:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void mylog(char *fc, char *msg)
{
char *debug;
debug = getenv("DEBUG");
if (debug != NULL)
{
if (strcmp(fc, "abc") == 0 && strstr(debug, ":abc") != NULL)
printf("%s", msg);
if (strcmp(fc, "def") == 0 && strstr(debug, ":def") != NULL)
printf("%s", msg);
if (strcmp(fc, "xyz") == 0 && strstr(debug, ":xyz") != NULL)
printf("%s", msg);
}
}
void abc()
{
mylog("abc", "entry abc\n");
mylog("abc", "exit abc\n");
}
void def()
{
mylog("def", "entry def\n");
mylog("def", "exit def\n");
}
void xyz()
{
mylog("xyz", "entry xyz\n");
mylog("xyz", "exit xyz\n");
}
int main(int argc, char **argv)
{
abc();
def();
xyz();
return 0;
}
Execution:
$ export DEBUG=:xyz
$ ./debug
entry xyz
exit xyz
$ export DEBUG=:abc:xyz
$ ./debug
entry abc
exit abc
entry xyz
exit xyz
This is what I like to do:
#define LOG_ABC 1
#define LOG_DEF 0
#define LOG_XYZ 0
void mylogger(const char *funcname, const char *fmt, ...)
{
if ((strcmp(funcname, "abc") == 0 && LOG_ABC) ||
(strcmp(funcname, "def") == 0 && LOG_DEF) ||
(strcmp(funcname, "xyz") == 0 && LOG_XYZ))
{
va_list ap;
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
}
}
#define MYLOG(fmt, ...) mylogger(__FUNCTION__, fmt, __VA_ARGS__);
void abc(char *name) {
MYLOG("Hello %s\n", name);
}
void def(int x) {
MYLOG("Received x = %d\n", x);
}
//... and so on
Simply change the LOG_ABC /LOG_DEF / LOG_XYZ to enable disable logging from each function.
Infact in my own projects I use a variation of this. I also pass __FILE__ and __LINE__ so that the logger can also show me the file and line number of the log message - makes it easy for debugging.
More importantly, instead of using the function name, I define log categories, and log severity. So my logging looks like this:
MYLOG(LOG_DATAPATH, LOG_WARNING, "My log message %d %s", x, y);
And I can enable and disable individual categories, and also specify the minimum severity.

C Get function line number from within 2 function calls

In the process of developing a small SDK, I need to create an "error handler". To make more effective I want to get the line number where the function was called and I don't know if it's possible in C (using GCC for compiling).
When a SDK function is called, the SDK function itself will call the error handler function if an error occurred.
With that I'd like to know if there is a way to know the line number from the user source code that called the function.
Example :
User.c :
main{ CallSDKFunction(); }
SDK.a file :
void CallSDKFunction( void ){ if ( ERROR ){ CallERRORHandler(); } }
...
...
...
void CallERRORHandler( void ){ // Here I want to know in which line in user.c the CallSDKFunction was called}
One approach is to pass the __FILE__ and __LINE__ to the SDK function, and then have the SDK function pass them on to the error handler function. However, the user won't want to be bothered with that, so you need to define a macro in the SDK's header file that hides the details. The macro would look like this
#define CallSDKFunction(a,b) actualSDKFunction( __FILE__, __LINE__, a, b )
The user would call the SDK with code like this. Note that the user doesn't need to know that the __FILE__ and __LINE__ are being passed to the SDK function. The macro takes care of that.
int main( void )
{
int a = 3;
int b = 4;
int result = CallSDKFunction( a, b );
printf( "%d\n", result );
}
And the SDK implementation would be something like this
int actualSDKFunction( const char *fileStr, int lineNum, int a, int b )
{
if ( a+b > 5 )
CallERRORHandler( fileStr, lineNum );
return( a+b );
}
void CallERRORHandler( const char *fileStr, int lineNum )
{
printf( "Bad values in file %s at line %d\n", fileStr, lineNum );
}
The C preprocessor has the special tokens __LINE__ and __FILE__, which expand to the current line (as integer) and the current file (as C string).
To make it work, you must declare a wrapper macro:
void error(int line, const char *file)
{
fprintf(stderr, "Error in %s, line %d\n", file, line);
// handle error
}
#define ERROR() error(__LINE__, __FILE__)
This will pass the information on the location of the macro invocation to the error handler.
If I have understood your requirement properly, you can make use of __FILE__and __LINE__ MACRO to get the filename and the line number of any instruction. These two are standard predefined MACRO. You can check Online GCC reference.
Also, there is __func__ (C99) which gives you the current function name.
So, as you want, you can define the another function prototype (maybe in debug mode), which passes on (and accepts) the extra parameters like __FILE__, __LINE__, __func__ etc while making the function call. Then , you can have the caller function name and line displayed from the called function.
Alternatively, you can also have a look at backtrace() function. However, it is a GNU extension.

How to prevent function from printing?

Is it possible to silence a function?
For example:
#include <stdio.h>
int function(){
printf("BLAH!");
return 10;
}
int main(){
printf("%d", silence( function()) );
return 0;
}
And instead of:
BLAH!
10
I would get:
10
Is it possible? If positive how to do it?
An awfully complicated way to do almost what you want is to use the dup2() system call. This requires executing fflush(stdout); dup2(silentfd, stdout); before function() is called, and copying back afterwards: fflush(stdout); dup2(savedstdoutfd, stdout);. So it is not possible to do as just silence(function()), since this construct only allows to execute code after function() has already been executed.
The file descriptors silentfd and savedstdoutfd have to be prepared in advance (untested code):
int silentfd = open("/dev/null",O_WRONLY);
int savedstdoutfd = dup(stdout);
This is almost certainly not what you really want, but inasmuch as your question is phrased as “is it possible?”, the answer is “almost”.
use macro function and null device.
E.g. for windows
#include <stdio.h>
#define silence(x) (_stream = freopen("NUL:", "w", stdout), _ret_value = x,_stream = freopen("CON:", "w", stdout),_ret_value)
int _ret_value;
FILE *_stream;
int function(){
printf("BLAH!");
return 10;
}
int main(void){
printf("%d", silence( function()) );
return 0;
}
No its not possible. You could however try to temporarily redirect the stdout to something else. That may come close to what you want.
You can use this macro instead of printf to be able to prevent printing:
int flag=0;
#define PRINT(...) if(flag){printf(...)}
then use PRINT macro by considering the variable flag. If flag==1, the function will print and if flag==0, the function will not print.
With GCC extensions, you might consider having macros like
bool silent;
#define silence(X) ({int _x; quiet(); _x = (X); verbose(); _x; })
#define printf(Fmt,...) \
do{if (!silent) printf(Fmt,##__VA_ARGS__);}while(0)
that silence macro would work only if its argument X is a int expression (or use typeof) I also assume that the result of printf is never used. Recall that "recursive" macros are specially pre-processed, the inside occurrence of printf (in that printf macro) is left verbatim without macro-expansion.
Notice that silence cannot be a function (otherwise, its argument would have been evaluated before calling it). And you need GCC statement expressions extension to "remember" the result of the argument in some variable _x (you could generate that name using __COUNTER__ and preprocessor concatenation), to give it back as the value of silence macro invocation.
Then you need to define your functions quiet() and verbose(), perhaps something like
void quiet()
{
silent = true;
}
void verbose()
{
silent = false,
}
if you don't want to define printf as your macro, you could use freopen(3) on stdout (perhaps with "/dev/null" etc...) or do dup2(2) tricks (like suggested by Pascal Cuoq).
If your code base is huge, and you want something more serious and are willing to spend days or weeks of work, consider customizing your GCC compiler with a plugin or a MELT extension (or ask someone to do it). Notice that printf is known to GCC.
In reality, you should define your own macro like
#define myprintf(Fmt, ...) do{if (!silent) \
printf(Fmt,__VA_ARGS__);}while(0)
and just use myprintf instead of printf everywhere, this is a portable trick. Of course, I assume you are not passing printf as a function pointer.
For debugging, I actually recommend
#define dbgprintf(Fmt,...) do{if (wantdebug) \
printf("%s:%d:" Fmt "\n", __FILE__, __LINE__, \
##__VA_ARGS__);}while(0)
and then I use dbgprintf("i=%d",i) or simply dbgprintf("foo here") in my code.
I'm using ##__VA_ARGS__ which is a GCC extension to accept no variable arguments to a variadic macro. If you want strict C99, you will just say __VA_ARGS__ and every dbgprintf would need one argument after the format.
You could also re-implement your own printf function, but I don't advise doing that.
(Notice that things could be more complex, you can print using fputs not printf ....)
If you're designing the function do the following:
int function(void (*printer)(char *)){
if (!printer)
printer = printf;
printer("BLAH!");
return 10;
}
void silence(char *s){
return;
}
int main(int argc, char **argv){
printf("%d\n", function(silence));
return 0;
}
That should do what you're looking for. Unfortunately, I didn't test it and my C is probably a little bit rusty.
Of course if function isn't something you have control over, the answers already posted are all correct solutions.
Actually, if you're designing the function yourself, just do:
int function(int print){
if (print)
printf("BLAH!");
return 10;
}
function(0); /* Won't print anything */
function(!0); /* Will print "BLAH!" */
because 0 is false and any non-zero (or !0) value is true. My above suggestion is error prone since you'll have to be able to mimic the printf signature for silence or for any other function you wish to use.
Unfortunately if you have the function explicitly printing and call it like this then it will always print. if you want to silence the function completely you could simply comment out that line.You could even use a control statement so that it only prints IF and when a condition is met otherwise it stays blank and only returns the number.

Force function to accept specific definitions only?

I would like to force a functions parameters to accept only specific definitions. For example, consider #define OUTPUT 1, #define INPUT 0 and void restrictedFunction(int parameter); .
How would I force restrictedFunction(int parameter) to accept only OUTPUT or INPUT?
I would also like to take into consideration that another definition may have the same value, for example, #define LEFT 1 and #define RIGHT 0.
So in this case I would like restrictedFunction(int parameter) to be able to accept only OUTPUT and INPUT specifically.
typedef enum { INPUT = 0, OUTPUT = 1 } IO_Type;
void restrictedFunction(IO_Type parameter) { ... }
It doesn't absolutely force the use of the values (the compiler will let someone write restrictedFunction(4)), but it is about as good as you'll get.
If you truly want to force the correct type, then:
typedef enum { INPUT = 0, OUTPUT = 1 } IO_Type;
typedef struct { IO_Type io_type } IO_Param;
void restrictedFunction(IO_Param parameter) { ... }
In C99 or later, you could call that with:
restrictedFunction((IO_Param){ INPUT });
This is a compound literal, creating a structure on the fly. It is not entirely clear that the structure type really buys you very much, but it will force the users to think a little and may improve the diagnostics from the compiler when they use it wrong (but they can probably use restrictedFunction((IO_Param){ 4 }); still).
What this means is that your restrictedFunction() code should be ready to validate the argument:
void restrictedFunction(IO_Type io_type)
{
switch (io_type)
{
case INPUT:
...do input handling...
break;
case OUTPUT:
...do output handling...
break;
default:
assert(io_type != INPUT && io_type != OUTPUT);
...or other error handling...
break;
}
}
You could use an enum.
typedef enum TrafficDirection { INPUT = 0, OUTPUT = 1 } TrafficDirection;
restrictedFunction(TrafficDirection direction);
of course, this isn't perfect. You can still pass any int to it as long as you use a cast.
restrictedFunction((TrafficDirection) 4);
You don't get quite as much protection as you might like, but you can do:
enum func_type { INPUT, OUTPUT };
void restrictedFunction( enum func_type parameter );
You can use a wrapper to validate the argument:
#define restrictedFunction(x) do { \
static_assert((x) == INPUT || (x) == OUTPUT); \
assert(!strcmp(#x, "INPUT") || !strcmp(#x, "OUTPUT")); \
restrictedFunction(x); \
} while(0)
Notes:
This assumes restrictedFunction() returns a void. If it returns a value which you actually use, you'll need something like gcc's compound statement http://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html. Or--better--you can use BUILD_BUG_ON_ZERO (see What is ":-!!" in C code?), which I keep forgetting about, because it doesn't seem to work with C++.
The do ... while(0) is to "swallow the semi-colon"; not really relevant here.
static_assert() is a compile-time assert; there are many variants available. Here is a link to one, https://stackoverflow.com/a/9059896/318716, if you don't have your own handy.
assert() is the standard run-time assert.
With gcc 4.1.2, and my version of static_assert(), you can replace the run-time assert() with a compile-time assert when the two !strcmp()'s are replaced with ==; see example below. I haven't tested this with other compilers.
x is only used once in the macro expansion, since the first four references are only used at compile-time.
When your actually define your function, you'll have to add parentheses to disable the macro expansion, as in:
void (restrictedFunction)(int x){ ... }
Also, if your code has a special case (whose code doesn't?) where you need to call restrictedFunction() with the argument foo, you'll need to write:
(restrictedFunction)(foo);
Here is a complete example, which puts a wrapper around the standard library function exit():
#include <stdlib.h>
#define CONCAT_TOKENS(a, b) a ## b
#define EXPAND_THEN_CONCAT(a,b) CONCAT_TOKENS(a, b)
#define ASSERT(e) enum{EXPAND_THEN_CONCAT(ASSERT_line_,__LINE__) = 1/!!(e)}
#define ASSERTM(e,m) enum{EXPAND_THEN_CONCAT(m##_ASSERT_line_,__LINE__)=1/!!(e)}
#define exit(x) do { \
ASSERTM((x) == EXIT_SUCCESS || (x) == EXIT_FAILURE, value); \
ASSERTM(#x == "EXIT_SUCCESS" || #x == "EXIT_FAILURE", symbol); \
exit(x); \
} while(0)
int main(void) {
exit(EXIT_SUCCESS); // good
exit(EXIT_FAILURE); // good
exit(0); // bad
exit(3); // doubly bad
}
If I try to compile it, I get:
gcc foo.c -o foo
foo.c: In function 'main':
foo.c:17: error: enumerator value for 'symbol_ASSERT_line_17' is not an integer constant
foo.c:18: warning: division by zero
foo.c:18: error: enumerator value for 'value_ASSERT_line_18' is not an integer constant
foo.c:18: error: enumerator value for 'symbol_ASSERT_line_18' is not an integer constant

Portable instrumentation

GCC has a nice feature about instrumentation which let you call a routine every time a function is called, or every time a function returns.
Now, I want to create my own system to make it portable to other compilers, and also to allow to instrumentalize the functions I want (which can vary in number of parameters), so I was thinking in two macro for both situations. I am thinking in making some kind of profile that it is activated only with a define clause.
#define FUNCT(t,function_name,...) \
(t) function_name(...) { \
(void) *func_pointer = &(function_name); \
start_data(func_pointer, myclock());
#define RETURN(x) {stop_data(func_pointer, myclock()); return (x);}
FUNCT(BOOL, LMP, const int prof, const int nmo))
if (nmo <= 5 ||
prof > (prof_l / 3)) {
.... do long operations....
RETURN(FALSE);
}
... do more....
RETURN(TRUE);
}
but I can’t get it to work. Can someone help me with this? or is this a difficult task to accomplish?
Other alternative that comes to my mind is let the function declare without a macro, and if it is anyway to know the function pointer without knowing its name, something like in VB when you call a Form with Me, with it is a generic alias. is it possible?
Use gcc -E to debug your macros. Using the code you posted:
$ gcc -E t.c
# ... skip stuff ....
(BOOL) LMP(...) { (void) *func_pointer = &(LMP);
start_data(func_pointer, myclock());)
if (nmo <= 5 ||
prof > (prof_l / 3)) {
.... do long operations....
{stop_data(func_pointer, myclock()); return (FALSE);};
}
... do more....
{stop_data(func_pointer, myclock()); return (TRUE);};
}
(I added some whitespace to make it readable.)
You can see two problems immediately: function arguments didn't get expanded as you thought they would, and there's an extra ) from somewhere.
To get the expanded variadic arguments, use __VA_ARGS__, not .... The stray ) is at the call site.
So:
#define FUNCT(t,function_name,...) \
(t) function_name(__VA_ARGS__) { \
(void) *func_pointer = &(function_name); \
start_data(func_pointer, myclock());
#define RETURN(x) {stop_data(func_pointer, myclock()); return (x);}
FUNCT(BOOL, LMP, const int prof, const int nmo)
if (nmo <= 5 ||
prof > (prof_l / 3)) {
.... do long operations....
RETURN(FALSE);
}
... do more....
RETURN(TRUE);
}
As to whether this is worth trying (variadic macros came with C99, not all compilers implement that standard, and support might vary from compiler to compiler), I'm not certain. You are probably better off using each compiler's native profiling tools - you'll get better results with hopefully less overhead.
It is much easier to instrument your functions at the calling side instead of the function side. A macro can have the same name as a function. Declare your replacement function somewhere
double myfunc_wrapper(int someArg) {
double ret = 0;
// do something before
...
// now call it
ret = (myfunc)(someArg);
// Then do something after
....
return ret;
}
Just to be sure put the () arround the call itself to be sure that always a function is called and not a macro.
And then "overload" your function with a macro
#define myfunc(...) mfunc_wrapper(__VA_ARGS__)
with that idea you can replace your function on the fly in the compilation units that interes you.
in addition to Mat, there is a ergonimical problem with using #define RETURN(x) {...}:
if (test)
RETURN (TRUE);
else
RETURN (FALSE);
will evaluate to
if (test)
{...}
; // <syntactical error
else
{...}
;

Resources