C 如何仅通过内存地址定位错误?

C 如何仅通过内存地址定位错误?,c,debugging,gdb,C,Debugging,Gdb,我在这样一个对象中得到了一个段错误: http_client_reset(struct http_client *client) { if (client->last_req) { /* @client should never be NULL, but weather a valid object, I don't know */ ... } } 通过调试GDB中的核心转储文件,客户端的内存地址为0x40a651

我在这样一个对象中得到了一个段错误:

http_client_reset(struct http_client *client) {
    if (client->last_req) {
         /* @client should never be NULL, but weather
            a valid object, I don't know */
        ...
    }
}
通过调试GDB中的核心转储文件,
客户端
的内存地址为
0x40a651c0
。我试了好几次,地址都是一样的

然后我在GDB中尝试了
bt
命令:

(gdb) bt
#0  0x0804c80e in http_client_reset (
    c=<error reading variable: Cannot access memory at address 0x40a651c0>, 
    c@entry=<error reading variable: Cannot access memory at address 0x40a651bc>)
    at http/client.c:170
Cannot access memory at address 0x40a651bc
(gdb)bt
#http_客户端_重置中的0 0x0804c80e(
c=,
c@entry=)
http/client.c:170
无法访问地址为0x40a651bc的内存
没有回溯消息,我已经
grep
编辑了我的源代码,并且只有一个调用
http\u client\u reset

  • 如何仅通过内存地址调试此类错误
  • 在访问对象字段之前,是否有方法判断对象是否有效(除了
    obj==NULL

coredump崩溃调试从来都不是一件“黑与白”的事情。因此,您将无法获得与调试coredump相关的问题的确切答案。然而,大多数coredump都是由于编程错误造成的,这些错误可分为广泛的领域。我将提供其中一些广泛的领域和一些调试机制,这可能会对您有所帮助


导致崩溃的编程错误类别

  • 多线程代码-在访问公共数据时检查是否缺少关键部分。这可能会损坏导致此类崩溃的数据。在您的情况下,您可以检查http_客户端指针、对该指针的访问以及CRUD的创建/读取/更新和删除
  • 堆损坏-在大多数情况下,这是一个有效指针,由于在另一段代码中对堆的处理不正确,这可能会导致有效指针被覆盖。想想指针位置内和周围的数组-ABW等问题很容易导致此问题
  • 堆栈损坏-这不太可能,但很难找到。若覆盖堆栈数据(类似于上例中的数组),但覆盖的是堆栈上的数据,那个么同样的问题也会发生
    解除堆芯倾倒根本原因接地的方法

    您需要了解-从技术上讲,coredump是一种非法操作,导致未处理的异常导致崩溃。由于大多数问题都与内存处理有关,因此一个静态分析工具(如
    kloc/PCLint
    将捕获几乎80%的问题。接下来我将运行
    valgrind/purify
    ,很可能会发现问题的其余部分。很少有问题会遗漏这两个问题—这可能是一些与排序/计时相关的代码—可以通过
    代码审查
    找到


    尝试在gdb中使用
    disass
    来反汇编当前函数。不,当一个对象是“坏”值时,无法确定它是否有效。实际上,您只有一个锚点:
    位于http/client。c:170
    在这一点上输入额外的调试信息。Valgrind是您的朋友: