根据定义,调试工具是那些那些使我们能够监测、控制和纠正其他程序的程序。我们为什么应该用调试工具呢? 在有些情况下,运行一些程序的时候我们会被卡住,我们需要明白究竟发生了什么。 例如,我们正在运行应用程序,它产生了一些错误消息。要修复这些错误,我们应该先找出为什么产生这些错误的消息和这些错误消息从哪里产生的。 一个应用程序可能突然挂起,我们必须了解其他什么进程同时在运行。我们可能还必须弄清楚某个进程挂起的时候在做什么。为了剖析这些细节, 我们需要调试工具的帮助。
有几个Linux下的用户空间调试工具和技术,它们用来分析用户空间的问题相当有用。它们是:
'print' 语句
查询 (/proc, /sys 等)
跟踪 (strace/ltrace)
Valgrind (memwatch)
GDB
让我们一个个地了解。
1.'print' 语句这是一个基本的原始的调试问题的方法。 我们可以在程序中插入print语句来了解控制流和变量值。 虽然这是一个简单的技术, 但它有一些缺点。 程序需要进行编辑以添加'print'语句,然后必须重新编译,重新运行来获得输出。 如果要调试的程序相当大,这是一个耗时的方法。
2. 查询在某些情况下,我们需要弄清楚在一个运行在内核中的进程的状态和内存映射。为了获得这些信息,我们不需要在内核中插入任何代码。 相反,可以用 /proc 文件系统。
/proc 是一个伪文件系统,系统一启动运行就收集着运行时系统的信息 (cpu信息, 内存容量等)。
'ls /proc'的输出
正如你看到的, 系统中运行的每一个进程在/proc文件系统中有一个以进程id命名的项。每个进程的细节信息可以在进程id对应的目录下的文件中获得。
'ls /proc/pid'的输出
解释/proc文件系统内的所有条目超出了本文的范围。一些有用的列举如下:
/proc/cmdline -> 内核命令行
/proc/cpuinfo -> 关于处理器的品牌,型号信息等
/proc/filesystems -> 文件系统的内核支持的信息
/proc/<pid>/cmdline -> 命令行参数传递到当前进程
/proc/<pid>/mem -> 当前进程持有的内存
/proc/<pid>/status -> 当前进程的状态
3. 跟踪strace的和ltrace是两个在Linux中用来追踪程序的执行细节的跟踪工具。
strace:strace拦截和记录系统调用及其接收的信号。对于用户,它显示了系统调用、传递给它们的参数和返回值。strace的可以附着到已在运行的进程或一个新的进程。它作为一个针对开发者和系统管理员的诊断、调试工具是很有用的。它也可以用来当做一个通过跟踪不同的程序调用来了解系统的工具。这个工具的好处是不需要源代码,程序也不需要重新编译。
使用strace的基本语法是:
strace 命令
strace有各种各样的参数。可以检查看strace的手册页来获得更多的细节。
strace的输出非常长,我们通常不会对显示的每一行都感兴趣。我们可以用'-e expr'选项来过滤不想要的数据。
用 '-p pid' 选项来绑到运行中的进程.
用'-o'选项,命令的输出可以被重定向到文件。
strace过滤成只有系统调用的输出
ltrace:ltrace跟踪和记录一个进程的动态(运行时)库的调用及其收到的信号。它也可以跟踪一个进程所作的系统调用。它的用法是类似与strace。
ltrace command
'-i' 选项在调用库时打印指令指针。
'-S' 选项被用来现实系统调用和库调用
所有可用的选项请参阅ltrace手册。
ltrace捕捉'STRCMP'库调用的输出
4. ValgrindValgrind是一套调试和分析工具。它的一个被广泛使用的默认工具——'Memcheck'——可以拦截malloc(),new(),free()和delete()调用。换句话说,它在检测下面这些问题非常有用:
内存泄露
重释放
访问越界
使用未初始化的内存
使用已经被释放的内存等。
它直接通过可执行文件运行。
Valgrind也有一些缺点,因为它增加了内存占用,会减慢你的程序。它有时会造成误报和漏报。它不能检测出静态分配的数组的访问越界问题。
为了使用它,首先请下载并安装在你的系统上。可以使用操作系统上的包管理器来安装。
使用命令行安装需要解压缩和解包下载的文件。