I'd built a version of gdb 7.0 for myself after being pointed to a new feature, and happened to have that in my path still.
Attempting to step through some new code, I'd added a pause() call, expecting to be able to get out like so:
(gdb) b 5048
Breakpoint 1 at 0x2b1811b25052: file testca.C, line 5048.
(gdb) signal SIGCONT
Continuing with signal SIGCONT.
Breakpoint 1, FLUSH_SUDF_TEST (h=#0x2b1811b061c0) at testca.C:5048
5048 rc = h.SAL_testcaFlushPagesByUDF( uPrimary - 1, uPrimary ) ;
(that was with the system gdb, version 6.6).
With gdb 7.0 I never hit the post-pause() breakpoint when I try this. With the various multi process debugging changes in gdb 7, does anybody know if signal handling has to be handled differently and how?
The pause() function does not return unless a signal handler is called (see the specification and the man page).
To make it return after your program receives SIGCONT, you must install an handler for SIGCONT. Try and see using the following example:
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
volatile int caught_signal = 0;
void handler(int sig)
{
caught_signal = sig;
}
int main()
{
signal(SIGCONT, handler);
pause();
printf("Caught signal: %d, %s\n",
caught_signal, strsignal(caught_signal));
return 0;
}
The behavior is correct with gdb 7.0: pause() completely ignores ignored signals (like SIGCHLD, returns on caught signals (SIGCONT), and no signal is delivered when the continue command is issued.
(gdb) break 17
Breakpoint 1 at 0x80484b3: file pause.c, line 17.
(gdb) continue
Continuing.
^C
Program received signal SIGINT, Interrupt.
0x0012d422 in __kernel_vsyscall ()
(gdb) signal SIGCHLD
Continuing with signal SIGCHLD.
^C
Program received signal SIGINT, Interrupt.
0x0012d422 in __kernel_vsyscall ()
(gdb) signal SIGCONT
Continuing with signal SIGCONT.
Breakpoint 1, main () at pause.c:17
17 printf("Caught signal: %d, %s\n",
(gdb)
Related
My binary (generated from C++) has two threads. When I care about exceptions, I care about exceptions thrown in one of them (the worker) but not the other.
Is there a way to tell gdb only to pay attention to one of the threads when using catch throw? The gdb manual (texinfo document) and googling suggest to me that this isn't possible, although I think I could request catching a specific type of exception, which hopefully only one of the threads would throw, using catch throw REGEXP.
Is there a way to tell gdb only to pay attention to one of the threads
The catch throw is really just a fancy way to set a breakpoint on __cxxabiv1::__cxa_throw (or similar), and you can make a breakpoint conditional on thread number, achieving the equivalent result.
Example:
#include <pthread.h>
#include <unistd.h>
void *fn(void *)
{
while(true) {
try {
throw 1;
} catch (...) {}
sleep(1);
}
return nullptr;
}
int main() {
pthread_t tid;
pthread_create(&tid, nullptr, fn, nullptr);
fn(nullptr);
return 0;
}
g++ -g -pthread t.cc
Using catch throw, you would get a breakpoint firing on the main and the second thread. But using break ... thread 2 you would only get the one breakpoint you care about:
gdb -q a.out
Reading symbols from a.out...
(gdb) start
Temporary breakpoint 1 at 0x11d6: file t.cc, line 17.
Starting program: /tmp/a.out
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Temporary breakpoint 1, main () at t.cc:17
17 pthread_create(&tid, nullptr, fn, nullptr);
(gdb) n
[New Thread 0x7ffff7a4c640 (LWP 1225199)]
## Note: GDB refuses to set thread-specific breakpoint until the thread actually exists.
18 fn(nullptr);
(gdb) break __cxxabiv1::__cxa_throw thread 2
Breakpoint 2 at 0x7ffff7e40370: file ../../../../src/libstdc++-v3/libsupc++/eh_throw.cc, line 77.
(gdb) c
Continuing.
[Switching to Thread 0x7ffff7a4c640 (LWP 1225199)]
Thread 2 "a.out" hit Breakpoint 2, __cxxabiv1::__cxa_throw (obj=0x7ffff0000be0, tinfo=0x555555557dc8 <typeinfo for int#CXXABI_1.3>, dest=0x0) at ../../../../src/libstdc++-v3/libsupc++/eh_throw.cc:77
77 ../../../../src/libstdc++-v3/libsupc++/eh_throw.cc: No such file or directory.
(gdb) bt
#0 __cxxabiv1::__cxa_throw (obj=0x7ffff0000be0, tinfo=0x555555557dc8 <typeinfo for int#CXXABI_1.3>, dest=0x0) at ../../../../src/libstdc++-v3/libsupc++/eh_throw.cc:77
#1 0x00005555555551b5 in fn () at t.cc:8
#2 0x00007ffff7d7eeae in start_thread (arg=0x7ffff7a4c640) at pthread_create.c:463
#3 0x00007ffff7caea5f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
(gdb) c
Continuing.
Thread 2 "a.out" hit Breakpoint 2, __cxxabiv1::__cxa_throw (obj=0x7ffff0000be0, tinfo=0x555555557dc8 <typeinfo for int#CXXABI_1.3>, dest=0x0) at ../../../../src/libstdc++-v3/libsupc++/eh_throw.cc:77
77 in ../../../../src/libstdc++-v3/libsupc++/eh_throw.cc
(gdb) bt
#0 __cxxabiv1::__cxa_throw (obj=0x7ffff0000be0, tinfo=0x555555557dc8 <typeinfo for int#CXXABI_1.3>, dest=0x0) at ../../../../src/libstdc++-v3/libsupc++/eh_throw.cc:77
#1 0x00005555555551b5 in fn () at t.cc:8
#2 0x00007ffff7d7eeae in start_thread (arg=0x7ffff7a4c640) at pthread_create.c:463
#3 0x00007ffff7caea5f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
VoilĂ -- thread-specific catch throw equivalent.
For the first time I use gdb to call the function Test(), it shows gdborig.exe has stopped working.
#include <cstdio>
int a=1;
int Test(){
return ++a;
}
int main(){
printf("%d",Test());
return 0;
}
Then I reboot the cmd, this time it just exit without any warning.
Reading symbols from Test... done.
(gdb) b 7
Breakpoint 1 at Ox401573: file Test.cpp, line 7.
(gdb) r
Starting program: C:\Users\He\Desktop\Test.exe
[New Thread 12420. Ox41ec]
[New Thread 12420. Ox2c68]
Thread 1 hit Breakpoint 1, main () at Test.cpp:7
7 printf("%d", Test()) ;
(gdb) call Test()
The gdb version is gdb-8.1
In some of the answers to related questions I could see that gdb 7.3 should support displaying thread names atleast with 'info threads' command .
But I am not even getting that luxury. please help me to understand what I am doing wrong.
My sample code used for testing:
#include <stdio.h>
#include <pthread.h>
#include <sys/prctl.h>
static pthread_t ta, tb;
void *
fx (void *param)
{
int i = 0;
prctl (PR_SET_NAME, "Mythread1", 0, 0, 0);
while (i < 1000)
{
i++;
printf ("T1%d ", i);
}
}
void *
fy (void *param)
{
int i = 0;
prctl (PR_SET_NAME, "Mythread2", 0, 0, 0);
while (i < 100)
{
i++;
printf ("T2%d ", i);
}
sleep (10);
/* generating segmentation fault */
int *p;
p = NULL;
printf ("%d\n", *p);
}
int
main ()
{
pthread_create (&ta, NULL, fx, 0);
pthread_create (&tb, NULL, fy, 0);
void *retval;
pthread_join (ta, &retval);
pthread_join (tb, &retval);
return 0;
}
Output( using core dump generated by segmentation fault)
(gdb) core-file core.14001
[New LWP 14003]
[New LWP 14001]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/libthread_db.so.1".
Core was generated by `./thread_Ex'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x08048614 in fy (param=0x0) at thread_Ex.c:30
30 printf("%d\n",*p);
(gdb) info threads
Id Target Id Frame
2 Thread 0xb77d76c0 (LWP 14001) 0x00b95424 in __kernel_vsyscall ()
* 1 Thread 0xb6dd5b70 (LWP 14003) 0x08048614 in fy (param=0x0) at thread_Ex.c:30
(gdb) bt
#0 0x08048614 in fy (param=0x0) at thread_Ex.c:30
#1 0x006919e9 in start_thread () from /lib/libpthread.so.0
#2 0x005d3f3e in clone () from /lib/libc.so.6
(gdb) thread apply all bt
Thread 2 (Thread 0xb77d76c0 (LWP 14001)):
#0 0x00b95424 in __kernel_vsyscall ()
#1 0x006920ad in pthread_join () from /lib/libpthread.so.0
#2 0x080486a4 in main () at thread_Ex.c:50
Thread 1 (Thread 0xb6dd5b70 (LWP 14003)):
#0 0x08048614 in fy (param=0x0) at thread_Ex.c:30
#1 0x006919e9 in start_thread () from /lib/libpthread.so.0
#2 0x005d3f3e in clone () from /lib/libc.so.6
(gdb) q
As you can see I cant see any thread names that I have set. what could be wrong?
Note:
I am using gdb version 7.7 (Downloaded and compiled using no special options)
commands used to compile & install gdb : ./configure && make && make install
As far as I am aware, thread names are not present in the core dump.
If they are available somehow, please file a gdb bug.
I get thread name displayed on CentOS6.5, but not displayed on CentOS6.4 .
I am trying to implement a thread pool using ACE Semaphore library. It does not provide any API like sem_getvalue which is in Posix semaphore. I need to debug some flow which is not behaving as expected. Can I examine the semaphore in GDB. I am using Centos as OS.
I initialized two semaphores using the default constructor providing count 0 and 10. I have declared them as static in the class and initialized it in the cpp file as
DP_Semaphore ThreadPool::availableThreads(10);
DP_Semaphore ThreadPool::availableWork(0);
But when I am printing the semaphore in GDB using the print command, I am getting the similar output
(gdb) p this->availableWork
$7 = {
sema = {
semaphore_ = {
sema_ = 0x6fe5a0,
name_ = 0x0
},
removed_ = false
}
}
(gdb) p this->availableThreads
$8 = {
sema = {
semaphore_ = {
sema_ = 0x6fe570,
name_ = 0x0
},
removed_ = false
}
}
Is there a tool which can help me here, or shall I switch to Posix thread and re-write all my code.
EDIT: As requested by #timrau the output of call this->availableWork->dump()
(gdb) p this->availableWork.dump()
[Switching to Thread 0x2aaaae97e940 (LWP 28609)]
The program stopped in another thread while making a function call from GDB.
Evaluation of the expression containing the function
(DP_Semaphore::dump()) will be abandoned.
When the function is done executing, GDB will silently stop.
(gdb) call this->availableWork.dump()
[Switching to Thread 0x2aaaaf37f940 (LWP 28612)]
The program stopped in another thread while making a function call from GDB.
Evaluation of the expression containing the function
(DP_Semaphore::dump()) will be abandoned.
When the function is done executing, GDB will silently stop.
(gdb) info threads
[New Thread 0x2aaaafd80940 (LWP 28613)]
6 Thread 0x2aaaafd80940 (LWP 28613) 0x00002aaaac10a61e in __lll_lock_wait_private ()
from /lib64/libpthread.so.0
* 5 Thread 0x2aaaaf37f940 (LWP 28612) ThreadPool::fetchWork (this=0x78fef0, worker=0x2aaaaf37f038)
at ../../CallManager/src/DP_CallControlTask.cpp:1043
4 Thread 0x2aaaae97e940 (LWP 28609) DP_Semaphore::dump (this=0x6e1460) at ../../Common/src/DP_Semaphore.cpp:21
2 Thread 0x2aaaad57c940 (LWP 28607) 0x00002aaaabe01ff3 in __find_specmb () from /lib64/libc.so.6
1 Thread 0x2aaaacb7b070 (LWP 28604) 0x00002aaaac1027c0 in __nptl_create_event () from /lib64/libpthread.so.0
(gdb)
sema.semaphore_.sema_ in your code looks like a pointer. Try to find it's type in the ACE headers, then convert it to a type and print:
(gdb) p *((sem_t)0x6fe570)
Update: try to convert the address within the structure you posted to sem_t. If you use linux, ACE should be using posix semaphores, so type sem_t must be visible to gdb.
Here is a simple application that handled CTRL+C signal both on linux and windows:
#include <QtCore/QCoreApplication>
#include <QDebug>
#include <QThread>
void SigIntHandler()
{
qDebug()<<"SigInt ThreadID: "<<QThread::currentThreadId();
qApp->quit();
}
#ifdef __linux__
#include <signal.h>
void unix_handler(int s)
{
//svakako je SIGINT, ali da ne javlja warning da se s ne koristi
if (s==SIGINT)
SigIntHandler();
}
#else
#include <windows.h>
BOOL WINAPI WinHandler(DWORD CEvent)
{
switch(CEvent)
{
case CTRL_C_EVENT:
SigIntHandler();
break;
}
return TRUE;
}
#endif
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
//kod za hvatanje CTRL+C - unix i windows
#ifdef __linux__
signal(SIGINT, &unix_handler);
#else
SetConsoleCtrlHandler((PHANDLER_ROUTINE)WinHandler, TRUE);
#endif
qDebug()<<"Main ThreadID: "<<QThread::currentThreadId();
return a.exec();
}
After compiling and running it on linux (Debian Squeeze), I get following output:
/Test-build-desktop$ ./Test
Main ThreadID: 140105475446560
^CSigInt ThreadID: 140105475446560
/Test-build-desktop$ ./Test
Main ThreadID: 140369579480864
^CSigInt ThreadID: 140369579480864
/Test-build-desktop$ ./Test
Main ThreadID: 140571925509920
^CSigInt ThreadID: 140571925509920
And that's what I've expected (SigIntHandler method runs on main thread). But when I compile and execute same code on Windows 7, I get this:
d:\Test-build-desktop\debug>Test.exe
Main ThreadID: 0x5a8
SigInt ThreadID: 0x768
d:\Test-build-desktop\debug>Test.exe
Main ThreadID: 0x588
SigInt ThreadID: 0x1434
d:\Test-build-desktop\debug>Test.exe
Main ThreadID: 0x1170
SigInt ThreadID: 0xc38
As you can see, here SigIntHandler method is executed in different thread then main ... And that creates me many problems. So my question is - is it possible to force SigIntHandler to run in main thread on windows ? Am I maybe catching siging wrong ?
Thanks !!
From MSDN topic HandlerRoutine:
A HandlerRoutine function is an application-defined function used with the SetConsoleCtrlHandler function. A console process uses this function to handle control signals received by the process. When the signal is received, the system creates a new thread in the process to execute the function.
So, the answer is: this is impossible.
Read the following link for an interesting take on this: http://blogs.msdn.com/b/oldnewthing/archive/2008/07/28/8781423.aspx