When I hit a breakpoint in GDB, and I need to find out what thread this is on, I do info thr. This prints out the list of all the threads in my program, and the current thread is marked with a *
Instead of having GDB dump the entire list of threads, and then manually reading what thread has the *, is there a command in gdb which simply prints out the current thread?
I need this because I am logging some behavior in my program. In other words, I have something like this -
(gdb) command 12
>> p " xyz just happpened"
>> whatThreadIsThis // I would like this
>> c
>> end
If GDB implemented something like the whatThreadIsThis command, then I could use GDB to log all occurrences of xyz with the threads they happened on.
You can use the "thread thread-id" command to switch to another thread as the docs mentions. What the docs doesn't seem to mention is that without any argument, it just prints the current thread:
(gdb) thread
[Current thread is 1 (Thread 0x7ffff7fc2700 (LWP 4641))]
gdb also has Convenience Variables.
One of the them is:
$_thread
The thread number of the current thread.
You can print it with:
(gdb) p $_thread
$2 = 2
Also it can be used in conditions:
condition 1 $_thread != 1
Related
gdb switches a thread when the appropriate breakpoint fires.
I need to remember the thread number to come back with thread n.
Is there a special command to return to the thread where step-by-step execution was performed?
(gdb) n
57 m_app = create_app();
(gdb) n
[Switching to Thread 0x7fffdfffd700 (LWP 32059)]
Thread 9 "foo" hit Breakpoint 1, 0x0000000000421ef0 in App::App()#plt ()
(gdb) # command to return to the interrupted thread
You can setup custom GDB prompt to show current thread number with set extended-prompt:
(gdb) set extended-prompt <\t>
Every time you use any of GDB commands current thread number will be printed in GDB prompt, for example:
<1> thread
[Current thread is 1 (Thread 0x7ffff7dcd740 (LWP 148411))]
<1> info threads
Id Target Id Frame
* 1 Thread 0x7ffff7dcd740 (LWP 148411) "a.out" main () at /home/ks/t.c:7
<1>
With that information in GDB prompt you can return to interrupted thread with:
thread <id_taken_from_prompt_before_interrupt>
I have a multi-threaded program, where each thread is assigned a unique name with help of pthread_setname_np. If I attach to a running program with gdb, I can see their names:
(gdb) i th
Id Target Id Frame
* 1 Thread 0x7f883dba1200 (LWP 3867757) "main" __pthread_clockjoin_ex (threadid=140222870320896, thread_return=0x0, clockid=<optimized out>, abstime=<optimized out>, block=<optimized out>)
at pthread_join_common.c:145
2 Thread 0x7f883477f700 (LWP 3867759) "log_aggregator" 0x00007f883dc8026f in __GI___clock_nanosleep (clock_id=clock_id#entry=0, flags=flags#entry=0, req=0x7f883477b220, rem=0x7f883477b220)
at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:78
Note main and log_aggregator names. However, If I make a core dump and then load this dump with gdb, I don't see the names:
$ gcore 3867757
...
Saved corefile core.3867757
...
$ gdb -c core.3867757 my_program
GNU gdb (Ubuntu 10.2-0ubuntu1~20.04~1) 10.2
...
(gdb) i th
Id Target Id Frame
* 1 Thread 0x7f883dba1200 (LWP 3867757) __pthread_clockjoin_ex (threadid=140222870320896, thread_return=0x0, clockid=<optimized out>, abstime=<optimized out>, block=<optimized out>)
at pthread_join_common.c:145
2 Thread 0x7f883477f700 (LWP 3867759) 0x00007f883dc8026f in __GI___clock_nanosleep (clock_id=clock_id#entry=0, flags=flags#entry=0, req=0x7f883477b220, rem=0x7f883477b220)
at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:78
How do I get thread names in this case? Or should I create core file differently to put them in the core file? I examined coredump_filter option, but did not find anything related. I also discovered this discussion at narkive mailing list archive, but it does not provide an answer, only a suggestion that this might be impossible.
My next question would be is there any way this /proc/self/task/[tid]/comm
The /proc/.../comm is not a real file, it's a representation of kernel data structures related to this task generated on-demand (when you try to read that "file").
The current->comm field that you are looking for is not mentioned in the binfmt_elf.c file (which is where other core dumping code is), so it's probably not saved.
In fact this is easily confirmed by running a test program generating a random string, calling pthread_setname_np, dumping core and then running strings -a core | grep $string, which produces no output.
There is no fundamental reason the current->comm can not be saved in the core, but currently it isn't.
P.S. Usually looking at thread apply all where is enough to distinguish different threads, so the unique thread name is redundant and unnecessary.
Why is GDB not able to see my local variable i ?
I am debugging a multi-process application running on an embedded linux device.
I am having a hard time attaching to a child process (note that I cannot start the child process by itself, it needs the parent to run it. )
Using set follow-fork-mode child did not work (gdb hangs while loading dynamic libraries).
My strategy is to have this in my code to stop the child
#ifdef DEBUG
int i = 0;
while (i == 0)
{
usleep(100000); // sleep for 0.1 seconds
}
#endif // DEBUG
To have time to attach to the child using gdbserver --attach :1234 <child-pid> and then, after setting a break point where I want (line 200 in main.cpp), to issue the following command in gdb : set var i = 1 to break out of the while loop.
This isn't working and I am wondering why. Here is the output from gdb:
(gdb) bt
#0 0x00007ff3feab7ff0 in nanosleep () from target:/lib/libc.so.6
#1 0x00007ff3feae1c14 in usleep () from target:/lib/libc.so.6
#2 0x000055cc4e56908a in main (argc=<optimized out>, argv=<optimized out>)
at platform/aas/intc/ucmclient/src/main.cpp:195
(gdb) break main.cpp:200
Breakpoint 1 at 0x55cc4e56908c: file platform/aas/intc/ucmclient/src/main.cpp, line 200.
(gdb) set var i=1
No symbol "i" in current context.
The backtrace seems to show I am in the while loop. Why then is the variable i not in the locals?
I'm currently writing a multi-threaded, high efficient and scalable algorithm. Because I have to guess a parameter for the code and I'm not sure how the calculation performs on a specific data set, I would like to watch a variable. The test only works with a real world, huge data set. It is possible to analyze the collected data after profiling. Imagine the following, simple code example (real code can contain multiple watch points:
// function get's called by loops of multiple threads
void payload(data_t* data, double threshold) {
double value = calc(data);
// here I want to watch the value
if (value < threshold) {
doSomething(data);
} else {
doSomethingElse(data);
}
}
I thought about the following approaches:
Using cout or other system outputs
Use a binary output (file, network)
Set a breakpoint via gdb/lldb
Use variable watching + logging via gdb/lldb
I'm not happy with the results because: To use 1. and 2. I have to change the code, but this is a debugging/evaluating task. Furthermore 1. requires locking and 1.+2. requires I/O operations, which heavily slows down the entire code and makes testing with real data nearly impossible. 3. is also too slow. To use 4., I have to know the variable address because it's not a global variable, but because threads get created by a dynamic scheduler, this would require breaking + stepping for each thread.
So my conclusion is, that I need a profiler/debugger that works at machine code level and dumps/logs/watches the variable without double->string conversion and is highly efficient, or to sum up with other words: I would like to profile the internal state of my algorithm without heavy slow-down and without doing deep modification. Does anybody know a tool that is able to this?
OK, this took some time but now I'm able to present a solution for my problem. It's called tracepoints. Instead of breaking the program every time, it's more lightweight and (ideally) doesn't change performance/timing too much. It does not require code changes. Here is an explanation how to use them using gdb:
Make sure you compiled your program with debugging symbols (using the -g flag). Now, start the gdb server and provide a network port (e.g. 10000) and the program arguments:
gdbserver :10000 ./program --parameters you --want --to use
Now, switch to a second console and start gdb (program parameters are not required here):
gdb ./program
All following commands are entered in the gdb command line interface. So let's connect to the server:
target remote :10000
After you got the connection confirmation, use trace or ftrace to set a tracepoint to a specific source location (try ftrace first, it should be faster but doesn't work on all platforms):
trace source.c:127
This should create tracepoint #1. Now you can setup an action for this tracepoint. Here I want to collect the data from myVariable
action 1
collect myVariable
end
If expect much data or want to use the data later (after restart), you can set a binary trace file:
tsave trace.bin
Now, start tracing and run the program:
tstart
continue
You can wait for program exit or interrupt your program using CTRL-C (still on gdb console, not on server side). Continue by telling gdb that you want to stop tracing:
tstop
Now we come the tricky part and I'm not really happy with the following code because it's really slow:
set pagination off
set logging file trace.txt
tfind start
while ($trace_frame != -1)
set logging on
printf "%f\n", myVariable
set logging off
tfind
end
This dumps all variable data to a text file. You can add some filter or preparation here. Now you're done and you can exit gdb. This will also shutdown the server:
quit
For detailed documentation especially for explanation of filtering and more advanced tracepoint positions, you can visit the following document: http://sourceware.org/gdb/onlinedocs/gdb/Tracepoints.html
To isolate trace file writing from your program execution, you can use cgroups or another network connected computer. When using another computer, you have to add the host to the port information (e.g. 192.168.1.37:10000). To load a binary trace file later, just start gdb as shown above (forget the server) and change the target:
gdb ./program
target tfile trace.bin
you can set hardware watchpoint using gdb debugger, for example if you have
bool b;
variable and you want to be notified every time the value of it has chenged (by any thread)
you would declare a watchpoint like this:
(gdb) watch *(bool*)0x7fffffffe344
example:
root#comp:~# gdb prog
GNU gdb (GDB) 7.5-ubuntu
Copyright ...
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /dist/Debug/GNU-Linux-x86/cppapp_socket5_ipaddresses...done.
(gdb) watch *(bool*)0x7fffffffe344
Hardware watchpoint 1: *(bool*)0x7fffffffe344
(gdb) start
Temporary breakpoint 2 at 0x40079f: file main.cpp, line 26.
Starting program: /dist/Debug/GNU-Linux-x86/cppapp_socket5_ipaddresses
Hardware watchpoint 1: *(bool*)0x7fffffffe344
Old value = true
New value = false
main () at main.cpp:50
50 if (strcmp(mask, "255.0.0.0") != 0) {
(gdb) c
Continuing.
Hardware watchpoint 1: *(bool*)0x7fffffffe344
Old value = false
New value = true
main () at main.cpp:41
41 if (ifa ->ifa_addr->sa_family == AF_INET) { // check it is IP4
(gdb) c
Continuing.
mask:255.255.255.0
eth0 IP Address 192.168.1.5
[Inferior 1 (process 18146) exited normally]
(gdb) q
I was debugging my app with gdb.
I used break main
So it can break when main is called.
Know if I use thread info it shows that thread count is 1.
How a thread is starting before main ?
I don't have any thread call in my call so from where thread is getting created. I am using these libs
sqlite , curl , pcre , c-client
Update
I have written a sample program to test that if all program start with single thread
#include<iostream>
int main(int argc,char *argv[]){
std:: cout<<"Will I have any thread";
return 0;
}
but when I debug it with gdb
(gdb) break main
Breakpoint 1 at 0x400783: file threadtest.cpp, line 3.
(gdb) run
Starting program: /home/vivek/Desktop/a.out
Breakpoint 1, main (argc=1, argv=0x7fffffffe728) at threadtest.cpp:3
3 std:: cout<<"Will I have any thread";
(gdb) info threads
* 1 process 21608 main (argc=1, argv=0x7fffffffe728) at threadtest.cpp:3
(gdb)
it doesn't show the same information. It show 1 process not 1 thread.
When I compile it with -lpthread it show 1 thread.
So program start with one thread when we use lpthread ?
or GDB behaves like that ?
All programs have at least 1 thread, the main thread. The program is started before main since the C++ runtime does some initializing before main() starts, like calling all global objects which have constructors.
The operating system creates a process space with one thread and calls the application loader to execute the application in that thread, which in turns performs some initial setup (gathering command line arguments into argc and argv, for example) and calls main.
For the sample App when I compile it with -lpthread it shows 1 thread is running.
So lpthread is playing key point here.
(gdb) break main
Breakpoint 1 at 0x400793: file threadtest.cpp, line 3.
(gdb) run
Starting program: /home/vivek/Desktop/a.out
[Thread debugging using libthread_db enabled]
Breakpoint 1, main (argc=1, argv=0x7fffffffe728) at threadtest.cpp:3
3 std:: cout<<"Will I have any thread";
(gdb) info threads
* 1 Thread 0x2aaaaaac8bb0 (LWP 21649) main (argc=1, argv=0x7fffffffe728)
at threadtest.cpp:3
(gdb)