print the value of variables while running in C - c
I am trying to test some packages written in C by checking the value of the local and global variables, I tried to use the GDB debugger and fprint as suggested by many people here and they worked well with simple and small programs, but with the package, it's not easy.
So, I need to extract all variables into a txt.file (each line has one variable) and then while running the program I need to print the value of these variables.
I used a normal print statement to take the name of variables from txt file, the problem is the exact character is printed.
Question: how do I use these characters from the text file as variables to print the values not the name?
variables.txt
x
y
d
main.c
in the main file, I included the header and called the func.
//printState.h
void printstate(){
char ch;
FILE *fp;
if(fp = fopen("Varaibles.txt", "r"))
{
ch=getc(fp);
while(ch != EOF)
{
printf("%c",ch);
ch = getc(fp);
}
fclose(fp);
}
}
int func(int x) {
int y = 0;
x = y + x;
if(x > 0){
x = x % 4;
printstate();
/* I want to know the value of x at this point.*/
}
else {
x = x + 1;
printstate();
/* I want to know the value of x at this point.*/
}
return x;
}
expected output:
is the value of x, y, d after the statement (x = x % 4) and (x = x + 1)
For example:
5
7
6
the actual output I got was:
x
y
d
This question implies the use of reflection on the local and global variables. Sadly, C doesn't have such concept.
I'm sure gdb can help you generate the list of local and global variables (maybe here?)
However, since you didn't explicitly say how to achieve this, I'll throw my 2 cents on this.
There are some projects implementing reflection on C, but my preference always goes into exploiting the preprocessor to achieve this. Although you can avoid the header-only library, I will use P99 to ease the macro programming.
a MWE can be the following one:
#include <P99/p99_for.h>
#include <P99/p99_args.h>
#include <stdio.h>
enum print_type {
PT_char,
PT_int,
PT_ptr,
PT_string,
};
#define FOR_PAIR(CONTEXT, OP, FUNC, ...) P99_PASTE2(_BASE_FOR_PAIR_, P99_NARG(__VA_ARGS__))(CONTEXT, OP, FUNC, ## __VA_ARGS__)
#define _BASE_FOR_PAIR_2(CONTEXT, OP, FUNC, value1, value2) FUNC(CONTEXT, 0, value1, value2)
#define _BASE_FOR_PAIR_4(CONTEXT, OP, FUNC, value1, value2, ...) OP(CONTEXT, 1, FUNC(CONTEXT, 1, value1, value2), _BASE_FOR_PAIR_2(CONTEXT, OP, FUNC, ## __VA_ARGS__))
#define _BASE_FOR_PAIR_6(CONTEXT, OP, FUNC, value1, value2, ...) OP(CONTEXT, 2, FUNC(CONTEXT, 2, value1, value2), _BASE_FOR_PAIR_4(CONTEXT, OP, FUNC, ## __VA_ARGS__))
#define _BASE_FOR_PAIR_8(CONTEXT, OP, FUNC, value1, value2, ...) OP(CONTEXT, 3, FUNC(CONTEXT, 3, value1, value2), _BASE_FOR_PAIR_6(CONTEXT, OP, FUNC, ## __VA_ARGS__))
#define _BASE_FOR_PAIR_10(CONTEXT, OP, FUNC, value1, value2, ...) OP(CONTEXT, 4, FUNC(CONTEXT, 4, value1, value2), _BASE_FOR_PAIR_8(CONTEXT, OP, FUNC, ## __VA_ARGS__))
#define _LENGTH_VAR _localsTrackingSystem_arrayLengths
#define _NAMES_VAR _localsTrackingSystem_names
#define _VARIABLES_VAR _localsTrackingSystem_variables
#define _PRINTMETHOD_VAR _localsTrackingSystem_printMethod
#define STR(x) #x
#define _NAMES_REDUCE(NAME, I, REC, RES) REC, RES
#define _NAMES_MAP(context, length, type, name) (STR(name))
#define _GENERATE_NAMES(...) FOR_PAIR(, _NAMES_REDUCE, _NAMES_MAP, ## __VA_ARGS__)
#define _POINTERS_REDUCE(NAME, I, REC, RES) REC; RES
#define _POINTERS_MAP(arrayLength, length, type, aname) _VARIABLES_VAR[arrayLength - length - 1] = ((void*)&aname)
#define _GENERATE_POINTERS(...) FOR_PAIR(P99_DIV(P99_NARG(__VA_ARGS__), 2), _POINTERS_REDUCE, _POINTERS_MAP, ## __VA_ARGS__)
#define _PRINT_REDUCE(NAME, I, REC, RES) REC, RES
#define _PRINT_MAP(context, length, type, name) (P99_PASTE2(PT_, type))
#define _GENERATE_PRINT(...) FOR_PAIR(, _PRINT_REDUCE, _PRINT_MAP, ## __VA_ARGS__)
//variadic needs to be always even
// _GENERATE_POINTERS needs to be initialized every time since pointers may change (although length doesn't)
#define TRACKED_FUNCTION(...) \
static const int _LENGTH_VAR = P99_DIV(P99_NARG(__VA_ARGS__), 2); \
static const char* _NAMES_VAR[] = {_GENERATE_NAMES(__VA_ARGS__)}; \
static const enum print_type _PRINTMETHOD_VAR[] = {_GENERATE_PRINT(__VA_ARGS__)}; \
static const void* _VARIABLES_VAR[P99_DIV(P99_NARG(__VA_ARGS__), 2)]; \
_GENERATE_POINTERS(__VA_ARGS__)
#define printState() _printState(_LENGTH_VAR, _NAMES_VAR, _VARIABLES_VAR, _PRINTMETHOD_VAR);
void _printState(int length, const char** nameArray, const void** pointerArray, const enum print_type* printMethodArray) {
for (int i=0; i<length; ++i) {
printf("at %p %s = ", pointerArray[i], nameArray[i]);
switch (printMethodArray[i]) {
case PT_char: {
printf("%c", *((char*)pointerArray[i]));
break;
}
case PT_int: {
printf("%d", *((int*)pointerArray[i]));
break;
}
case PT_ptr: {
printf("%p", *((void**)pointerArray[i]));
break;
}
case PT_string: {
printf("%s", *((char**)pointerArray[i]));
break;
}
default: {
exit(1);
}
}
printf("\n");
}
}
int func(int x, const char* name){
//LOCALS DEFINITIONS
int y = 0;
int* yPtr = &y;
x = y + x;
//declare which variables you want to track... like your "variables.txt" files
TRACKED_FUNCTION(int, x, int, y, ptr, yPtr, string, name);
//MAIN BODY
if(x > 0) {
x = x % 4;
printf("expected x=%d, y=%d, yPtr=%p name=%s\n", x, y, yPtr, name);
printState();
/* I want to know the value of x at this point.*/
} else {
x = x + 1;
printf("expected x=%d, y=%d, yPtr=%p name=%s\n", x, y, yPtr, name);
printState();
/* I want to know the value of x at this point.*/
}
return x;
}
int main() {
func(5, "Hello World!");
}
My output:
expected x=1, y=0, yPtr=0x7ffec1e5b5ec name=Hello World!
at 0x7ffec1e5b5dc x = 1
at 0x7ffec1e5b5ec y = 0
at 0x7ffec1e5b5f0 yPtr = 0x7ffec1e5b5ec
at 0x7ffec1e5b5d0 name = Hello World!
I've already treated a similar concept here, however let me briefly explain what this code does:
Usage: very simple; after having declared all the variables you're interested in printing, you call TRACKED_FUNCTION and pass a sequences of pairs of variables: the first element of the pair is a string representing how you wish to print the content of the variable (e.g., you might have a char, but maybe you want to print it as int); the second is the name of the variable itself; so in the example TRACKED_FUNCTION(int, x, int, y, ptr, yPtr, string, name); we want to track x which needs to be printed as an int, y as a int, yPtr as a pointer and name as a string; After calling such macro, you can call printState() whenever you want to obtain a list of all the variables you explicitly declared;
Internal details: my main idea is to create 4 "hidden" variables: an array containing all the variables names, another containing all the variables pointers, another one containing for each variable how to print it and an integer representing the length of all the arrays; TRACKED_FUNCTION generates those 3 arrays while printState() just print them. In particular, the first element of each pair in TRACKED_FUNCTION is actually concatenated into an identifier which belong to the enum print_type: this is the main reason why we can use a "type" string but we cannot use a type void*: PT_void* is not a vlaid enum identifier!
Pros: This implementation is, aside a bunch of headers of P99, library-free. Some macro programming is required though; Furthermore it is C99 compliant;
Cons: It's C99 compliant, but we can probably improve the method if we were on C11, however, OP didn't specify it in the tags, so whatever :). Another cons (I think you've guessed it) is the fact that this solution doesn't use the file at all. Even worse, it cannot work with the file because the lines fetched from the file cannot be handled in any way with macro programming. This is why I didn't use it. I don't know if you require to use the file or it suffices list in another way (with this solution in TRACKED_FUNCTION) the variables you're interested in.
Hope it helps
Related
Evaluate/print function return that is used as input to macro
I am trying to create a simple unit test library for my projects. I can get most things working, but now I am trying to add some functionality: printing the expressions/input. It works if I pass arguments by actual value (1, 2.456, false), but if I pass a function argument I get the function string printed. Here is my code explaining the problem I am not 100% sure what the STR(x) macro is doing, copied it from somewhere online... The code actually works (the evaluation of LHS and RHS) just the printing does not, shown below. #include <stdio.h> #define STR(x) #x #define TEST_COMPARE_EQ(TestName, LHS, RHS) \ do { \ if ((LHS) != (RHS)) { \ printf("[Test: %s] --- Failed at line %d in file %s\n", TestName, __LINE__, __FILE__); \ printf("\Got value %s\n", STR(LHS)); \ printf("\Expected value %s\n", STR(RHS)); \ } \ else { \ printf("[Test: %s] --- Passed\n", TestName); \ }\ } while (0) // Calling code example // This works, prints: // Got value 123 // Expected value 124 TEST_COMPARE_EQ("PrintingWorks", 123, 124); // This however does not work. // It prints // Got value my_fn_that_returns_false // Expected value true // How can I get it to print the return value of my_fn_that_returns_false, and not // the actual function name? TEST_COMPARE_EQ("PrintingDoesNotWork", my_fn_that_returns_false(), true);
what the STR(x) macro is doing, It takes the code as it is and adds " in front and back. STR(anything) is "anything", just like that. How can I get it to print the return value You have to print it. printf("Got value %d\n", LHS); No, there are no templates in C. It is hard to write type generic functions in C. You have to handle each possible type separately - like TEST_COMPARE_EQ_INT TEST_COMPARE_EQ_FLOAT etc. For inspiration, take a look at Unity C unit testing library. Writing that in a type-generic way sounds like a nice challenge in C. It would look basically like the following: void test_eq_int(int a, const char *astr, int b, const char *btr) { if (a != b) { printf("%s = %s -> %d != %s\n", astr, bstr, a, b); } } void test_eq_long(....) { .... } void test_eq_some_other_type(...) { .... } // etc. for each possible type #define TEST_COMPARE_EQ(msg, a, b) \ _Generic(a, \ int: test_eq_int, \ long: test_eq_long, \ /* etc. for each type */ \ )(msg, a, #a, b, #b);
Is there a way to save the function call with parameters?
I'm experimenting with memory management and trying to create something that will help with it in any way. Right now I'm trying to think is there any way to repeat the 'defer' functionality from Go in C. Fast example for those who don't know what defer is: package main import "fmt" func main() { defer fmt.Println("1") defer fmt.Println("2") defer fmt.Println("3") return } will print 3 2 1 So I'm thinking about some macros that will push the function with params to some stack and will call them when the function exit is called. Something like this: int func(void) { MEMSTACK_INIT; char * string = NULL; node_t * node = NULL; MEMSTACK_PUSH(free(string)); MEMSTACK_PUSH(NodeFree(&node)); <..> switch (something) { case ONE : RETURN ERROR_ONE; case TWO : RETURN ERROR_TWO; case THR : switch (something else) { <.. Many more code ..> } } RETURN ERROR_GOOD; } Is there a way (except for making my own preprocessor, of course), to store somewhere a function call with params? In other words I want the previous code to be preprocessed in something like this: int func(void) { <.. Some MEMSTACK initialisation stuff (if needed) ..> char * string = NULL; node_t * node = NULL; <..> switch (something) { case ONE : free(string); NodeFree(&node); return ERROR_ONE; case TWO : free(string); NodeFree(&node); return ERROR_TWO; case THR : switch (something else) { <.. Many more code ..> } } free(string); NodeFree(&node); return ERROR_GOOD; } It would be good thing for functions who require a lot of cleanup before exit. Yes, yes, I know about goto cleanup trick.
I'm experimenting with memory management and trying to create something that will help with it in any way. A good approach is to have only one return in any function. Possibly marked with a label (yes, so can gotoit, but this is also often discouraged). And of course: Be always sure to know who owns allocated memory and when (and where) ownership is transferred! Now, let's... [..] repeat the 'defer' functionality from Go in C. First, in order to defer the call, we need to store the function (a pointer to it) as well as the evaluated arguments. Since C is statically typed, we need to unify that in a single type: struct Fn { void * parameters; // pointer to memory where the parameters are stored void (*function)(void *); // pointer to function able to unpack parameters from above struct Fn * next; // we want a stack, so ... }; For each function that we are going to eventually defer, we need a way to store it's parameters. So we define a struct capable of holding the parameters and a function that is able to unpack the parameters from that struct: #define MAKE_DEFERRABLE(name, N, ...) \ struct deferred_ ## name ## _parameters { PARAMS(N, __VA_ARGS__) }; \ void deferred_ ## name (void * p) { \ struct deferred_ ## name ## _parameters * parameters = p; \ printf(" -- Calling deferred " #name "\n"); \ (void)name(CPARAMS(N)); \ } The N is the number of arguments. There are tricks to infer that from the __VA_ARGS__, but I'll leave that as an exercise for the reader. That macro contains two other macro expansions, PARAMS and CPARAMS. The former expands into a list suitable to define the struct contents. The later expands into code to extract the struct members as arguments: #define PARAM_0(...) #define PARAM_1(type, ...) type p1; PARAM_0(__VA_ARGS__) #define PARAM_2(type, ...) type p2; PARAM_1(__VA_ARGS__) #define PARAM_3(type, ...) type p3; PARAM_2(__VA_ARGS__) #define PARAM_4(type, ...) type p4; PARAM_3(__VA_ARGS__) #define PARAMS(N, ...) SPLICE(PARAM_, N)(__VA_ARGS__) #define CPARAM_0 #define CPARAM_1 parameters->p1 #define CPARAM_2 parameters->p2, CPARAM_1 #define CPARAM_3 parameters->p3, CPARAM_2 #define CPARAM_4 parameters->p4, CPARAM_3 #define CPARAMS(N) SPLICE(CPARAM_, N) If we'd want to defer functions with more than 4 parameters then this would need to be adjusted. The SPLICE is a nice little helper: #define SPLICE_2(l,r) l##r #define SPLICE_1(l,r) SPLICE_2(l,r) #define SPLICE(l,r) SPLICE_1(l,r) Next, we need to store the deferred functions somehow. For simplicity I choose to allocate them dynamically and keep a global pointer to the most recent: struct Fn * deferred_fns = NULL; Obviously you can extend this in many directions: Using (bounded) static storage, making it thread local, using per function deferred_fns, using alloca, ... ... but here's the simple, not production-ready (MISSING ERROR CHECKS) variant: #define DEFER(name, N, ...) \ do { \ printf(" -- Deferring a call to " #name "\n"); \ if (deferred_fns == NULL) { \ deferred_fns = malloc(sizeof(*deferred_fns)); \ deferred_fns->next = NULL; \ } else { \ struct Fn * f = malloc(sizeof(*f)); \ f->next = deferred_fns; \ deferred_fns = f; \ } \ deferred_fns->function = &(deferred_ ## name); \ struct deferred_ ## name ##_parameters * parameters = malloc(sizeof(*parameters)); \ SPARAMS(N,__VA_ARGS__); \ deferred_fns->parameters = parameters; \ } while(0) This just allocates a new struct Fn, makes it the top of the stack (read singly-linked list deferred_fns) and sets its members accordingly. The important SPARAMS saves the parameters into the corresponding struct: #define SPARAM_0(...) #define SPARAM_1(value, ...) parameters->p1 = (value); SPARAM_0(__VA_ARGS__) #define SPARAM_2(value, ...) parameters->p2 = (value); SPARAM_1(__VA_ARGS__) #define SPARAM_3(value, ...) parameters->p3 = (value); SPARAM_2(__VA_ARGS__) #define SPARAM_4(value, ...) parameters->p4 = (value); SPARAM_3(__VA_ARGS__) #define SPARAMS(N, ...) SPLICE(SPARAM_, N)(__VA_ARGS__) Note: This fixes the order of parameter evaluation by making them evaluate from last to first. C does not mandate an evaluation order. Finally, all that's left is a convenient way to run these deferred functions: void run_deferred_fns(void) { while (deferred_fns != NULL) { deferred_fns->function(deferred_fns->parameters); free(deferred_fns->parameters); struct Fn * bye = deferred_fns; deferred_fns = deferred_fns->next; free(bye); } } A small test: void foo(int x) { printf("foo: %d\n", x); } void bar(void) { puts("bar"); } void baz(int x, double y) { printf("baz: %d %f\n", x, y); } MAKE_DEFERRABLE(foo, 1, int); MAKE_DEFERRABLE(bar, 0); MAKE_DEFERRABLE(baz, 2, int, double); int main(void) { DEFER(foo, 1, 42); DEFER(bar, 0); DEFER(foo, 1, 21); DEFER(baz, 2, 42, 3.14); run_deferred_fns(); return 0; } In order to achieve the same behavior as in your example, make deferred_fns a local variable, and pass that as parameter to run_deferred_fns. Wrap in simple macros, done: #define PREPARE_DEFERRED_FNS struct Fn * deferred_fns = NULL; #define RETURN(x) do { run_deferred_fns(deferred_fns); return (x); } while (0) Welcome to insanity. Note: My solution works at the "source level". By that I mean that you need to specify defer-able functions in the source code. That implies that you cannot, for example, defer a function loaded through dlopen. There's also a different approach, working at the ABI level, if you will: avcall, part of libffcall. Now, I need really need my parentheses ... lots of them (())))(()(((()
Passing operator as a parameter in C99
I want to pass an operator as a parameter in C99. My solution is this: int add(int l, int r) { return l + r; } int sub(int l, int r) { return l - r; } // ... long list of operator functions int perform(int (*f)(int, int), int left, int right) { return f(left, right); } int main(void) { int a = perform(&add, 3, 2); } Is there some other way to do it? I don't want to write a function for every operator. It could look like this: int a = perform(something_cool_here, 3, 2);
You could use switch/case, for example: int perform(char op,int a,int b) { switch (op) { case '+': return a+b; case '-': return a-b; default: return 0; } } But you would still have to write some code for each operator; you don't get anything for free in C.
You can use X Macros. By defining a single macro that contains a table of repeated values in a redefinable macro, you can just redefine the internal macro for the current task and insert a single macro to handle the whole set. Here is a compact way to do it with single operand floating point builtins as an example. The process is similar for other types. //add name of each function you want to use here: #define UNARYFPBUILTINS \ $(acos) $(acosh) $(asin) $(asinh) $(atan) $(atanh) $(cbrt) $(ceil) \ $(cos) $(erf) $(erfc) $(exp) $(exp10) $(exp2) $(expm1) $(fabs) \ $(floor) $(gamma) $(j0) $(j1) $(lgamma) $(log) $(log10) $(log1p) \ $(log2) $(logb) $(pow10) $(round) $(signbit) $(significand) \ $(sin) $(sqrt) $(tan) $(tgamma) $(trunc) $(y0) $(y1) //now define the $(x) macro for our current use case - defining enums #define $(x) UFPOP_##x, enum ufp_enum{ UNARYFPBUILTINS }; #undef $ //undefine the $(x) macro so we can reuse it //feel free to remove the __builtin_## ... its just an optimization double op(enum ufp_enum op, double f){ switch(op){ //now we can use the same macros for our cases #define $(x) case UFPOP_##x : f = __builtin_##x(f);break; UNARYFPBUILTINS #undef $ } return f; } You can continue using it for other stuff as well ///////////EXTRA STUFF///////// //unused - may be good mapping the enums to strings //#define $(x) #x, //const char * ufp_strings{ UNARYFPBUILTINS }; //#undef $ //this uses float instead of double, so adds the ##f to each function float opf(enum ufp_enum op, float f){ switch(op){ #define $(x) case UFPOP_##x : f = __builtin_##x##f(f);break; UNARYFPBUILTINS #undef $ } return f; } //you could do the same thing for long double here Edit: Note that $ in macros is implementation dependent, You can call it whatever Edit2: Here is an example with multiple parameters to do arithmetic operators. This one uses computed gotos instead of a switch in case your compiler handles one better than the other. #define IOPS $(SUB,-) $(MUL,*) $(DIV,/) $(MOD,%) $(ADD,+) $(AND,&) $(OR,|) \ $(XOR,^) $(SR,>>) $(SL,<<) enum iops_enum { #define $(x,op) IOPSENUM_##x, IOPS IOPSENUM_COUNT #undef $ }; int opi(int a, enum iops_enum b, int c){ static const char array[] = { //you may get better results with short or int #define $(x,op) &&x - &&ADD, IOPS #undef $ }; if (b >= IOPSENUM_COUNT) return a; goto *(&&ADD + array[b]); //else should give a warning here. #define $(x,op) x: return a op c; IOPS #undef $ }
When is CAMLparamX required?
I am writing an interface to a C-library using external declarations in OCaml. I used ctypes for testing but it involved a 100% overhead for fast calls (measured by a core_bench micro benchmark). The functions look like this: /* external _create_var : float -> int -> int -> int -> _npnum = "ocaml_tnp_number_create_var" ;; */ value ocaml_tnp_number_create_var(value v, value nr, value p, value o) { //CAMLparam4(v, nr, p, o); const int params = Int_val(p); const int order = Int_val(o); const int number = Int_val(nr); const double value = Double_val(v); return CTYPES_FROM_PTR(tnp_number_create_variable(value, number, params, order)); } /* external _delete : _npnum -> unit = "ocaml_tnp_number_delete" ;; */ value ocaml_tnp_number_delete(value num) { //CAMLparam1(num); struct tnp_number* n = CTYPES_TO_PTR(num); tnp_number_delete(n); return Val_unit; } I borrowed the CTYPES_* macros, so I am basically moving pointers around as Int64 values. #define CTYPES_FROM_PTR(P) caml_copy_int64((intptr_t)P) #define CTYPES_TO_PTR(I64) ((void *)Int64_val(I64)) #define CTYPES_PTR_PLUS(I64, I) caml_copy_int64(Int64_val(I64) + I) AFAIK, those values are represented as boxes which are tagged as "custom", which should be left untouched by the GC. Do I need to uncomment the CAMLparamX macros to notify the GC about my usage or is it legal to omit them?
According to the comment in byterun/memory.h your function must start with a CAMLparamN macro with all value parameters.
enumerating all enum names/values in C
How can I enumerate all enum names and values in C to print it like printf("Name: %s, value: %d\n", name, value); ?
Check out the X macro: #define COLORS \ X(Cred, "red") \ X(Cblue, "blue") \ X(Cgreen, "green") #define X(a, b) a, enum Color { COLORS }; #undef X #define X(a, b) b, static char *ColorStrings[] = { COLORS }; #undef X printf("%s\n", ColorStrings[Cred]); // output: red
You can't, at least not directly. There are a few solutions though. First, if you don't actually need the names, you can simply have an end marker in the enum, if values are sequential: enum my_vals { FIRST, SECOND, LAST_my_vals }; ... for (enum my_vals it = FIRST ; it < LAST_my_vals ; ++it) { .... } But if you do need the names, you can adapt this question: Get enum value by name Then you will have a array with all the values, and can iterate the array.