<一>A really simple tracing debugger

在上一篇文章中讲到了ptrace,那么我们完全可以用ptrace来写一个非常简单的trace工具,用以trace程序的具体运行过程。

用它可以很清楚的回答,使用glibc编译后的hello world是从什么地方开始运行的。

(注:本文内容根据“A really simple tracing debugger"翻译而来,具体链接见参考资料一节)

itrace.c

#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>#include <sys/user.h>
#include <sys/ptrace.h>int main(int argc, char **argv)
{int pid = fork();if(pid == 0) {if(ptrace(PTRACE_TRACEME) < 0) {perror("ptrace");_exit(1);}execvp(argv[1], argv + 1);perror("exec");_exit(1);}while(1) {int status;struct user_regs_struct regs;if(waitpid(pid, &status, 0) < 0)perror("waitpid");if(!WIFSTOPPED(status))break;if(ptrace(PTRACE_GETREGS, pid, 0, &regs) < 0)perror("ptrace/GETREGS");printf("%lx %lx\n", regs.eip, regs.esp);if(ptrace(PTRACE_SINGLESTEP, pid, 0, 0) < 0)perror("ptrace/SINGLESTEP");}return 0;
}

编译:

gcc -m32 itrace.c -o itrace

译者注: -m32表示编译成32位格式,如果是在64位机器上,不需要加此选项,同时将itrace.c源码中的eip和esp转换为rip,rsp.

hellow.c

#include <stdio.h>
int main() { printf("Hello, world!\n");return 0;
}

编译:

gcc -static -o hellow hellow.c

译者注: itrace保持一致,itrace如果是按32位格式来编译的,此处也应该一样。

测试运行

./itrace ./hellow | addr2line -e ./hellow -f | grep -v "??\|:?" | uniq

说明如下:

addr2line 是将地址转换为相应的源码。运行的结果很长,所以就不打算没有贴出来了。

treeify

为了让运行结果在显示的时候能够更好的反映出调用关系,根据堆栈(%esp)中的信息采用python脚本将其层次化的打印出来。

import subprocess
import sysdef read():for line in sys.stdin:try:regs = [int(x, 16) for x in line.split(" ")]yield {"eip": regs[0], "esp": regs[1]}# Ignore lines interspersed with other output!except (ValueError, IndexError):passdef addr2line(iterable):proc = subprocess.Popen(["addr2line", "-e", sys.argv[1], "-f"],stdin=subprocess.PIPE, stdout=subprocess.PIPE)for regs in iterable:proc.stdin.write("%x\n" % regs["eip"])a = proc.stdout.readline().rstrip("\n")b = proc.stdout.readline().rstrip("\n")regs["func"] = "%s %s" % (a, b)yield regsdef entry_points(iterable):funcs = {}# We treat the first address we see for the function as its entry# point, and only report those entries from this point on.for regs in iterable:func = regs["func"].split(":")[0]if funcs.setdefault(func, regs["eip"]) == regs["eip"]:yield regsdef add_nesting(iterable):stack = [2 ** 64]for regs in iterable:stack_pos = regs["esp"]if stack_pos < stack[-1]:stack.append(stack_pos)while stack_pos > stack[-1]:stack.pop()regs["indent"] = "  " * len(stack)yield regsfor x in add_nesting(entry_points(addr2line(read()))):print x["indent"], x["func"], "%x" % x["eip"]

运行

./itrace ./hellow|python2 ./treeify.py ./hellow

测试结果:

     _start /root/glibc/src/glibc-2.18/csu/../sysdeps/i386/start.S:61 8048d40__libc_start_main ??:? 8048ea0_dl_aux_init ??:? 806e590_dl_discover_osversion ??:? 806f3b0uname ??:? 80921c0?? ??:0 b77e0414index ??:? 805b250__x86.get_pc_thunk.bx /root/glibc/src/glibc-2.18/csu/../sysdeps/i386/crti.S:66 8048d70__init_cpu_features ??:? 806f570strncasecmp_l ??:? 80b5ac0strcmp ??:? 805b460memset ??:? 805ba70strcasecmp_l ??:? 805bc10bcmp ??:? 805b6b0strstr ??:? 806b080memchr ??:? 808ce90__x86.get_pc_thunk.bx /root/glibc/src/glibc-2.18/csu/../sysdeps/i386/crti.S:66 8048d70strrchr ??:? 808c660__x86.get_pc_thunk.bx /root/glibc/src/glibc-2.18/csu/../sysdeps/i386/crti.S:66 8048d70wcslen ??:? 808eae0__x86.get_pc_thunk.bx /root/glibc/src/glibc-2.18/csu/../sysdeps/i386/crti.S:66 8048d70__rawmemchr ??:? 805bcc0__x86.get_pc_thunk.bx /root/glibc/src/glibc-2.18/csu/../sysdeps/i386/crti.S:66 8048d70memmove ??:? 805b9d0__strnlen ??:? 808c620__x86.get_pc_thunk.bx /root/glibc/src/glibc-2.18/csu/../sysdeps/i386/crti.S:66 8048d70strcpy ??:? 805b4d0stpcpy ??:? 805bb30__pthread_initialize_minimal ??:? 80494d0__libc_setup_tls ??:? 8049240sbrk ??:? 806cd70__brk ??:? 80928e0?? ??:0 b77e0414__brk ??:? 80928e0?? ??:0 b77e0414memcpy ??:? 805bc50__libc_init_first ??:? 806f4b0__setfpucw ??:? 807ac00__libc_init_secure ??:? 806f360_dl_non_dynamic_init ??:? 806e7f0_dl_get_origin ??:? 809a800?? ??:0 b77e0414malloc ??:? 8058f60malloc_hook_ini malloc.o:? 805a020ptmalloc_init.part.7 malloc.o:? 8059c20__linkin_atfork ??:? 806e0f0malloc ??:? 8058f60_int_malloc malloc.o:? 8057060malloc_consolidate malloc.o:? 80560b0malloc_init_state malloc.o:? 80552e0__default_morecore ??:? 805b230sbrk ??:? 806cd70__brk ??:? 80928e0?? ??:0 b77e0414__default_morecore ??:? 805b230sbrk ??:? 806cd70__brk ??:? 80928e0?? ??:0 b77e0414mempcpy ??:? 805bb00getenv ??:? 804e240strlen ??:? 805b5f0_dl_new_object ??:? 80972a0strlen ??:? 805b5f0__calloc ??:? 8059720_int_malloc malloc.o:? 8057060__memset_sse2_rep ??:? 805f690memcpy ??:? 805bc50_dl_setup_hash ??:? 8097150strlen ??:? 805b5f0malloc ??:? 8058f60_int_malloc malloc.o:? 8057060memcpy ??:? 805bc50_dl_add_to_namespace_list ??:? 8097200getenv ??:? 804e240strlen ??:? 805b5f0_dl_init_paths ??:? 80951f0_dl_important_hwcaps ??:? 80991b0malloc ??:? 8058f60_int_malloc malloc.o:? 8057060mempcpy ??:? 805bb00malloc ??:? 8058f60_int_malloc malloc.o:? 8057060malloc ??:? 8058f60_int_malloc malloc.o:? 8057060getenv ??:? 804e240strlen ??:? 805b5f0getenv ??:? 804e240strlen ??:? 805b5f0getenv ??:? 804e240strlen ??:? 805b5f0getenv ??:? 804e240strlen ??:? 805b5f0getenv ??:? 804e240strlen ??:? 805b5f0__init_misc ??:? 806dd90__strrchr_sse2_bsf ??:? 808d830__ctype_init ??:? 807abb0__cxa_atexit ??:? 804e5d0__new_exitfn ??:? 804e440__libc_csu_init ??:? 80494f0_init /root/glibc/src/glibc-2.18/csu/../sysdeps/i386/crti.S:63 8048190__x86.get_pc_thunk.bx /root/glibc/src/glibc-2.18/csu/../sysdeps/i386/crti.S:66 8048d70_init /root/glibc/src/glibc-2.18/csu/../sysdeps/i386/crtn.S:40 80481aeframe_dummy crtstuff.c:? 8048e20__register_frame_info_bases ??:? 80bd5a0__x86.get_pc_thunk.bx /root/glibc/src/glibc-2.18/csu/../sysdeps/i386/crti.S:66 8048d70register_tm_clones crtstuff.c:? 8048db0init_cacheinfo cacheinfo.o:? 8048b10handle_intel cacheinfo.o:? 806b380intel_check_word cacheinfo.o:? 806b0b0intel_check_word cacheinfo.o:? 806b0b0intel_check_word cacheinfo.o:? 806b0b0intel_check_word cacheinfo.o:? 806b0b0handle_intel cacheinfo.o:? 806b380intel_check_word cacheinfo.o:? 806b0b0intel_check_word cacheinfo.o:? 806b0b0_setjmp ??:? 804d970main ??:? 8048e7cputs ??:? 804f350strlen ??:? 805b5f0_IO_new_file_xsputn ??:? 8052470_IO_file_overflow ??:? 8052e60_IO_doallocbuf ??:? 8053b10_IO_file_doallocate ??:? 808a730_IO_file_stat ??:? 8051f20___fxstat64 ??:? 806c300?? ??:0 b77e0414__mmap ??:? 806ce60?? ??:0 b77e0414_IO_setb ??:? 8053aa0_IO_new_do_write ??:? 80527b0_IO_default_xsputn ??:? 8053bc0exit ??:? 804e420__run_exit_handlers ??:? 804e320__libc_csu_fini ??:? 8049590fini sdlerror.o:? 8048b00check_free.isra.0 sdlerror.o:? 80a6f30__do_global_dtors_aux crtstuff.c:? 8048df0deregister_tm_clones crtstuff.c:? 8048d80__deregister_frame_info_bases ??:? 80bd7c0__x86.get_pc_thunk.bx /root/glibc/src/glibc-2.18/csu/../sysdeps/i386/crti.S:66 8048d70_fini /root/glibc/src/glibc-2.18/csu/../sysdeps/i386/crti.S:82 80bec78__x86.get_pc_thunk.bx /root/glibc/src/glibc-2.18/csu/../sysdeps/i386/crti.S:66 8048d70_fini /root/glibc/src/glibc-2.18/csu/../sysdeps/i386/crtn.S:45 80bec87_IO_cleanup ??:? 80543b0_IO_flush_all_lockp ??:? 8054190_IO_file_overflow ??:? 8052e60_IO_new_do_write ??:? 80527b0new_do_write fileops.o:? 8051100_IO_file_write ??:? 8051f50__write ??:? 806c420?? ??:0 b77e0414_IO_file_setbuf ??:? 8051060_IO_default_setbuf ??:? 8053d10_IO_file_sync ??:? 8053060_IO_setb ??:? 8053aa0_Exit ??:? 806ba24?? ??:0 b77e0414

参考资料

  1. http://lackingrhoticity.blogspot.ca/2009/05/really-simple-tracing-debugger.html

<二>两个gdb集成测试环境

本节重点描述两个gdb集成测试环境。

有没有办法在一边调试的时候,一边显示对应的源码呢?有没有一种工具能够将gdb集成到ide中呢,本文就试图回答这些问题。

emacs gdb

在linux的世界里,emacs集成gdb来时行调试可是闻名已久,经过了不断的演进gud也变得越来越强大,越来越好使了。

那么如何进入gud呢,很简单在emacs中,输入M-x(也就是alt+x)后,输入gdb,然后回车。有一个简短的提示,无视直接回车即可。

在gdb所在窗口设置断点,运行程序。

程序将在设置的断点处停止运行,此时在菜单中选择gud->gdb-mi->display other windows,呈现如下图所示的效果:

gdb tui

与上述的emacs+gdb比较起来,这个gdb tui可能默默无名。我也是在无意之中发现这个东东的,还是比较好使的, 最主要的是这个功能是gdb本身内置的。无须第三方工具。

如何进入gdb tui模式

gdb -tui ./prog

或者在进入gdb之后输入如下快捷键

c-x a

想同时显示源码和反汇编代码的话,就c-x 2或者执行相应的指令layout

写在后面的话

花了15篇文章的内容,将自己日常软件调试时使用到的gdb知识作了一个小结,希望对大家有用。同时俺徽沪一郎也希望大家在转载的时候能够注明原文出处,谢谢。

每天学点GDB(八)相关推荐

  1. [老老实实学WCF] 第八篇 实例化

    老老实实学WCF 第八篇 实例化 通过上一篇的学习,我们简单地了解了会话,我们知道服务端和客户端之间可以建立会话连接,也可以建立非会话连接,通信的绑定和服务协定的 ServiceContract 的S ...

  2. Python可以这样学(第八季:课堂教学管理系统设计与开发实战)-董付国-专题视频课程...

    Python可以这样学(第八季:课堂教学管理系统设计与开发实战)-1398人已学习 课程介绍         董付国老师系列教材<Python可以这样学>(ISBN:97873024564 ...

  3. 【Linux】一步一步学Linux——gdb命令(258)

    00. 目录 文章目录 00. 目录 01. 命令概述 02. 命令格式 03. 常用选项 04. 参考示例 05. 附录 01. 命令概述 gdb命令包含在GNU的gcc开发套件中,是功能强大的程序 ...

  4. 学人工智能电脑主机八大件配置选择指南

    来源:深度之眼 作者:frank 编辑:学姐 <<打造舒适的AI环境>>系列总览: 分为硬件篇x1 跟 软件篇x3 硬件篇1:主机八大件的选购 软件篇1:AI开发过程中常用开发 ...

  5. 从零开始学NLP(八) 隐马尔科夫模型(超详细)

    目录 前言 一.HMM基础 二.HMM定义 三.HMM的三个基本问题 1.概率计算问题 2. 学习问题 3.预测问题 四.HMM中的参数估计 1.前向算法 2.后向算法 五.HMM实例 总结 前言 上 ...

  6. 10锁屏幻灯片_手机跟我学第一百八十八课——如何设置锁屏

    银 / 发 / 学 /堂 手机跟我学 小米手机设置 各位同学们,大家好,我是小银班长 随着科技的发展,手机已经越来越离不开咱们的日常生活,而且也让我们的生活变得更加便利.我们可以对手机的基础设置进行调 ...

  7. 我在b站学数据库 (八):多表操作练习

    上一篇:我在b站学数据库 (七):多表操作练习 数据准备 --创建部门表 create table dept(deptno int primary key, #--部门编号dname varchar( ...

  8. 八代i7学计算机,Intel八代i7-8700配RTX2060组装电脑配置方案,8000元电脑配置推荐...

    继GTX1060甜品级显卡之后,万众期待的RTX2060预计2019年1月15日正式发售,国外定价349美元,而国内定价2499起,虽然它是属于GTX1060下一代继承者,但是其性能提升还是十分大的, ...

  9. 零基础学Arcgis(八)|空间参考

    写在前面的话: B站搜索"中图地信"便可观看全套71章节详细操作视频(有操作数据获取,同步学习) (一)新建Shapefile文件 [1]启动ArcMap,新建空白地图文档: [2 ...

最新文章

  1. C++ Primer 5th笔记(chap 19 特殊工具与技术)类成员指针
  2. linux c语言定位显示字符,Linux c语言实现修改文本字符串
  3. QT的QCompleter类的使用
  4. SpringCloud底层原理
  5. django from组件 实现增加 删除 编辑(推荐用法)
  6. sweetalert php,SweetAlert插件
  7. 机器学习的练功心法(三)——特征工程
  8. java语句类型_01-java数据类型与语句
  9. 树莓派绿灯闪了几下不闪了_城市猎人的树莓派笔记一灯大师
  10. flask查询User,返回对象列表,提示ypeError: Object of type ‘bytes‘ is not JSON serializable解决办法
  11. Requests Header | Http Header
  12. _beginthread, _beginthreadex
  13. 基于51单片机的直流电机正反转及控速+proteus仿真图
  14. pnpm : 无法加载文件 C:\Users\86183\AppData\Roaming\npm\pnpm.ps1,因为在此系统上禁止运行脚本。
  15. ResponseEntity下载
  16. 图像篡改入门02 利用空间结构篡改定位
  17. linux终端命令行删除当前光标之后内容ctrl +k
  18. java-php-python-ssm文献管理平台计算机毕业设计
  19. 树莓派之无屏幕下发现树莓派IP方法
  20. DNS 服务与邮件服务器应用--配置DNS正向解析与反向解析

热门文章

  1. 要毕业了,自学实现SSM开发房屋租赁系统
  2. 四次CA面试经历_manok_新浪博客
  3. [转载]亲历:探访乔布斯的低调豪宅(组图38)
  4. [ 攻防演练演示篇 ] 利用谷歌 0day 漏洞上线靶机
  5. EVE-NG模拟器安装教程
  6. java 如何判断抽象类_JAVA抽象类和抽象方法(abstract)
  7. Linux 用 yum 安装 trzsz
  8. 在Android.mk文件中进行文件拷贝
  9. 冰雪初融,旭日阳刚,a fine day 哦~~~
  10. 多路型DMA接口的工作原理