《C语言程序设计进阶教程》一2.7 在DDD(命令行调试程序)上检测调用栈

简介: 本文讲的是C语言程序设计进阶教程一2.7 在DDD(命令行调试程序)上检测调用栈,本节书摘来华章计算机《C语言程序设计进阶教程》一书中的第2章,第2.6.2节, Intermediate C Programming[美] 陆永祥(Yung-Hsiang Lu) 著 徐东 译 译更多章节内容可以访问云栖社区“华章计算机”公众号查看。

2.7 在DDD(命令行调试程序)上检测调用栈

本文讲的是C语言程序设计进阶教程一2.7 在DDD(命令行调试程序)上检测调用栈,在编辑器中输入下面的程序,并把名字存为p1.c
screenshot
screenshot
不要担心还不能完全理解main函数中的argv,这将会在之后讨论。在Linux终端下使用下面的命令创建可执行文件:
screenshot
这里使用gcc将C程序(p1.c)的源文件转化为计算机可以理解的可执行文件。添加-g启用调试,这样我们可以检验调用栈。添加-Wall和-Wshadow启用警告信息。影子变量将会在4.1节中进行讲解。警告信息有时是良性的,但是它们通常表明在代码中有深层的问题。总是启用警告信息并按照gcc的建议去做是一个好的习惯。输出文件(即可执行文件)的名字由-o所指定。在本例中,p1是此gcc命令的输出,因此是可执行文件(即程序)。它可以通过在终端中输入下列内容来运行:
screenshot
输出应该和下面相同:
screenshot
要看到调用栈,我们需要启动调试工具。在本例中,我们将使用DDD(命令行调试程序)。DDD是一个针对GDB调试工具的图形用户界面。启动DDD,进入菜单并点击:
File→Open Program→select p1→Open
这里,我们已经选择了可执行程序而不是.c文件。调试工具将自动地基于gcc留在可执行文件中的信息找到.c文件。当调试一个使用多个源文件的程序时这会很有用。
在底部窗口(gdb)提示之后,可在两个函数g1和g2中使用下面的指令设置断点:
screenshot
指令b g1指示DDD在函数g1开始时设置一个断点。当程序到达g1的第一行,程序将停止,你会有机会检查程序的状态。指令b g2指示DDD在函数g2开始时类似地去设置一个断点。
通过在(gdb)提示时输入下面的指令来执行此程序:
screenshot
程序将会启动,然后在函数g2的断点处停止。为什么程序在g2处停止而不是g1呢?因为main函数调用g2,所以g2在g1之前被执行。如果设置了多个断点,那么程序将按照它们被执行的顺序停止在断点处,而不是按照它们被设置的顺序。在本例中,虽然在g1中的断点是先设置的,但程序先执行g2。所以,程序将先停在g2中的断点处。
要继续这个程序,输入下面的指令:
screenshot
程序将继续执行,之后停在下一个断点处,该断点位于函数g1中。调用栈可以通过调用栈回溯查看到。这可以用下面的指令完成:
screenshot
这条指令的意思是“栈回溯”。你会在调试工具中看到什么?
screenshot
a和b的值在顶部栈帧中显示。每一行的起始显示了调用栈的栈帧(0、1和2),与函数g1、g2和main函数相对应。可以使用f命令来看到不同的栈帧:例如,输入:
screenshot
可以看到frame1,即函数g2的栈帧。a和b的值被再一次地显示。它们的值是多少呢?0x之后的数字在你的计算机上可能与此不同,这些就是地址。在g2的栈帧中,a和b的值与顶部栈帧中的值不同。图2.6~图2.9显示了一些DDD的截图。
screenshot
screenshot
screenshot
screenshot

原文标题:C语言程序设计进阶教程一2.7 在DDD(命令行调试程序)上检测调用栈

相关文章
|
存储 自然语言处理 编译器
【C语言】编译与链接:深入理解程序构建过程
【C语言】编译与链接:深入理解程序构建过程
220 1
|
10月前
|
监控 Linux PHP
【02】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-2月12日优雅草简化Centos stream8安装zabbix7教程-本搭建教程非docker搭建教程-优雅草solution
【02】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-2月12日优雅草简化Centos stream8安装zabbix7教程-本搭建教程非docker搭建教程-优雅草solution
362 20
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
371 5
|
C语言
C语言编程中,错误处理至关重要,能提升程序的健壮性和可靠性
C语言编程中,错误处理至关重要,能提升程序的健壮性和可靠性。本文探讨了C语言中的错误类型(如语法错误、运行时错误)、基本处理方法(如返回值、全局变量、自定义异常处理)、常见策略(如检查返回值、设置标志位、记录错误信息)及错误处理函数(如perror、strerror)。强调了不忽略错误、保持处理一致性及避免过度处理的重要性,并通过文件操作和网络编程实例展示了错误处理的应用。
396 4
|
网络协议 物联网 数据处理
C语言在网络通信程序实现中的应用,介绍了网络通信的基本概念、C语言的特点及其在网络通信中的优势
本文探讨了C语言在网络通信程序实现中的应用,介绍了网络通信的基本概念、C语言的特点及其在网络通信中的优势。文章详细讲解了使用C语言实现网络通信程序的基本步骤,包括TCP和UDP通信程序的实现,并讨论了关键技术、优化方法及未来发展趋势,旨在帮助读者掌握C语言在网络通信中的应用技巧。
356 2
|
存储 算法 C语言
用C语言开发游戏的实践过程,包括选择游戏类型、设计游戏框架、实现图形界面、游戏逻辑、调整游戏难度、添加音效音乐、性能优化、测试调试等内容
本文探讨了用C语言开发游戏的实践过程,包括选择游戏类型、设计游戏框架、实现图形界面、游戏逻辑、调整游戏难度、添加音效音乐、性能优化、测试调试等内容,旨在为开发者提供全面的指导和灵感。
559 2
|
NoSQL 编译器 C语言
C语言调试是开发中的重要技能,涵盖基本技巧如打印输出、断点调试和单步执行,以及使用GCC、GDB、Visual Studio和Eclipse CDT等工具。
C语言调试是开发中的重要技能,涵盖基本技巧如打印输出、断点调试和单步执行,以及使用GCC、GDB、Visual Studio和Eclipse CDT等工具。高级技巧包括内存检查、性能分析和符号调试。通过实践案例学习如何有效定位和解决问题,同时注意保持耐心、合理利用工具、记录过程并避免过度调试,以提高编程能力和开发效率。
425 1
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
453 1
|
程序员 C语言
C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门
C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门。本文深入探讨了指针的基本概念、声明方式、动态内存分配、函数参数传递、指针运算及与数组和函数的关系,强调了正确使用指针的重要性,并鼓励读者通过实践掌握这一关键技能。
248 1
|
编译器 C语言 C++
VSCode安装配置C语言(保姆级教程)
VSCode安装配置C语言(保姆级教程)
1157 4