title: 应用调试(二)GDB
date: 2019/1/17 21:00:10
toc: true
应用调试(二)GDB
gdb下载工具安装交叉工具链设置GDB介绍编译GDBtarget/host/build编译主机GDB编译单板GDBserver调试程序CoreDumpGDB命令杂项附录源码
gdb下载
这里我下载了gdb-7.6.tar.gz
编译成功,下载了8.x的需要c++11,后来没有试了
里面的".sig"为文件名的分离签名文件,用来校验下载资源的完整性,.xz
为另外格式的压缩包
工具安装
# 高版本的gdb需要这个东西sudo apt-get install texinfo
交叉工具链设置
--program-prefix=arm-linux-
是指生成的可执行文件的前缀,比如arm-linux-gdb- -prefix是指生成的可执行文件安装在哪个目录
- 可以指定工具连
make CC=arm-none-linux-gnueabi-gcc
https://blog.csdn.net/hanq4998/article/details/84675718
GDB介绍
GDB调试分为两个部分
- 单板运行
gdbserver
,作为主进程,他来创建所调试程序为子进程,使用系统调用ptrace
跟踪 - 主机运行
arm-linux-gdb
,调试远程的单板程序
mark
编译GDB
target/host/build
这里的这些其实就是编译工具的指定
- build
- host 编译出来的程序在哪里运行,其实就是编译工具
- target 这个选项一般为编译器所拥有,一般的程序不需要,意思是编译出来的编译器它编译的东西在哪里运行
mark
编译主机GDB
具体流程如下
tar xzf gdb-7.6.tar.gzcd gdb-7.6/# 忽略这种函数命名不规范导致的错误./configure --target=arm-linux --disable-werrormakemkdir tmp make install prefix=$PWD/tmpsudo cp tmp/bin/arm-linux-gdb /usr/bin# arm-linux-gdb -vGNU gdb (GDB) 7.6
一些注意点
- 编译出的运行在
ubuntu
下的GDB
需要调试arm
下的程序,这里需要指定target=arm-linux
--disable-werror
是百度到的,不然接下去make
失败- 使用
arm-linux-gcc version 3.4.5
编译 - 先安装到当前目录的
tmp
下,可以通过生成的Makefie
看到默认的路径是usr/local
build_alias=x86_64-unknown-linux-gnubuild_vendor=unknownbuild_os=linux-gnubuild=x86_64-unknown-linux-gnuhost_alias=x86_64-unknown-linux-gnuhost_vendor=unknownhost_os=linux-gnuhost=x86_64-unknown-linux-gnutarget_alias=arm-linuxtarget_vendor=unknowntarget_os=linux-gnutarget=arm-unknown-linux-gnu
编译单板GDBserver
命令如下
cd gdb/gdbserver/./configure --host=arm-linuxmake# 这里需要修改 vi linux-arm-low.cmake
#因为这gdbserver是要放在开发板上的,就不用make install了
#查看下生成的文件[email protected]:~/stu/gdb/gdb-7.6/gdb/gdbserver$ file gdbservergdbserver: ELF 32-bit LSB executable, ARM, version 1, dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.4.3, not stripped# 复制到单板cp gdbserver ~/stu/code
gdbserver
调试的程序是运行在arm
下的,也就是指定host
,这里应该不需要指定host
,我测试了一下,生成的执行文件crc一致- 修该代码,这里make会有如下错误提示找不到宏定义,我们需要去交叉编译工具链的目录去搜索
linux-arm-low.c: In function
arm_stopped_by_watchpoint‘:linux-arm-low.c:643: error:
PTRACE_GETSIGINFO‘ undeclared (first use in this function) # 查看环境变量echo不能识别此Latex公式:PATH/home/book/bin:/home/book/.local/bin:/opt/slickedit-pro2017/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/opt/gcc-3.4.5-glibc-2.3.6/bin:/snap/bincd /opt/gcc-3.4.5-glibc-2.3.6/ #搜索宏 PTRACE_GETSIGINFO[email protected]:/opt/gcc-3.4.5-glibc-2.3.6
grep "PTRACE_GETSIGINFO" * -nRarm-linux/include/linux/ptrace.h:27:#define PTRACE_GETSIGINFO 0x4202arm-linux/sys-include/linux/ptrace.h:27:#define PTRACE_GETSIGINFO 0x4202distributed/arm-linux/include/linux/ptrace.h:27:#define PTRACE_GETSIGINFO 0x4202distributed/arm-linux/sys-include/linux/ptrace.h:27:#define PTRACE_GETSIGINFO 0x4202 # 修改代码 加入 #include<linux/ptrace.h>vi linux-arm-low.c
调试程序
- 编译程序,加入
-g
选项,形如arm-linux-gcc -g -o test test.c
- 单板开启
gdbserver
,命令形如gdbserver 192.168.95.2345 ./test
,这IP是单板的IP,端口随意 - 主机远程连接到单板
arm-linux-gdb ./test target remote 192.168.95.222:2345
- 接下去就可以调试了,注意这里打断点到哪一行,该行并未执行,这和我们ide是一样的,并且使用
step
等命令显示的下一句c
代码,实际上也是没有执行的mark
-
我们这个程序故意引入空指针,所以最后会有错误提示
Program received signal SIGSEGV, Segmentation fault.0x000084ac in C (p=0x0) at test.c:66 *p = 0x12;
CoreDump
这个类似一个日志文件,首先需要在单板上开启这个功能
ulimit -c unlimited# ./testa = 0x12Segmentation fault (core dumped)
# 复制这个 core 文件去主机# 我们这里本身就在主机nfs上
直接使用这个文件在主机上运行,这里可能需要加权限,直接chmod 777 core
[email protected]:~/stu/code$ sudo chmod 777 core[email protected]:~/stu/code$ arm-linux-gdb ./test coreGNU gdb (GDB) 7.6Copyright (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 "--host=x86_64-unknown-linux-gnu --target=arm-linux".For bug reporting instructions, please see:<http://www.gnu.org/software/gdb/bugs/>...Reading symbols from /home/book/stu/code/test...done.[New LWP 812]
warning: `/lib/ld-linux.so.2‘: Shared library architecture unknown is not compatible with target architecture arm.
warning: Could not load shared library symbols for /lib/libc.so.6.Do you need "set solib-search-path" or "set sysroot"?Core was generated by `./test‘.Program terminated with signal 11, Segmentation fault.#0 0x000084ac in C (p=0x0) at test.c:66 *p = 0x12;
可以看到出错的地方
直接使用命令bt
查看调用树
(gdb) bt#0 0x000084ac in C (p=0x0) at test.c:6#1 0x000084d0 in B (p=0x0) at test.c:12#2 0x000084f0 in A (p=0x0) at test.c:17#3 0x0000856c in main (argc=1, argv=0xbedb6ed4) at test.c:38
GDB命令
http://www.cnblogs.com/veryStrong/p/6240775.html
http://blog.sciencenet.cn/blog-619295-813770.html
名称 | 命令 | 描述 |
---|---|---|
断点 | break main | |
break test.c:20 | 在test.c的20行 中间不能有空格 | |
继续 | c | continue |
单步进入 | step | 进入函数 |
单步跳过 | next | 不会进入函数 |
打印变量 | print a | 打印a变量 |
杂项
FAQ
这里我试了在编译gdb的时候,最后安装的时候出现gdb.info
出错,但实际上arm-linux-gdb
已经生成了,好像是可以用的了
一些命令
#查看文件属性file gdbserver
#链接文件sudo mv ./gdb ./gdb.oldcd /usr/local/gdb8/binsudo ln -s $(pwd)/gdb /usr/bin/gdb
附录源码
#include <stdio.h>
void C(int *p){ *p = 0x12;}
void B(int *p){ C(p);}
void A(int *p){ B(p);}
void A2(int *p){ C(p);}
int main(int argc, char **argv){ int a; int *p = NULL;
A2(&a); // A2 > C printf("a = 0x%x\n", a);
printf("step1"); printf("step2"); printf("step3");
A(p); // A > B > C
return 0;}
原文地址:https://www.cnblogs.com/zongzi10010/p/10291525.html
时间: 2024-11-11 18:55:26