I just started programming in c, and I want to test some code. So, I need to know the value of a variable at a specific point in the program which I already know.
while searching I saw many people are using gdb and core dump but most of the examples I found they use it to debug the code if there is a crash.
in my case, I don't want to terminate the execution, I just want to save/know the value of a specific variable at a specific point.
for example:
if I have this piece of code:
int func(int x){
x = 3 * x;
if(x > 0){
x = x % 4;
/* I want to know the value of x at this point*/
}
else {
x = x + 1;
/* I want to know the value of x at this point*/
}
return x;
}
if the user enters the value, I want to know what will be the value of x inside the block of (if) after the calculation.
UPDATE:
to clarify my question, I have a big code and I want to test the complete package and I want to write a function that tells me what is the stored value at this program point.
GDB is the best tool for you. While the program is in execution you can see the values of the variables. Please follow the below steps:
compile your program with -g flag.
gcc -g program.c -o output
Now run your program with gdb:
gdb output
In Gdb command line set a breakpoint at 'main' by using:
(gdb) b main
or use below one to set a breakpoint at a particular line.
(gdb) b line_number
now enter 'r' to run the program.
(gdb) r
type 'n' and press enter to go to next line
(gdb) n
type 'step' to step into a function:
(gdb) step
Examine the variable value by using
(gdb) print variable-name
Keep the breakpoint at 'line no' where you want to see the value of a variable and use 'print variable-name' to view the value.
Please take this as a reference for more GDB commands:
http://www.yolinux.com/TUTORIALS/GDB-Commands.html
Hope this answer will help you to debug your code.
I think You can use something like this
printf("%d\n",x);
after each expression with
x= ...
in Your function.
Or You can use fprintf to write values in a file instead printf if You don't want to output values to the console.
Use the debugger (install any C IDE like Eclipse CDT and you will not have to configure anything)
You can even do the debugging online https://www.onlinegdb.com/
Another approach expanding on using printf is to use debugging macros or functions. E.g. see:
https://github.com/jleffler/soq/blob/master/src/libsoq/debug.c
Something like this can be used to allow dynamically enabling debugging for some use cases of your function and then disable it again so you don't get too much output to have to work through when debugging your code.
Related
I am using GDB to debug my msp430. I connect the target and then load the binary of program and then "continue".
My program is working fine however I want to see certain values of variables in real time. Actually I want to check the time stamp of my start of code and end of code which will give me total duration.
As I am totally new to GDB, currently I have placed this line in my code
printf("Hello World\n");
However nothing is printed but my code is working fine which is actually blinking LEDs.
Please guide me how to view values of variables in GDB in debug mode.
Thanks
To print a variable in gdb you can use the print command
(gdb) print counter
You can set a breakpoint on line 10 with break 10. And then attach a sequence of commands to be run every time the program stops at breakpoint 1 with commands 1. An example is below:
(gdb) break 10
Breakpoint 1 at 0x1c4d: file example.c, line 10.
(gdb) commands 1
Type commands for breakpoint(s) 1, one per line.
End with a line saying just "end".
>print counter
>continue
>end
(gdb) continue
So this will break at line 10, print the value of counter and then continue the program.
For timestamps, what you probably want to do is set two breakpoints, one at the start of the code, and one at the end. Have each breakpoint record the time, say by calling the appropriate function. You can make a breakpoint do things by using the commands feature.
However, if this is something you want to do frequently, you might consider just adding code to your program to do it.
For real-time (-ish) access to variables when debugging remotely, you might be interested in the gdb "tracepoint" feature. Currently this feature only works when debugging remotely, and it relies on the remote debug server having the needed features. Tracepoints let you record some selected variables at selected points, and then examine them later. The recording is done with reasonably minimal overhead.
Okay, so this is going to sound like a silly question, yet I am stuck : I have trouble reading the value of a variable during a lldb debugging session (things work fine with gdb).
I have found posts from other people who had encountered the same error message than myself, but the difference is that I can't even figure out how to print out the value of the simplest form of variable.
To better express my problem, I will consider a very simple example here. We have a file "main.c" containing the following code :
#include <stdlib.h>
#include <stdio.h>
int main(void) {
int a = 1;
int b = 2;
int c = 0;
c = a + b;
c = c*b;
printf("c = %d\n", c);
return 0;
}
I compile it using :
user#machine ~ $ gcc -g main.c
A binary file named
"a.out"
is generated
I then ivoque lldb :
user#machine ~ $ lldb-3.4 ./a.out
I want to stop at line 9 and read the value of c. Therefore, I start by adding a breakpoint :
(lldb) breakpoint set -f main.c -l 9
Then I run the code :
(lldb) run
Up until now, every thing goes as expected. Now comes the tricky part : I want to read the value of variable c. Therefore, I write :
(lldb) print c
And lldb returns me :
error: use of undeclared identifier 'c'
error: 1 errors parsing expression
Of course :
(lldb) expression c
returns exactly the same error message.
Is there anything that I missed ? Any help would be very much appreciated.
My setup :
lldb : "lldb version 3.4 ( revision )" (package v. : "3.4~svn183914-1ubuntu1")
gcc : "gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1" (package v. : "4.8.1-2ubuntu3")
(my repositories are the ones provided by linux mint 16 by default)
Some more information following answer from #Sean Perry :
1: It seems that appending option -O0 does not change the debugger's behaviour.
2: I also tried to use the following dummy code instead of my previous one
#include <stdlib.h>
#include <stdio.h>
int main(void) {
long a = 1;
long b = 2;
long c = 0;
c = a + b;
c += (long) &c;
printf("c = %ld\n", c);
return 0;
}
I am not certain that is what #Sean Perry meant by "using pointers", but I suppose it must prevent code optimisation anyway since the address of variable c (more or less) randomly changes for each run of the binary file.
3: Eventually, I noticed something interesting :
compiling with gcc [-g -O0] then debugging with gdb : works
compiling with gcc [-g -O0] then debugging with lldb : does not work
compiling with clang [-g -O0] then debugging with gdb : works
compiling with clang [-g -O0] then debugging with lldb : works
edit1 : reply to #SeanPerry
edit2 : distinguishing the software version from the package version
Seems like this was a specific issue when using gcc 4.8.1 and lldb-3.4
Using gcc-4.8.2 and gcc-4.7.3 works fine.
The best way to investigate the behavior you're seeing is to look at the debug info. On a Mac OS X system, you'd run dwarfdump on the .dSYM bundle or on the .o file if you didn't create a dSYM. The debug information has the instructions from the compiler to the debugger about where to find variables.
In a live process, with lldb, you can have lldb show you where all the local variables are stored (expressed in the DWARF location expression language) with image lookup -v -a $pc (or im loo -va $pc for short).
If there's a program where gdb can't print a variable and lldb at the same pc address cannot, that sounds like it could be an lldb bug. The debug information is the ultimate truth (as far as the debugger is concerned) about where variables are stored and how long they are "live". In optimized code, they may be live for very short sections of your function.
From a hack point of view, the real source of truth is to read the assembly code. Often, under optimization, the compiler doesn't track the location of the variables as well as it could -- it may say that a variable is unavailable at a given pc address, but if you read the assembly closely enough, you might find a copy of the last value still saved on the stack & such.
This code is so simple I bet llvm has removed the variables completely. Try compiling with optimizations disabled (-O0) and see if it helps. Beyond that, use a pointer or do something a little more complicated so the compiler does not removed your math and replace it with precomputed values.
I've never used a debugger and the time has come to give them a try. MinGW appears to come with GDB which I've been trying to use. Supposdly running gdb from the command line and typing run myprog.exe starts the debugger but when I do this I get
Starting program: C:\MinGW\bin\myprog.exe MyProg.exe
[New Thread 1828.0xd8c]
Error opening file.
[Inferior 1 (process 1828) exited with code 02]
How to proceed or what's an easier way?
In particular I'm trying to flush out undefined behavior.
Since your program terminates, you'll need to set a breakpoint to see anything. Try break main before the run line. Then you can do commands line next (next line), step (step into/outof function calls), print expression (where expression can be a variable name or a function-call or a calculation), display expression (same as print, but prints just before each prompt). At any given point you can type backtrace to get a call stack. You can even type up and down to move up the callstack, so you can print higher local variables.
Well, the easiest way would be to use an IDE, actually. You might want to give code::blocks a try - very easy to use, configures everything for you on installation (just make sure to pick a compiler - don't worry, it'll prompt you) and there, you're all set and ready to go. As it's multi-platform, it doesn't really lock you into windows either, and gives you very powerful (and, I guess more importantly, convenient) possibilities of graphical debugging.
pass the binary with gdb
gdb <binary>
then set breakpoint to main
gdb) break main
Then run your program in gdb
gdb) run
then break point hits use 'n' or 'next' to step to different lines
gdb) n
Use 's' for stepping into function and 'p' printing var value
Example :
gdb) s <fun_name>
gdb) p x
I would suggest , as a beginner start off with Visual Studio. It has a very good and easy to use debugger. Just create a break point in the line from which you want to start debugging (click on the left bar beside the line or right click and create a break point). Once your break points are set you can just simply run the program in debug mode and the execution of the program will halt in the point where the break was created.
At this point you should be able to view all valuable information about the execution of the program. You can use F10 to continue the execution step or F11 to step inside the execution tree.
The debugger as many other advanced features like break on condition , hit count etc but you can start off with it's basic functionality.
If I compiled a program like this:
gcc -o my-prog -g myprog.c
I could then debug the executable my-prog it like this:
gdb my-prog
The -g option tells gcc to generate full debugging info. Other compilers will have their own versions of this option (e.g. the MSVC cl command has the /Zi option).
Since you're having issues running the gdb on your program, it might be worth checking if it was compiled with debugging info in the first place. The debugging info is usually generated in the same location as where you compiled your program.
Using Valgrind or any other debugger in Linux, how can one see places where a variable is modified. I am using gcc. Note that I don't want to step into the code using gdb. I just want to run the program and have the debugger report me in the end, places where the variable is modified in the code.
Hm, thinking about it it's not exact duplicate of Can I set a breakpoint on 'memory access' in GDB?, because it asks a little bit more. So:
Use gdb
Find the address you want to watch (hardware watchpoints only work for watching address, so you have to run it to the point where the variable or object are instantiated, take their address and use the watch command on that address.
Attach command to the address to give you a backtrace (or any other info you need to collect) and continue.
So you'll have something like:
p &variable
watch *$$
cmd
bt
c
end
(I am not completely sure with the $$, I normally use the $n as printed by the p command).
Use Breakpoint Command Lists to do this in gdb. You will have to know the address of variable to watch. Set watchpoint with a series of commands like this:
watch *0xfeedface
commands
silent
bt
cont
end
You can also optionally save all this output to log file. Look gdb doc for more details.
I have an application. I have the source code (in C). I can compile it anyway I want. Add whatever tool I want to it. Etc. However, I do not want to pepper the source code with a bunch of printf's. I want to be able to produce a log of some sort that shows when a particular value (some member of a global structure for example) is written to (its value changes). I'd like to be able to show source file and line number, and the old and new value.
I'd also like to be able to specify the value by name, not address. But address is OK. Bonus points if I can specify a value that is local to a function.
I'm still scratching my head trying to figure out gdb's trace commands. Any help is greatly appreciated. Thanks.
First, you'll need to make sure to compile your program with debug symbols, and probably w/o optimization to make gdb most useful. For gcc, that'd be -g -O0.
Second, the feature you're looking for isn't tracing, its watchpoints.
(gdb) help watch
Set a watchpoint for an expression.
A watchpoint stops execution of your program whenever the value of
an expression changes.
So, given some example code:
int main() {
int a;
a = 1;
a = 2;
return 0;
}
you can then run gdb on it, and:
(gdb) b main
Breakpoint 1 at 0x80483a5: file test.c, line 4.
(gdb) run
Starting program: /tmp/test
Breakpoint 1, main () at test.c:4
4 a = 1;
(gdb) watch a
Hardware watchpoint 2: a
(gdb) c
Continuing.
Hardware watchpoint 2: a
Old value = -1207552288
New value = 2
main () at test.c:8
8 return 0;
it's working slightly funny due to a being on the stack, not memory. And if optimization were on, it'd work even less: a would be optimized out.
As stated already, you need to set a watchpoint on your variable.
The you use the "commands" command
(gdb) help commands
Set commands to be executed when a breakpoint is hit.
Give breakpoint number as argument after "commands".
With no argument, the targeted breakpoint is the last one set.
The commands themselves follow starting on the next line.
Type a line containing "end" to indicate the end of them.
Give "silent" as the first line to make the breakpoint silent;
then no output is printed when it is hit, except what the commands print.
So, find the watchpoint number from the watch command, and do this (assuming your watch is the second break)
(gdp) commands 2
> print a
> cont
> end
Assuming a is the variable you want. You can leave out the print line if you're happy with the output gdb gives you anyway.
You can also use the commands in your original breakpoint to set the watchpoint and continue.
Thank you both #derobert and #peter! I finally went back to this, and this:
break main
commands
watch somevar
commands
cont
end
cont
end
run
does the trick. This works when "somevar" is global, or local to "main". If "somevar" is local to anther function, just replace "main" with that function name above.
Put these commands in a file (e.g. "gdbscript") and run gdb like:
gdb -x gdbscript a.out