# 编译调试版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 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: ... 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) ```