【问题标题】:Segfaulting on function call (C)函数调用的段错误(C)
【发布时间】:2011-06-25 21:51:57
【问题描述】:

所以,我现在有点不知所措,希望有人能提供帮助。我在一个名为“list_free”的库中定义了一个函数,正如您可以想象的那样,它释放了您之前创建的列表。当我从另一个模块中调用此函数时,我的程序会出现段错误。但是,在运行 GDB 时,我得到:

(gdb) bt
#0  *__GI___libc_free (mem=0x65656853) at malloc.c:3709
#1  0x0804f279 in list_free ()
#2  0x0012ffef in set_var (...) at src/calc/model.c:337
#3  0x0804b320 in test_dependency_updates (_i=0) at src/tests/test_calc.c:63
#4  0x080507ea in srunner_run_all ()
#5  0x0804d2b9 in main () at src/tests/test_all.c:19

因此,引起我注意的行是 #1 ... 没有引用该函数的源代码。当我将函数的名称从 list_free 更改为 list_freex (即只是不同的东西)时,不再有段错误。另一个奇怪的事情是,如果我更改 .c 文件中的名称,我不会收到“未定义对 list_free 的引用”的警告,也不会收到因忘记链接库而导致的任何错误。

因此,我被引导相信该函数是在其他地方定义的,但我不知道在哪里。 grep -R list_free . 没有提供任何帮助,gdb 输出似乎没有其他指示。

所以我想知道是否有人对如何查找可能定义此函数的位置有任何提示。另外,我现在已经重命名了上面提到的函数,因为我似乎没有任何其他选择......但我不确定这是否是一个好/安全的主意?即,我这样做可以掩盖其他问题吗?

提前致谢。

【问题讨论】:

  • 至少提供test_calc.c、model.c以及相关头文件的摘录。

标签: c debugging gdb segmentation-fault


【解决方案1】:

如果您使用的是 linux,valgrind 是查找内存管理问题的宝贵工具。

【讨论】:

  • 谢谢 - 也应该提到这一点。我确实使用了 valgrind,它告诉我有一个无效的读取。但我想不通这怎么可能?即,我尝试调试发生无效读取的位置,但找不到...并且在更改函数名称后,我是否仍会收到段错误/无效读取?也就是改函数名后不再得到无效读取?
  • 是的,我使用 -Wall 进行编译。
【解决方案2】:

尝试从链接器生成链接映射。

在我的系统上,在标准输出上生成地图(很多很多行)

gcc ... -Wl,-M ... ### ^ 小写 L

或者,用地图创建一个文件

gcc ... -Wl,-Map,a.map ...

【讨论】:

  • 啊!!太棒了...感谢您的建议。我使用了-Wl,-Map,out.map,以便可以在文件中查看它(从命令行查看时遇到问题)...发现它链接到另一个库中的同名函数(检查单元测试库) !所以想知道 - 你知道我如何告诉 GCC 使用我的“list_free”函数而不是检查函数吗?再次感谢!
  • 我认为您在命令行上指定库的顺序很重要。尝试切换它们出现的顺序
  • 确实......它只是按照它们在命令行中出现的顺序选择第一个找到的。我预计 gcc 会说multiple definition of ...。有没有办法在不手动检查地图文件的情况下找到类似的讨厌的错误?
  • 这是一个链接器问题,而不是编译器(编译器会抱怨multiple definition 消息)。我找不到让链接器抱怨的方法......
  • 知道了——我得摆弄它。我正在使用自动构建系统,所以我不确定如何更改它,但这是有道理的。再次感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 2018-01-26
  • 1970-01-01
  • 2021-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-10
相关资源
最近更新 更多