一. GDB与多线程
在多线程编程时,当我们需要调试时,有时需要控制某些线程停在断点,有些线程继续执行。有时需要控制线程的运行顺序。有时需要中断某个线程,切换到其他线程。这些都可以通过gdb实现。GDB默认支持调试多线程,跟主线程,子线程block在create+thread。
先来看一下gdb调试多线程常用命令:
info+threads:显示可以调试的所有线程。gdb会为每个线程分配一个ID(和tid不同),编号一般从1开始。后面的ID是指这个ID。
thread+ID:切换当前调试的线程为指定ID的线程。
(gdb) help set scheduler-locking
Set mode for locking scheduler during execution.
off == no locking (threads may preempt at any time)
on == full locking (no thread except the current thread may run)
step == scheduler locked during every single-step operation.
In this mode, no other thread may run during a step command.
Other threads may run while stepping over a function call ('next')
#include<stdio.h>
#include<pthread.h>
void *thread_run1(void *argv)
{
printf("I am thread_run1, thread_run1:%u\n", pthread_self());
return NULL;
}
void *thread_run2(void *argv)
{
printf("I am thread_run2, thread_run2:%u\n", pthread_self());
return NULL;
}
int main(int argc, char *argv[])
{
pthread_t pid1, pid2;
pthread_create(&pid1, NULL, thread_run1, NULL);
pthread_create(&pid2, NULL, thread_run2, NULL);
pthread_join(pid1, NULL);
pthread_join(pid2, NULL);
return 0;
}
cfc:/app/tmp>gdb somethread
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-90.el6)
Copyright (C) 2010 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-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /app/tmp/somethread...done.
(gdb) break thread_run1
Breakpoint 1 at 0x400620: file somethread.c, line 6.
(gdb) break thread_run2
Breakpoint 2 at 0x400650: file somethread.c, line 12.
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x0000000000400620 in thread_run1 at somethread.c:6
2 breakpoint keep y 0x0000000000400650 in thread_run2 at somethread.c:12
(gdb) run
Starting program: /app/tmp/somethread
[Thread debugging using libthread_db enabled]
[New Thread 0x7ffff7fe5700 (LWP 17196)]
[Switching to Thread 0x7ffff7fe5700 (LWP 17196)]
Breakpoint 1, thread_run1 (argv=0x0) at somethread.c:6
6 printf("I am thread_run1, thread_run1:%u\n", pthread_self());
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.192.el6.x86_64
(gdb) info threads
[New Thread 0x7ffff75e4700 (LWP 17197)]
3 Thread 0x7ffff75e4700 (LWP 17197) 0x0000003d8a2e8a71 in clone () from /lib64/libc.so.6
* 2 Thread 0x7ffff7fe5700 (LWP 17196) thread_run1 (argv=0x0) at somethread.c:6
1 Thread 0x7ffff7fe7700 (LWP 17193) 0x0000003d8a2e8a71 in clone () from /lib64/libc.so.6
(gdb) c
Continuing.
I am thread_run1, thread_run1:4160640768
[Thread 0x7ffff7fe5700 (LWP 17196) exited]
[Switching to Thread 0x7ffff75e4700 (LWP 17197)]
Breakpoint 2, thread_run2 (argv=0x0) at somethread.c:12
12 printf("I am thread_run2, thread_run2:%u\n", pthread_self());
(gdb) info threads
* 3 Thread 0x7ffff75e4700 (LWP 17197) thread_run2 (argv=0x0) at somethread.c:12
1 Thread 0x7ffff7fe7700 (LWP 17193) 0x0000003d8a6082fd in pthread_join () from /lib64/libpthread.so.0
(gdb) n
I am thread_run2, thread_run2:4150150912
13 return NULL;
(gdb) n
14 }
(gdb) n
0x0000003d8a607aa1 in start_thread () from /lib64/libpthread.so.0
(gdb) info threads
* 3 Thread 0x7ffff75e4700 (LWP 17197) 0x0000003d8a607aa1 in start_thread () from /lib64/libpthread.so.0
1 Thread 0x7ffff7fe7700 (LWP 17193) 0x0000003d8a6082fd in pthread_join () from /lib64/libpthread.so.0
(gdb) n
Single stepping until exit from function start_thread,
which has no line number information.
[Thread 0x7ffff75e4700 (LWP 17197) exited]
Program received signal SIGSTOP, Stopped (signal).
[Switching to Thread 0x7ffff7fe7700 (LWP 17193)]
0x0000003d8a6082fd in pthread_join () from /lib64/libpthread.so.0
(gdb) n
Single stepping until exit from function pthread_join,
which has no line number information.
main (argc=1, argv=0x7fffffffdd88) at somethread.c:24
24 return 0;
(gdb) n
25 }
(gdb) n
0x0000003d8a21ed1d in __libc_start_main () from /lib64/libc.so.6
(gdb) n
Single stepping until exit from function __libc_start_main,
which has no line number information.
Program exited normally.
(gdb) info threads
(gdb) run
Starting program: /app/tmp/somethread
[Thread debugging using libthread_db enabled]
[New Thread 0x7ffff7fe5700 (LWP 17199)]
[Switching to Thread 0x7ffff7fe5700 (LWP 17199)]
Breakpoint 1, thread_run1 (argv=0x0) at somethread.c:6
6 printf("I am thread_run1, thread_run1:%u\n", pthread_self());
(gdb) info threads
[New Thread 0x7ffff75e4700 (LWP 17200)]
3 Thread 0x7ffff75e4700 (LWP 17200) 0x0000003d8a2e8a71 in clone () from /lib64/libc.so.6
* 2 Thread 0x7ffff7fe5700 (LWP 17199) thread_run1 (argv=0x0) at somethread.c:6
1 Thread 0x7ffff7fe7700 (LWP 17198) 0x0000003d8a2e8a71 in clone () from /lib64/libc.so.6
(gdb) n
[Switching to Thread 0x7ffff75e4700 (LWP 17200)]
Breakpoint 2, thread_run2 (argv=0x0) at somethread.c:12
12 printf("I am thread_run2, thread_run2:%u\n", pthread_self());
(gdb) info threads
* 3 Thread 0x7ffff75e4700 (LWP 17200) thread_run2 (argv=0x0) at somethread.c:12
2 Thread 0x7ffff7fe5700 (LWP 17199) 0x00000000004004d8 in printf@plt ()
1 Thread 0x7ffff7fe7700 (LWP 17198) 0x0000003d8a6082fd in pthread_join () from /lib64/libpthread.so.0
(gdb) n
I am thread_run1, thread_run1:4160640768
I am thread_run2, thread_run2:4150150912
13 return NULL;
(gdb) info threads
* 3 Thread 0x7ffff75e4700 (LWP 17200) thread_run2 (argv=0x0) at somethread.c:13
2 Thread 0x7ffff7fe5700 (LWP 17199) 0x0000003d8a605e20 in __nptl_death_event () from /lib64/libpthread.so.0
1 Thread 0x7ffff7fe7700 (LWP 17198) 0x0000003d8a6082fd in pthread_join () from /lib64/libpthread.so.0
(gdb) n
14 }
(gdb) n
0x0000003d8a607aa1 in start_thread () from /lib64/libpthread.so.0
(gdb) info threads
* 3 Thread 0x7ffff75e4700 (LWP 17200) 0x0000003d8a607aa1 in start_thread () from /lib64/libpthread.so.0
2 Thread 0x7ffff7fe5700 (LWP 17199) 0x0000003d8a605e20 in __nptl_death_event () from /lib64/libpthread.so.0
1 Thread 0x7ffff7fe7700 (LWP 17198) 0x0000003d8a6082fd in pthread_join () from /lib64/libpthread.so.0
(gdb) kill
Kill the program being debugged? (y or n) y
(gdb) run
Starting program: /app/tmp/somethread
[Thread debugging using libthread_db enabled]
[New Thread 0x7ffff7fe5700 (LWP 17202)]
[Switching to Thread 0x7ffff7fe5700 (LWP 17202)]
Breakpoint 1, thread_run1 (argv=0x0) at somethread.c:6
6 printf("I am thread_run1, thread_run1:%u\n", pthread_self());
(gdb) info threads
[New Thread 0x7ffff75e4700 (LWP 17203)]
3 Thread 0x7ffff75e4700 (LWP 17203) 0x0000003d8a60e2fe in __lll_lock_wait_private () from /lib64/libpthread.so.0
* 2 Thread 0x7ffff7fe5700 (LWP 17202) thread_run1 (argv=0x0) at somethread.c:6
1 Thread 0x7ffff7fe7700 (LWP 17201) 0x0000003d8a2e8a71 in clone () from /lib64/libc.so.6
(gdb) s
I am thread_run1, thread_run1:4160640768
7 return NULL;
(gdb) info threads
3 Thread 0x7ffff75e4700 (LWP 17203) 0x0000003d8a60e48f in __lll_unlock_wake_private () from /lib64/libpthread.so.0
* 2 Thread 0x7ffff7fe5700 (LWP 17202) thread_run1 (argv=0x0) at somethread.c:7
1 Thread 0x7ffff7fe7700 (LWP 17201) 0x0000003d8a6082fd in pthread_join () from /lib64/libpthread.so.0
(gdb) n
8 }
(gdb) info threads
3 Thread 0x7ffff75e4700 (LWP 17203) 0x0000003d8a60e48f in __lll_unlock_wake_private () from /lib64/libpthread.so.0
* 2 Thread 0x7ffff7fe5700 (LWP 17202) thread_run1 (argv=0x0) at somethread.c:8
1 Thread 0x7ffff7fe7700 (LWP 17201) 0x0000003d8a6082fd in pthread_join () from /lib64/libpthread.so.0
(gdb) c
Continuing.
[Switching to Thread 0x7ffff75e4700 (LWP 17203)]
Breakpoint 2, thread_run2 (argv=0x0) at somethread.c:12
12 printf("I am thread_run2, thread_run2:%u\n", pthread_self());
(gdb) info threads
* 3 Thread 0x7ffff75e4700 (LWP 17203) thread_run2 (argv=0x0) at somethread.c:12
2 Thread 0x7ffff7fe5700 (LWP 17202) thread_run1 (argv=0x0) at somethread.c:8
1 Thread 0x7ffff7fe7700 (LWP 17201) 0x0000003d8a6082fd in pthread_join () from /lib64/libpthread.so.0
(gdb) s
I am thread_run2, thread_run2:4150150912
13 return NULL;
(gdb) s
14 }
(gdb) n
0x0000003d8a607aa1 in start_thread () from /lib64/libpthread.so.0
(gdb) n
Single stepping until exit from function start_thread,
which has no line number information.
[Thread 0x7ffff75e4700 (LWP 17203) exited]
Program received signal SIGSTOP, Stopped (signal).
[Switching to Thread 0x7ffff7fe7700 (LWP 17201)]
0x0000003d8a6082fd in pthread_join () from /lib64/libpthread.so.0
(gdb) n
Single stepping until exit from function pthread_join,
which has no line number information.
n
n
n
^C
Program received signal SIGINT, Interrupt.
0x0000003d8a6082fd in pthread_join () from /lib64/libpthread.so.0
(gdb) info threads
2 Thread 0x7ffff7fe5700 (LWP 17202) 0x0000003d8a605e20 in __nptl_death_event () from /lib64/libpthread.so.0
* 1 Thread 0x7ffff7fe7700 (LWP 17201) 0x0000003d8a6082fd in pthread_join () from /lib64/libpthread.so.0
(gdb)
二、设置core
core的意思是核心,dumped的意思就是抛出,转储,core dumped就是核心转储的意思。当一个进程异常退出前,该进程会抛出当时该程序进程的内存详细情况存储在硬盘上,文件名通常是core,这就叫core dump。
进程异常终止通常是因为代码存在BUG,比如非法内存访问导致段错误,事后可以用调试器检查core文件以查清错误原因,这叫做事后调试.
uname -a 查看机器参数
ulimit -a 查看默认参数
ulimit -c 1024 设置core文件大小为1024
ulimit -c unlimit 设置core文件大小为无限
eg1(可以快速定位出问题的位置)
gdb a.out core.xxx
where
eg2 (在 gdb 中使用)
(gdb) core-file core.xxx