让我们摇滚。 下面我们有一个C程序,旨在接受和打印命令行参数:
Convert2.c接受要打印的字符串以及使用atoi()函数转换为整数的字符串。 但是,该程序有意包含一个错误。 注意,检查命令行参数数量的代码块已被注释掉。 当程序尝试访问无法访问的内存时,这将导致分段错误:
我们可以使用gdb进一步探索:
注意“ where”命令似乎显示了执行堆栈
仔细看看这一行:
GDB告诉我们argv(指向字符串列表的指针)指向某个地址0xbffff894 。 这是字符串列表中第一个字符串的地址的开头。 让我们检查一下内存:
三个十六进制字中的每一个代表一个命令行自变量(实际上是指向命令行自变量的指针)。 第一个参数始终是可执行文件的名称(在本例中为“ a.out ”),第二个参数在本例中为“ test ”。
由于我们没有提供第三个命令行参数,因此我们无法访问地址0x00000000的内存。 当我们尝试在源代码中使用“ count = atoi(argv [2]); ”行访问它时, 我们遇到了细分错误。
这个示例(间接)突出显示了我们尚未讨论的另一个gdb工具-“ bt”。 如果您在gdb中执行“ where”命令的位置查看两个屏幕截图,则会看到一个堆栈。 您可以使用bt实用程序随时显示执行堆栈的状态。 让我们使用一个示例程序来说明这一点:
Main()调用func1() ,后者调用func2() 。 我们的执行堆栈如下所示:
注意,这是我们运行“ bt”后的堆栈外观:
最上面的框架是我们当前正在使用的框架。 我们可以通过打印n的值(在func2()中此值为30)来验证这一点:
p是“打印”的缩写
我们还可以从一帧移到另一帧-即使当前帧尚未完成执行:
我们还可以通过运行“信息框架”来获取有关每个框架的信息:
在这里,我们看到的是帧#2住在0x7fffffffe5a0调用帧#1,它住在0x7fffffffe580。
这就是我们可以使用bt实用工具检查gdb中的执行堆栈,并希望将其用作跟踪分段错误的工具的方式。
From: https://hackernoon.com/the-basics-of-hacking-part-2-w1d3368v