gdb 为什么遇到 pthead_create 就不继续调试了???

xliu32 2008-01-21 04:38:40
我用GDB调试一个多文件的C++的Project,在调试到pthread_create()函数时,发现无论时用s(tep) or n(ext)or c(ontinue)都不能继续进入到下面的断点中,程序总是一直运行到结束。

用GDB调试如何调试多线程呢?具体针对我的问题来说,怎样在进行到pthread_create()函数时,程序还能继续调试下去呢?

在网上搜了很多,似乎都没有我这种问题,弄了一天了,好着急啊。希望大侠和好心人帮助解答。

The following is some related code:

先是这句话被执行
_threadHandler.SpawnThreadWorker();

然后走到这个函数:
void ThreadHandler::SpawnThreadWorker( void )
// ******************************************
// Spawns the 'worker' thread, which starts us into the Framework class.
{
Framework *fw;
int ret;

LOG( INFO, "Spawning worker thread..." );

fw = new Framework;
Program::Instance()->SetFW( fw );

ret = pthread_create( &_tidW, &_attr, ThreadHandler::ThreadWorker, fw );

if( ret != 0 ) {
LOG( EMERG, "Error spawning thread: %s", strerror( errno ) );
exit( EXIT_FAILURE );
}
_tidWDead = false;
}

调试到pthread_creat处,程序就开始哗啦啦的Run起来,后面设的断点根本没有停住。为什么啊?好奇怪啊?
焦急等待解答中!!!!!Thanks very much!!!!!
...全文
2134 16 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
xliu32 2008-02-16
  • 打赏
  • 举报
回复
这几天没来看,没想到有这么多回复,非常感谢大家的帮助!
我会试试sourceid讲的方法,Thanks so much!
libo500k 2008-02-14
  • 打赏
  • 举报
回复
靠, GDB版本太老了吧, 我碰到过这个问题,
你现在pthread_create前一语句做break; 然后step就跟进去了
sourceid 2008-01-29
  • 打赏
  • 举报
回复
大致过程这样.

// pthread_c_test.c

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>

void *prt_str(void *);

int
main(int argc, char *argv[])
{
pthread_t tid;

if (pthread_create(&tid, NULL, prt_str, NULL) != 0) {
perror("pthread_create error");
exit(1);
}

(void)pthread_join(tid, NULL);

return 0;
}

void *
prt_str(void *arg)
{
printf("Hello, world!\n");
}

# gcc -Wall -gstabs -static pthread_c_test.c -o pthread_c_test -lpthread

# gdb -q pthread_c_test
Using host libthread_db library "/lib/libthread_db.so.1".
(gdb) b *main
Breakpoint 1 at 0x8048208: file pthread_c_test.c, line 10.
(gdb) list
4 #include <pthread.h>
5
6 void *prt_str(void *);
7
8 int
9 main(int argc, char *argv[])
10 {
11 pthread_t tid;
12
13 if (pthread_create(&tid, NULL, prt_str, NULL) != 0) {
(gdb) b 13
Breakpoint 2 at 0x8048224: file pthread_c_test.c, line 13.
(gdb) r
Starting program: /root/asm/pthread_c_test
Reading symbols from shared object read from target memory...done.
[Thread debugging using libthread_db enabled]
Cannot find new threads: generic error
Cannot find user-level thread for LWP 4160: generic error
(gdb) c
Continuing.
[New Thread 157575216 (LWP 4160)]
[Switching to Thread 157575216 (LWP 4160)]

Breakpoint 1, main (argc=1, argv=0xbfa796f4) at pthread_c_test.c:10
10 {
(gdb) c
Continuing.

Breakpoint 2, main (argc=1, argv=0xbfa796f4) at pthread_c_test.c:13
13 if (pthread_create(&tid, NULL, prt_str, NULL) != 0) {
(gdb) disas pthread_create
Dump of assembler code for function pthread_create:
0x08048a28 <pthread_create+0>: push %ebp
0x08048a29 <pthread_create+1>: mov %esp,%ebp
0x08048a2b <pthread_create+3>: push %edi
0x08048a2c <pthread_create+4>: push %esi
0x08048a2d <pthread_create+5>: push %ebx
0x08048a2e <pthread_create+6>: sub $0x1c,%esp
0x08048a31 <pthread_create+9>: mov 0xc(%ebp),%eax
0x08048a34 <pthread_create+12>: mov %eax,0xffffffdc(%ebp)
0x08048a37 <pthread_create+15>: test %eax,%eax
0x08048a39 <pthread_create+17>: je 0x8048e0c <pthread_create+996>
0x08048a3f <pthread_create+23>: call 0x805b18c <getpagesize>
0x08048a44 <pthread_create+28>: lea 0xffffffff(%eax),%ebx
0x08048a47 <pthread_create+31>: mov 0xffffffdc(%ebp),%edx
0x08048a4a <pthread_create+34>: mov 0x14(%edx),%ecx
0x08048a4d <pthread_create+37>: test %ecx,%ecx
0x08048a4f <pthread_create+39>: je 0x8048d0d <pthread_create+741>
0x08048a55 <pthread_create+45>: mov %ecx,%edi
0x08048a57 <pthread_create+47>: mov 0xffffffdc(%ebp),%eax
0x08048a5a <pthread_create+50>: mov 0x8(%eax),%edx
0x08048a5d <pthread_create+53>: and $0x8,%edx
0x08048a60 <pthread_create+56>: jne 0x8048eff <pthread_create+1239>
0x08048a66 <pthread_create+62>: mov 0x80ba5d8,%eax
---Type <return> to continue, or q <return> to quit---q
Quit
(gdb) b *pthread_create+3
Breakpoint 3 at 0x8048a2b
(gdb) c
Continuing.

Breakpoint 3, 0x08048a2b in pthread_create ()
(gdb) s
Single stepping until exit from function pthread_create,
which has no line number information.
[New Thread -1208509520 (LWP 4171)]
0x0804953a in _L_mutex_unlock_2584 ()
(gdb) s
Single stepping until exit from function _L_mutex_unlock_2584,
which has no line number information.
Hello, world!
0x080490cf in pthread_create ()
(gdb) s
Single stepping until exit from function pthread_create,
which has no line number information.
main (argc=134982628, argv=0x0) at pthread_c_test.c:18
18 (void)pthread_join(tid, NULL);
(gdb) s
0x0804959c in pthread_join ()
(gdb)
Single stepping until exit from function pthread_join,
which has no line number information.
[Thread -1208509520 (LWP 4171) exited]
main (argc=134982628, argv=0x0) at pthread_c_test.c:20
20 return 0;
(gdb) s
21 }
(gdb)

xliu32 2008-01-24
  • 打赏
  • 举报
回复
Focus, Thank you very much for your help.
我可能会用log的方式先调试试试看吧。
你讲的方法没有完全懂。我比较弱:)
如果Log调试的方法不成,再Try你讲的方法。那时再多讨教细节。
非常感谢!!!
xliu32 2008-01-23
  • 打赏
  • 举报
回复
Hi, Focus, 多谢你啊! 我觉得你说得非常有道理。
你能告诉我我该怎么办吗??怎么解决这个问题呢??你也建议print log来Debug吗?

我把pthread_create 调用的函数附在这,可能对理解问题有帮助:

void *ThreadHandler::ThreadWorker( void *framework )
// ************************************************
// This function is the worker thread. 'framework' is alloc'd outside this
// function, but deleted by the thread cleanup handler.
{
Framework * fw = (Framework *) framework;
sigset_t signalset;

// Setup the cleanup routine. Also, very important, we block MOST
// signals for this thread (so that only the parent process gets the
// signal). The only signal that we don't block is the signal that the
// Gui thread uses to communicate with the worker thread.
pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, NULL );
pthread_cleanup_push( &ThreadHandler::ThreadWorkerCleanup, (void *) fw );
sigfillset( &signalset );
sigdelset( &signalset, SIGUSR2 ); // Don't block on SIGUSR2
pthread_sigmask( SIG_BLOCK, &signalset, NULL );
pthread_setcanceltype( PTHREAD_CANCEL_DEFERRED, NULL );
pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, NULL );

fw->Go(); // Get the framework running.

pthread_cleanup_pop(1);
return NULL;
}

多谢大侠指点啊!!!希望继续多给建议!!!
xliu32 2008-01-22
  • 打赏
  • 举报
回复
多谢vbzxcvb的回复。我在pthread_create调用的函数入口处和调用的函数内部都加了断点,奇怪的就是那些设的断点没有停住,而是执行了整个程序。

您的建议是我用print的方式来跟踪是吗?我想可能只能用这种方法了。多谢!!

另外哪位大侠知道多线程程序有什么好的调试工具吗???又过了一天了,还是没什么进展。
vbzxcvb 2008-01-22
  • 打赏
  • 举报
回复
很奇怪,你在pthread_create调用的函数(也就是新线程的起始函数)加断点不就行了么?还有就是gdb调试多线程程序会很累,而且效率也不怎么高。多线程程序还是print_log最有效。
xliu32 2008-01-21
  • 打赏
  • 举报
回复
多谢boer的回复。问题是我还没有进入子线程,程序就开始不停的Run到结束了(我想step into thread_creates时,程序就开始不停的执行了,我用的这个程序有很多的输出,所以很明显)。
我之前试过 break thread, 好像根本不认这个命令。。
我的程序看来是好像根本没有进入多线程调试。

怎么办啊?大侠和好心人多多建议啊!!!
xliu32 2008-01-21
  • 打赏
  • 举报
回复
我刚才又在gdb下运行了一次程序(就是象上面一样step就接着开始Run,停不下来),结束时候我又step,
显示了这个:
(gdb) s
Single stepping until exit from function pthread_handle_sigrestart,
which has no line number information.
0x081d5807 in __pthread_sigsuspend ()

谁知道这是什么意思吗???
对理解上面那个问题有帮助吗??

多谢大家的建议!!!
boer001217 2008-01-21
  • 打赏
  • 举报
回复
你找到对应版本的GDB看下,应该就可以发现调试的方法
break thread
break thread if ...
linespec指定了断点设置在的源程序的行号。threadno指定了线程的ID,注意,这个ID是GDB分配的,你可以通过“info threads”命令来查看正在运行程序中的线程信息。如果你不指定thread 则表示你的断点设在所有线程上面。你还可以为某
线程指定断点条件。如:
(gdb) break frik.c:13 thread 28 if bartab > lim
当你的程序被GDB停住时,所有的运行线程都会被停住。这方便你你查看运行程序的总体情况。而在你恢复程序运行
时,所有的线程也会被恢复运行。那怕是主进程在被单步调试时。
xliu32 2008-01-21
  • 打赏
  • 举报
回复
那我该怎么解决这个问题呢? 我怎么修改呢?
没办法,必须解决啊,否则我的工作进行不下去了。唉。。。
多谢多谢!!!
xliu32 2008-01-21
  • 打赏
  • 举报
回复
谢谢你回复!!
程序没有问题,结果是正确的,因为我是要在别人的代码上改,那个代码已经被很多人用过了。但我对pthread 一点都不熟。
我不设任何断点,直接Run的话,结果是对的。

23,217

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧