3

This question has been asked before for other languages: Python, PHP and JavaScript.

I would like to know if it is possible to do this in C. I am trying to get a snapshot of all the variables in my function at one point during the execution and then comparing that to another snapshot at a later point in time.

EDIT
A snapshot can be a list of all the variables in scope and their current value. I could code it by hand, but I would like to know if there is a faster way of doing things.

Community
  • 1
  • 1
JcMaco
  • 1,258
  • 3
  • 16
  • 31
  • What do you mean by "getting a snapshot"? Have the program display them? Have a debugger display them? – wallyk Apr 18 '11 at 17:00
  • 3
    possible duplicate of [How can one grab a stack trace in C?](http://stackoverflow.com/questions/105659/how-can-one-grab-a-stack-trace-in-c) – Brian Roach Apr 18 '11 at 17:03

4 Answers4

10

Yes and No

Is there a language feature? No.

Can it be done in a system-independent fashion? No.

Is there an easy way? No.

Can it be done in a system-specific way with some effort? Yes.

In summary, there is no good way and no easy way, but if you really really want to it can be done. Broadly speaking, the program is compiled for debugging and you then open the image file at run-time and find out which variables exist and where they are stored. Most likely, the practical way to accomplish this would be to script a debugger like gdb and let it do the low-level work.

If you system already has a run-time traceback feature then you may be able to leverage that.

Another possibility: some operating systems support a library function that reads the symbol table. Historic Unix and Mac OS X have nlist(3). Some versions of Linux and Solaris have dlinfo(3). A CLI tool called nm(1) (you could popen(1) it) is commonly available.

DigitalRoss
  • 143,651
  • 25
  • 248
  • 329
0

You simply can't do that in a (compiled) language that is so low-level. When the compiler + linker are done with your code there is little trace of "variables", only raw machine code.

nc3b
  • 15,562
  • 5
  • 51
  • 63
  • What does a debugger do then? – Carl Norum Apr 18 '11 at 17:03
  • @Carl Norum: It uses specially injected code. An interpreted language (usually) doesn't need debugging symbols to do this. – nc3b Apr 18 '11 at 17:04
  • 1
    As for needing debugging symbols, that's irrelevant. He's asking how you do it and that would be part of it. – Brian Roach Apr 18 '11 at 17:07
  • 2
    @Brian Roach: okay, I really didn't know about `backtrace(3)`. How would you go about listing **variables and values** ? – nc3b Apr 18 '11 at 17:08
  • Well, you've got the stack frame ... so you go from there. I didn't say it was *easy*, but saying it isn't possible is simply incorrect. `gdb` isn't magic. – Brian Roach Apr 18 '11 at 17:11
  • 2
    It isn't magic: it's using debugging symbols. That isn't something available in a production program and I feel isn't what's being asked here. It's not about "easy" and "hard". A normal binary will have no trace whatsoever of identifier names. – nc3b Apr 18 '11 at 17:16
  • @nc3b, a debugger doesn't inject any code anywhere. The debugging symbols aren't necessarily embedded in the program. – Carl Norum Apr 18 '11 at 17:28
  • additionally, some variables may have been optimized away and may not show in the backtrace, or may have incorrect values among other things depending on optimization settings... – Spudd86 Apr 18 '11 at 17:39
0

Depending on the C program you are interested in, you may be able to use Frama-C, specifically, a completely unrolled value analysis, to simulate an execution, and then, insert a call to Frama_C_dump_each() to obtain a dump of the values of variables at a specific point of the program.

You can expect a completely unrolled analysis simulating an execution to be between 10000 and 100000 times slower than the real thing, but then, we have fast computers nowadays. This still will only work for relatively small programs.

Example:

int x,a;
int y=2;

void f(void)
{
  int lf = 5;
  a = y + 2;
  Frama_C_dump_each();
  return;
}

main(){
  int lmain = 3;
  f();
  return 0;
}

$ frama-c -val -slevel 50000 t.c
....
[value] DUMPING STATE of file t.c line 8
    x ∈ {0; }
    a ∈ {4; }
    y ∈ {2; }
    lf ∈ {5; }
    lmain ∈ {3; }
    =END OF DUMP==
....
Pascal Cuoq
  • 79,187
  • 7
  • 161
  • 281
0

Not simple. You would need do such a thing at the binary level and have knowledge about where your compiler has put data structures with regards to the base pointer in the hardware. You would also need debug symbols.

Short answer is no, not without considerable effort.

Edd Barrett
  • 3,425
  • 2
  • 29
  • 48