c堆内存布局
c heap memory layout
我正在开发一个使用结构链表的相当复杂的 c 程序。在我的一个 .c 文件 (queue_head) 的顶部声明了一个全局变量。这个变量现在被神秘地覆盖,这会导致段错误。
有什么方法可以找出我的变量在内存中的布局。我对原因的最佳猜测是某些东西正在写入它的内存末尾并覆盖 queue_head 内存位置。
为了测试我在源文件中颠倒了 queue_head 和 queue_tail 的位置,下次我 运行 程序时,queue_tail 被破坏了但是 queue_head 很好。
当然它可能是一个 er运行t 指针,但我相信它背后的某些东西在内存中被写入超过它的内存分配。
有没有办法查看 c 如何映射出缺少反汇编的变量?
从大多数编译器(或更有可能是链接器),您可以生成一个 .map 文件,它将列出所有全局变量和函数。
你没有提到你使用的是哪个编译器,但是对于 gcc 会回答你的问题。
基本上,将此添加到您的 gcc 行:
-Xlinker -Map=output.map
变量通常按照在文件中出现的顺序排列,但如果程序有多个文件,则更难预测。您可以打印他们的地址以查找可能的违规者:
printf("%p %p\n", &queue_head, &fishy_var);
但是找到前一个变量有什么好处呢?损坏的代码很可能没有直接引用它。
更好的方法是使用调试器。例如,如果您可以 运行 在 gdb 中编程,那么您可以使用观察点在内存损坏的位置中断:watch queue_head
。此程序将在每次 queue_head 值更改后中断,包括合法使用。为了隔离合法使用,在 queue_head 之前添加虚拟指针变量并观察它:
void *fishy_var;
queue *queue_head;
然后在 gdb 中:
break main
run
watch fishy_var
continue
这应该直接指向有问题的代码。
请注意,您最好将我之前在 main 开始时展示的 printf 放在 1. 确保变量在内存中是连续的,以及 2. 确保编译器不会优化掉未使用的 fishy_var .
我正在开发一个使用结构链表的相当复杂的 c 程序。在我的一个 .c 文件 (queue_head) 的顶部声明了一个全局变量。这个变量现在被神秘地覆盖,这会导致段错误。
有什么方法可以找出我的变量在内存中的布局。我对原因的最佳猜测是某些东西正在写入它的内存末尾并覆盖 queue_head 内存位置。
为了测试我在源文件中颠倒了 queue_head 和 queue_tail 的位置,下次我 运行 程序时,queue_tail 被破坏了但是 queue_head 很好。
当然它可能是一个 er运行t 指针,但我相信它背后的某些东西在内存中被写入超过它的内存分配。
有没有办法查看 c 如何映射出缺少反汇编的变量?
从大多数编译器(或更有可能是链接器),您可以生成一个 .map 文件,它将列出所有全局变量和函数。
你没有提到你使用的是哪个编译器,但是对于 gcc
基本上,将此添加到您的 gcc 行:
-Xlinker -Map=output.map
变量通常按照在文件中出现的顺序排列,但如果程序有多个文件,则更难预测。您可以打印他们的地址以查找可能的违规者:
printf("%p %p\n", &queue_head, &fishy_var);
但是找到前一个变量有什么好处呢?损坏的代码很可能没有直接引用它。
更好的方法是使用调试器。例如,如果您可以 运行 在 gdb 中编程,那么您可以使用观察点在内存损坏的位置中断:watch queue_head
。此程序将在每次 queue_head 值更改后中断,包括合法使用。为了隔离合法使用,在 queue_head 之前添加虚拟指针变量并观察它:
void *fishy_var;
queue *queue_head;
然后在 gdb 中:
break main
run
watch fishy_var
continue
这应该直接指向有问题的代码。
请注意,您最好将我之前在 main 开始时展示的 printf 放在 1. 确保变量在内存中是连续的,以及 2. 确保编译器不会优化掉未使用的 fishy_var .