System
Fresh install of codeblocks 12.11 + mingw pack.
win7 64
gcc 4.7.1
gdb 7.5
Example code
Compiled with -g and no optimization.
#include <stdio.h>
void foo(int a, int b);
int main() {
foo(400, 42);
return 0;
}
void foo(int a, int b) {
a = a - 10;
b = a + 1;
printf("y2 %d\n", b);
}
Problem
I put a breakpoint on "void foo(int a, int b)" and I look value of b as I step through the 3 lines.
Either with the codeblocks debugging features or with the gdb command line, the value of b is 42 instead of being 391.
The console output is correct, 391.
GDB commands
C:\DebugTest>"C:\Program Files (x86)\CodeBlocks\MinGW\bin\gdb.exe"
GNU gdb (GDB) 7.5
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-mingw32".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
(gdb) file bin/Debug/DebugTest.exe
Reading symbols from C:\DebugTest\bin\Debug\DebugTest.exe...done.
(gdb) break foo
Breakpoint 1 at 0x401363: file C:\DebugTest\main.c, line 14.
(gdb) run
Starting program: C:\DebugTest\bin\Debug\DebugTest.exe
[New Thread 3596.0x658]
Breakpoint 1, foo (a=400, b=42) at C:\DebugTest\main.c:14
14 a = a - 10;
(gdb) print b
$1 = 42
(gdb) step
15 b = a + 1;
(gdb) print b
$2 = 42
(gdb) step
17 printf("y2 %d\n", b);
(gdb) print b
$3 = 42
(gdb)
Remarks
When the same operations are done without a function, with a and b as local variables inside main, the debug output is correct.
When compiled with gcc 4.4.1, the debug output is correct.
Any idea what could be wrong ? =)
I searched on gcc bugzilla and found this bug report :
Bug 54218 - Debug info for function parameters is incorrect when compiled with -O0"
Althoug the report is about gcc 4.8 and I'm using 4.7, I tried the proposed workaround and it works !
Compiling with -fvar-tracking allows GDB to print the correct value for b after assignment.
gcc does not generate debugging info correctly for values that are in registers -- either values that have been put in registers or values that start there due to the calling conventions. This is a long-standing problem with gcc since at least 4.0, and makes it tricky to debug things.
Sometimes the optimizer is smarter than the debugger. Try debugging unoptimized code, or step through disassembly and watch the HW registers directly rather than stepping through C source lines and watching the debugger's idea of what the variables are.
Related
Need to extract a few values from an auxiliary vector. You can read more about it here. That's where I got and slightly modified code below:
#include <stdio.h>
#include <elf.h>
int main(int argc, char* argv[], char* envp[])
{
Elf64_auxv_t *auxv;
while (*envp++ != NULL); /* from stack diagram above: *envp = NULL marks end of envp */
for (auxv = (Elf64_auxv_t *)envp; auxv->a_type != AT_NULL; auxv++)
/* auxv->a_type = AT_NULL marks the end of auxv */
{
if (AT_EXECFN == auxv->a_type)
{
char *str = (char *)auxv->a_un.a_val;
printf("%s\n", str);
break;
}
}
return 0;
}
I compile the code with gcc -g aux-extractor.c.
Here is the weird part. If I run the code as ./a.out I get and output as ./a.out which makes sense. However when I debug it in gdb and print the value at a specific address I get /tmp/a.out, which also makes sense I compiled my code in /tmp directory. My question is why I'm getting two different results, a.out and /tmp/a.out?
Here is my debugging session (pay attention to the output of the x/s command:
$ gdb ./a.out
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu". T
ype "show configuration" for configuration details.
For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./a.out...
(gdb) start
Temporary breakpoint 1 at 0x1149: file auxv-extractor.c, line 5.
Starting program: /tmp/a.out
Temporary breakpoint 1, main (argc=21845, argv=0x0, envp=0x5555555551c0 <__libc_csu_init>) at auxv-extractor.c:5
5 {
(gdb) break 15
Breakpoint 2 at 0x555555555198: file auxv-extractor.c, line 15.
(gdb) c
Continuing.
Breakpoint 2, main (argc=1, argv=0x7fffffffe408, envp=0x7fffffffe520) at auxv-extractor.c:15
15 printf("%s\n", str);
(gdb) x/s str
0x7fffffffefed: "/tmp/a.out"
(gdb)
When gdb runs your program, it does so by executing /tmp/a.out, having expanded the path from the ./a.out on the command line.
GDB has a habit of starting the program with $(realpath ./a.out) when ./a.out is given on the command line.
I've tried to set exec-wrapper as a way to avoid this, but was not successful -- even when setting exec-wrapper wrapper.sh with this contents:
#!/bin/bash
exec -a "./a.out" "$#"
the AT_EXECFN remains /tmp/a.out.
This answer shows how to pause the program after main() to make it easy to attach GDB from "outside". AT_EXECFN will be set to ./a.out as expected, and you can continue debugging as you normally would.
All my static __thread values shown as <optimized out> when, in debugging, I want to watch the value of a variable; even with -o0 and/or volatile.
Static Variables without __thread are shown correctly.
Is there anyway to show the values of the variable even though I'm working with threads?
Using Win10 (CreateThread), eclipse CDT, c11, mingw64-w64 and gdb 7.11.1
A workaround may be: add some printers of thread local variables in your code, and let gdb call them. (Or if you are familiar with x86 assembly, write some hackish plugin to modify the executable memory to read out fs:offset/gs:offset (thread local variable value) and recover the memory & register)
To be more specific, add a function to the C code that does nothing but return the interesting __thread variable, and when you break the program using gdb, you can always make gdb call that function for you (assume that the function is not optimized) without corrupting the stack frame of the original program. it should be as easy as:
(gdb) p rand()
$1 = 1804289383
(gdb) p rand()
$2 = 846930886
(gdb) p rand()
$3 = 1681692777
although rand is not a good example since it has side effect. TLS variable read does not have side effect.
Example: (under Ubuntu 16.04, but things shouldn't have much difference since the functionality is very basic)
tls.cpp:
#include <stdio.h>
__thread long thread_cand;
long what_is_thread_cand()
{
return thread_cand;
}
int main()
{
while ( !feof ( stdin ) )
{
scanf ( "%ld", &thread_cand );
printf ( "%p : %ld\n", &thread_cand, thread_cand );
}
return 0;
}
terminal:
$ g++ -O2 -g3 tls.cpp -o tls
tls.cpp: In function ‘int main()’:
tls.cpp:14:38: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
scanf ( "%ld", &thread_cand );
^
$ gdb tls --nh
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.04) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from tls...done.
(gdb) r
Starting program: /home/ubuntu/tls
123
0x7ffff7fcb6f8 : 123
432
0x7ffff7fcb6f8 : 432
^C
Program received signal SIGINT, Interrupt.
0x00007ffff7b04230 in __read_nocancel ()
at ../sysdeps/unix/syscall-template.S:84
84 ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb) p thread_cand
Cannot find thread-local storage for process 6472, executable file /home/ubuntu/tls:
Cannot find thread-local variables on this target
(gdb) p what_is_thread_cand()
$1 = 432
(gdb)
code sample(foo.c)
int main(){
int *x=(int*)malloc(sizeof(int)); // break here
*x=10;
free(x);
return 0;
}
I want to break at malloc. Here is what I try:
# gcc -g foo.c -o bar
# gdb bar
(gdb) b main
Breakpoint 1 at 0x80484cf: file src.c, line 7.
(gdb) r
Breakpoint 1, main () at src.c:7
(gdb) b malloc
Breakpoint 2 at 0x550944
(gdb) c
Program exited normally.
My system spec is:
OS: CentOS 5.5
gcc: gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-52)
gdb: GNU gdb (GDB) Red Hat Enterprise Linux (7.0.1-42.el5)
Please tell me where am I going wrong!!
I cannot reliably reproduce the error, but on Linux you could try breaking at __libc_malloc instead of malloc.
Resolved
Figured it out,
Actually breakpoint was being set in ld-linux.so instead of libc.so, could resolve it using:
b __malloc
b __libc_malloc
Thanks for looking into it!!
Though a new question would be:
how to ask gdb to set breakpoints only in a specific library (I know it can be done for a file)!!
I'm currently following this video on how to work with assembly and gdb, using this C program, but I'm running into a problem. Here's what I do to compile and run gdb:
chiggins#host:~/assem$ gcc -ggdb -o SimpleDemo SimpleDemo.c
chiggins#host:~/assem$ gdb ./SimpleDemo
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2) 7.4-2012.04
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /home/chiggins/assem/SimpleDemo...done.
(gdb) list
4 int add(int x, int y)
5 {
6 int z =10;
7
8 z = x + y;
9 return z;
10 }
11
12 main(int argc, char **argv)
13 {
(gdb)
14 int a = atoi(argv[1]);
15 int b = atoi(argv[2]);
16 int c;
17 char buffer[100];
18
19 gets(buffer);
20 puts(buffer);
21
22 c = add(a,b);
23
(gdb)
24 printf("Sum of %d+%d = %d\n",a, b, c);
25
26 exit(0);
27
28 }
(gdb) run 10 20
Starting program: /home/chiggins/assem/SimpleDemo 10 20
demo
Now from where I have "demo" typed at the end, that's where the program is supposed to be accepting user input. But when I press return after typing enter, nothing happens. I can't ctrl+c out of the program, can't do anything. I end up having to kill the process from another session just so I can get control back. Any ideas why gdb is doing this, or what I might be doing wrong?
Thanks!
I'm not sure why that doesn't work for you; it works as expected here...
Still, I find it easier to run programs performing interactive I/O in a separate terminal, and perhaps it will help you.
In one terminal,
$ gdbserver --multi localhost:4242
listening on port 4242
and in another,
$ gdb ./SimpleDemo
(gdb) target extended-remote localhost:4242
Remote debugging using localhost:4242
(gdb) run 10 20
Back to the terminal running gdbserver,
Remote debugging from host 127.0.0.1
Process ./SimpleDemo created; pid=PID
demo
demo
Sum of 10+20 = 30
Child exited with status 0
Are you trying to have user input during the program? If you simply want to set command line arguments at the beginning you can just say set args ... where you can give the arguments as you would during the course of the program.
Have you tried this?
gdb --args ./SimpleDemo 10 20
Use Ctrl+Enter instead of the Enter key.
I have a multithreaded (pthreads) program in which main() calls a function omp_file_open_all() and passes in a string as char* alongwith other arguments. I was debugging something using gdb and saw that gdb does not print out the string value correctly, whereas a printf inside the function prints it out correcly.
Breakpoint 1, omp_file_open_all (fd=0x423bb950, filename=0x7f605df078e0 "", mode=-16843009) at pthread_coll_file_open.c:29
29 if(omp_get_thread_num() == MASTER)
(gdb) print filename
$1 = 0x7f605df078e0 ""
So gdb shows filename as empty, whereas a printf inside the function outputs the correct value as "/tmp/test.out". The function being called (omp_file_open_all) is defined as follows (not in the same file as main()):
int omp_file_open_all (int fd, char* filename, int mode);
I cant post my program here as this is a part of a larger code thats approx. 1500 lines of code. 'filename' is a global variable and is set in main() by the main thread before newer threads are spawned.
So this is not an error, and I merely stumbled across it, but I am interested in finding out why gdb does not display the correct value.
OS: 64bit OpenSUSE,
gdb 6.8
Thanks for your help.
There might be some thing going wrong in your code. With the following code snippet, I am getting the string printed by gdb correctly.
#include <stdio.h>
#include <stdlib.h>
void checkString( char* fileName )
{
printf("%s", fileName);
}
int main()
{
char* name = "temp";
checkString(name);
return 0;
}
mahesh-babu-vattiguntas-macbook-pro:Desktop mahesh$ gdb gdb.out
GNU gdb 6.3.50-20050815 (Apple version gdb-1469) (Wed May 5 04:36:56 UTC 2010)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin"...Reading symbols for shared libraries .. done
(gdb) b gdb.c:6
Breakpoint 1 at 0x100000ebc: file gdb.c, line 6.
(gdb) run gdb.out
Starting program: /Users/mahesh/Desktop/gdb.out gdb.out
Reading symbols for shared libraries +. done
Breakpoint 1, checkString (fileName=0x100000f05 "temp") at gdb.c:6
6 printf("%s", fileName);
(gdb) p fileName
$1 = 0x100000f05 "temp"
(gdb)
Try stepping forward one line (gdb "s" command) after you hit the breakpoint, then try printing it again. I've sometimes seen gdb have trouble displaying parameter values correctly when breaking at the beginning of a function.
My first guess was that there is a scoping issue, since the name of the function parameter and your global variable is identical. However, this does not seem to be the case for the following very small program:
#include <cstdio>
static char const* filename = "something";
int foobar(char const* filename)
{
printf("%s\n", filename);
}
int main(int argc, char** argv)
{
return foobar("somethingelse");
}
Compiled with:
g++ -ggdb -g3 -O0 test.cpp -o test
GDB (7.2, also on x64 but Ubuntu) gives:
Breakpoint 1, foobar (filename=0x400706 "somethingelse") at test.cpp:7
7 printf("%s\n", filename);
(gdb) p filename
$1 = 0x400706 "somethingelse"
So it's not about scoping per-se. Also, the output suggests that the parameter is indeed an empty string at execution time. Could you please provide us with the output of bt at the same time you break into the debugger? Last two stack frames are sufficient.