# gdb工程实践

# 目录

[toc]

# [面试问]gdb如何调试多线程?

  • 安装pstack,使用pstack pid
  • pstree好像默认又
//查看当前运行的进程
ps aux|grep a.out
//查看当前运行的轻量级进程
ps -aL|grep a.out
//查看主线程和新线程的关系
pstree -p 主线程id
1
2
3
4
5
6

# 1.使用gdb调试段错误(segment fault)纯gdb

  • 第一步是使用带有调试标志(debugging flags)的方式编译这段代码

  • demo.c

#include <stdio.h>
#include <stdlib.h>
 
int main(int argc, char **argv)
{
   char *buf;
 
   buf = malloc(1<<31);
 
   fgets(buf, 1024, stdin);
   printf("%s\n", buf);
 
   return 1;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
huwei@dell:~/auto$ vim demo.c
huwei@dell:~/auto$ ls
demo.c  enviroment.sh  myauto.sh  source-flang15.sh  source-kmpl-llvm-14.sh
huwei@dell:~/auto$ gcc -g demo.c -o demo
demo.c: In function ‘main’:
demo.c:8:10: warning: argument 1 value ‘18446744071562067968’ exceeds maximum object size 9223372036854775807 [-Walloc-size-larger-than=]
    8 |    buf = malloc(1<<31);
      |          ^~~~~~~~~~~~~
In file included from demo.c:2:
/usr/include/stdlib.h:539:14: note: in a call to allocation function ‘malloc’ declared here
  539 | extern void *malloc (size_t __size) __THROW __attribute_malloc__
      |              ^~~~~~
huwei@dell:~/auto$ ls
demo  demo.c  enviroment.sh  myauto.sh  source-flang15.sh  source-kmpl-llvm-14.sh
huwei@dell:~/auto$ ./demo
asdf
Segmentation fault (core dumped)
huwei@dell:~/auto$ ls
demo  demo.c  enviroment.sh  myauto.sh  source-flang15.sh  source-kmpl-llvm-14.sh
huwei@dell:~/auto$ gdb demo
Reading symbols from demo...
(gdb) l
1	#include <stdio.h>
2	#include <stdlib.h>
3
4	int main(int argc, char **argv)
5	{
6	   char *buf;
7
8	   buf = malloc(1<<31);
9
10	   fgets(buf, 1024, stdin);
(gdb) r
Starting program: /home/huwei/auto/demo
w

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7e43881 in __GI__IO_getline_info (fp=fp@entry=0x7ffff7fac980 <_IO_2_1_stdin_>, buf=buf@entry=0x0, n=n@entry=1023,
    delim=delim@entry=10, extract_delim=extract_delim@entry=1, eof=eof@entry=0x0) at iogetline.c:77
77	iogetline.c: No such file or directory.
(gdb) bt
#0  0x00007ffff7e43881 in __GI__IO_getline_info (fp=fp@entry=0x7ffff7fac980 <_IO_2_1_stdin_>, buf=buf@entry=0x0,
    n=n@entry=1023, delim=delim@entry=10, extract_delim=extract_delim@entry=1, eof=eof@entry=0x0) at iogetline.c:77
#1  0x00007ffff7e4396c in __GI__IO_getline (fp=fp@entry=0x7ffff7fac980 <_IO_2_1_stdin_>, buf=buf@entry=0x0, n=n@entry=1023,
    delim=delim@entry=10, extract_delim=extract_delim@entry=1) at iogetline.c:34
#2  0x00007ffff7e426ca in _IO_fgets (buf=0x0, n=1024, fp=0x7ffff7fac980 <_IO_2_1_stdin_>) at iofgets.c:53
#3  0x00005555555551c4 in main (argc=1, argv=0x7fffffffc4b8) at demo.c:10
(gdb) l
72	in iogetline.c
(gdb) frame 3
#3  0x00005555555551c4 in main (argc=1, argv=0x7fffffffc4b8) at demo.c:10
10	   fgets(buf, 1024, stdin);
(gdb) l
5	{
6	   char *buf;
7
8	   buf = malloc(1<<31);
9
10	   fgets(buf, 1024, stdin);
11	   printf("%s\n", buf);
12
13	   return 1;
14	}
(gdb)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
  • 参考资料:https://blog.csdn.net/Deutschester/article/details/6739861

# 2.使用gdb调试段错误(segment fault)纯gdb+core文件

root@whoway:~/segfault$ gdb ./demo ./core 
1
  • 参考资料:https://blog.csdn.net/tuwenqi2013/article/details/88778045

# 3.gdb调试fopen和fprintf的程序

1033		fprintf(fp,"whoway:itok=%d\n", itok);
1: p = 0xaaaaab159360 <ctok> "real"
2: typ = 49
3: ctok = "real", '\000' <repeats 2043 times>
(gdb) n
1034		fclose(fp);
1: p = 0xaaaaab159360 <ctok> "real"
2: typ = 49
3: ctok = "real", '\000' <repeats 2043 times>
(gdb) !ls
demo-aed92b.ilm  demo-aed92b.stb  demo.f90  hands  whoway-debug.f
(gdb) !ls -l whoway-debug.f
-rw-r--r-- 1 root root 0 Jan 12 13:06 whoway-debug.f
(gdb) n
1036	    break;
1: p = 0xaaaaab159360 <ctok> "real"
2: typ = 49
3: ctok = "real", '\000' <repeats 2043 times>
(gdb) l
1031	//	LCASE(ctok); //避免REAL这样的大写
1032		fprintf(fp,"whoway:Last gtock ctok=%s\n", ctok);
1033		fprintf(fp,"whoway:itok=%d\n", itok);
1034		fclose(fp);
1035	    }
1036	    break;
1037	  case SW_BOUNDS:
1038	    if (no_specified) {
1039	      bclr(DIR_OFFSET(currdir, x[70]), 0x02);
1040	      flg.x[70] &= ~0x02; /* affect semant immediately */
(gdb) !ls
demo-aed92b.ilm  demo-aed92b.stb  demo.f90  hands  whoway-debug.f
(gdb) !ls -l whoway-debug.f
-rw-r--r-- 1 root root 82 Jan 12 13:07 whoway-debug.f
(gdb) !vim whoway-debug.f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

# 进一步的需求-能不能打印实时的fprint,但是好像不fclose看不到?

# 4.gdb调试带GUI的程序-需要你的Linux/Unix有GUI

前阵子,有个机顶盒程序,升级后,起不来。根据打印分析的话,是出现了段错误。开机的时候段错误,且那么多盒子,就出现那么一两个,概率太小。要是人工去跑gdb,那太费时费力了。于是就希望能够在启动的时候,自动去跑gdb。

虽然在启动脚本里面,使用了./gdb demo,但是这样的话,每次起来,还是需要手动输入run命令去运行。这个就达不到自动运行的结果。因为如果开机正常启动的话,还得让盒子重启,再去跑./gdb demo,不可能人工等在那里输入run命令。于是就想能够一条命令,解决在执行./gdb demo后,能够自动输入run命令,而且在出现段错误的时候,能自动输入bt,获取堆栈,这样才能拷机获取有用的信息。
————————————————
版权声明:本文为CSDN博主「rfasm」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/rfasm/article/details/41684683
1
2
3
4
5
6