232 lines
5.3 KiB
Markdown
232 lines
5.3 KiB
Markdown
# 编译调试版glibc以及gdb调试的简单用法 #
|
||
|
||
## 一、概述 ##
|
||
|
||
1、编译调试版glibc
|
||
|
||
2、如何使用gdb调试代码
|
||
|
||
## 二、编译glibc ##
|
||
|
||
1、下载源码:
|
||
|
||
```
|
||
git clone git@gitlab.rd.in.linx:linx6.0.42/applications.git
|
||
|
||
cd application/packages/g/glibc
|
||
```
|
||
|
||
2、在glibc configure编译时添加--enable-debug选项
|
||
|
||
```
|
||
vi Pkgfile
|
||
|
||
#修改版本与glibc区分
|
||
|
||
LINX_VERSION=linx-debugns
|
||
|
||
#在configure中添加如下内容:
|
||
|
||
--enable-debug=yes CFLAGS="-O1 -g" CPPFLAGS="-O1 -g"
|
||
```
|
||
|
||
3、编译
|
||
|
||
需要特别注意:需添加-ns参数,no strip(保留调试信息)
|
||
|
||
```
|
||
pkgmk -kw -s -pa post_add.sh -pm post_mk.sh -ns
|
||
```
|
||
|
||
4、安装
|
||
|
||
```
|
||
pkgadd glibc#2.5-x86_64-linx-debugns-Rocky4.2.pkg.tar.gz -u
|
||
```
|
||
|
||
## 三、使用gdb调试 ##
|
||
|
||
### 1、首先编译一个二进制文件 ###
|
||
|
||
g++ -lpthread pthread_test.cpp -g -o pthread_test
|
||
|
||
参数说明:
|
||
|
||
```
|
||
-lpthread: 编译时添加链接库
|
||
|
||
pthread_test.cpp : 需要编译的C++程序
|
||
|
||
-g: 开启debug调试选项
|
||
|
||
-o: 制定目标名称,缺省时编译出的文件是a.out
|
||
|
||
pthread_test : 编译后的二进制文件名
|
||
```
|
||
|
||
检测二进制文件是否支持debug调试
|
||
|
||
```
|
||
readelf -S ./pthread_test |grep debug
|
||
```
|
||
|
||
如需要关闭二进制文件中的debug,如下命令:
|
||
|
||
```
|
||
strip -S pthread_test
|
||
```
|
||
|
||
### 2、gdb简单调试示例 ###
|
||
|
||
在使用gdb调试时,需要glibc/work/src源码目录,否则调试时会报错,找不到文件。
|
||
|
||
```
|
||
localhost:~ # gdb -q pthread_jjli
|
||
Reading symbols from /root/pthread_jjli...done.
|
||
(gdb) b main #在main()函数设置断点
|
||
Breakpoint 1 at 0x4007e4: file pthread_jjli.cpp, line 21.
|
||
(gdb) r #运行程序
|
||
Starting program: /root/pthread_jjli
|
||
|
||
Breakpoint 1, main () at pthread_jjli.cpp:21
|
||
21 float useTime = 0;
|
||
(gdb) s #执行下一条代码
|
||
22 unsigned int loop = 0;
|
||
(gdb)
|
||
24 printf("Thread creation use hello\n");
|
||
(gdb)
|
||
Thread creation use hello
|
||
27 loop ++;
|
||
(gdb)
|
||
28 gettimeofday(&tv_begin, NULL);
|
||
(gdb)
|
||
29 res = pthread_create(&a_thread, NULL, thread_function, NULL);
|
||
(gdb)
|
||
30 gettimeofday(&tv_end, NULL);
|
||
(gdb)
|
||
31 for (int i=0;i<100;i++){
|
||
(gdb)
|
||
32 *(p+i) = 1;
|
||
(gdb)
|
||
|
||
Program received signal SIGSEGV, Segmentation fault.
|
||
0x000000000040084a in main () at pthread_jjli.cpp:32
|
||
32 *(p+i) = 1;
|
||
(gdb) where #显示代码出错位置
|
||
#0 0x000000000040084a in main () at pthread_jjli.cpp:32
|
||
(gdb) bt #跟踪错误
|
||
#0 0x000000000040084a in main () at pthread_jjli.cpp:32
|
||
(gdb) l #显示代码
|
||
27 loop ++;
|
||
28 gettimeofday(&tv_begin, NULL);
|
||
29 res = pthread_create(&a_thread, NULL, thread_function, NULL);
|
||
30 gettimeofday(&tv_end, NULL);
|
||
31 for (int i=0;i<100;i++){
|
||
32 *(p+i) = 1;
|
||
33 }
|
||
34
|
||
35 if (res != 0)
|
||
36 {
|
||
(gdb)
|
||
```
|
||
|
||
### 3、gdb使用 ###
|
||
|
||
(1)简介:
|
||
|
||
GDB是一个由GNU开源组织发布的、UNIX/LINUX操作系统下的、基于命令行的、功能强大的程序调试工具。
|
||
|
||
需要特别注意的是,在使用gdb调试时,必须保证其源码在当前目录,例如在调试glibc时,需要glibc/work/src源码目录,否则调试时会报错。
|
||
|
||
(2)gdb命令说明:
|
||
|
||
```
|
||
常用命令:
|
||
r: 程序开始运行
|
||
b: 设置断点
|
||
c: 程序继续运行
|
||
q: 退出程序
|
||
d: 删除断点
|
||
s: 执行下一条代码,如果函数进入函数
|
||
n: 一条一条执行
|
||
where: 显示代码出错位置
|
||
bt: 跟踪错误
|
||
l: 默认显示10行代码
|
||
p: 打印变量的值
|
||
回车: 执行上一条gdb命令
|
||
|
||
扩展命令:
|
||
|
||
delete break: 删除所有断点
|
||
delete break n: 删除某个断点,n为断点号
|
||
clear n: 删除设置在n行的断点
|
||
disable break n: 禁用某个断点,n为断点号
|
||
enable break n: 使能莫个断点,n为断点号
|
||
info b: 查看所有断点信息
|
||
info b n: 查看第n个断点的信息
|
||
list: 默认显示10行代码
|
||
finish: 运行到当前函数返回
|
||
l_行号或函数名: 列出源码
|
||
```
|
||
|
||
(3)运行gdb的几种方式:
|
||
|
||
gdb pthread_test: 进入gdb模式并加载文件
|
||
|
||
```
|
||
localhost:~ # gdb pthread_test
|
||
GNU gdb (GDB) 7.6.2
|
||
Copyright (C) 2013 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-unknown-linux-gnu".
|
||
For bug reporting instructions, please see:
|
||
<http://www.gnu.org/software/gdb/bugs/>...
|
||
Reading symbols from /root/pthread_test...done.
|
||
(gdb)
|
||
```
|
||
|
||
dgb -q pthread_test: 不输出gdb的版本信息说明
|
||
|
||
```
|
||
localhost:~ # gdb -q pthread_test
|
||
Reading symbols from /root/pthread_test...done.
|
||
(gdb)
|
||
```
|
||
|
||
gdb -q :进入gdb模式,然后再加载文件
|
||
|
||
```
|
||
localhost:~ # gdb -q
|
||
(gdb) file pthread_test
|
||
Reading symbols from /root/pthread_test...done.
|
||
(gdb)
|
||
```
|
||
|
||
(4)如果关闭debug调试,如下所示:
|
||
|
||
```
|
||
localhost:~ # gdb -q
|
||
(gdb) file pthread_jjli
|
||
Reading symbols from /root/pthread_jjli...(no debugging symbols found)...done.
|
||
(gdb) b main
|
||
Breakpoint 1 at 0x4007e0
|
||
(gdb) r
|
||
Starting program: /root/pthread_jjli
|
||
(no debugging symbols found)
|
||
(no debugging symbols found)
|
||
(no debugging symbols found)
|
||
(no debugging symbols found)
|
||
(no debugging symbols found)
|
||
(no debugging symbols found)
|
||
(no debugging symbols found)
|
||
|
||
Breakpoint 1, 0x00000000004007e0 in main ()
|
||
(gdb)
|
||
```
|
||
|
||
|
||
|