使用 gdb 查找 memcpy 错误

Posted

技术标签:

【中文标题】使用 gdb 查找 memcpy 错误【英文标题】:Find memcpy error with gdb 【发布时间】:2016-02-07 14:49:52 【问题描述】:

以下代码中的错误是memcpy(t[j], m[j], sizeof(int) * DIM * DIM);应该是memcpy(t[j], m[j], sizeof(int) * DIM);

// Untitled7.c

#include <stdio.h>
#include <string.h>

#define DIM 1000

int main(void)

    int m[DIM][DIM], t[DIM][DIM];
    unsigned j, k;

    for(j = 0; j < DIM; j++)
        for(k = 0; k < DIM; k++)
            m[j][k] = j * DIM + k;

    for(j = 0; j < DIM; j++)
        memcpy(t[j] ,m[j], sizeof(int) * DIM * DIM); // only one DIM

    for(j = 0; j < DIM; j++)
        for(k = 0; k < DIM; k++)
            m[j][k] = t[DIM-k-1][j];

    return 0;

使用 gdb 我怎么能找到那个错误?我了解了如何创建核心文件(使用ulimit -c unlimited),然后我使用了$ gdb Untitled7 core,它给出了:

...

Reading symbols from Untitled7...done.
[New LWP 10610]
Core was generated by ` ?  @  A'. // and symbols of binary files
Program terminated with signal SIGSEGV, Segmentation fault.
#0  __memcpy_ssse3 () at ../sysdeps/i386/i686/multiarch/memcpy-ssse3.S:2590
2590    ../sysdeps/i386/i686/multiarch/memcpy-ssse3.S: File o directory non esistente. // File or directory not existent.

之后我该怎么办?

【问题讨论】:

您无法真正使用 GDB 来查找此类错误。我建议你改用Valgrind。 相关:Recommended way to track down array out-of-bound access/write in C program 【参考方案1】:

您无法通过这种方式总能找到真正的错误,但您可以找到发生分段违规的位置。

您需要使用调试信息编译您的程序,最好不要进行优化,即使用-ggdb -O0 编译标志。如果违规在库函数中,就像在您的示例中一样,请使用gdb 命令up 向上移动调用堆栈,直到您到达您的代码。然后,您应该会看到程序的违规行。

确保gdb 可以找到您的来源。通常当您的当前目录是您的构建目录时,gdb 可以找到它们。如果没有,请使用gdbdirectory 命令。

【讨论】:

以上是关于使用 gdb 查找 memcpy 错误的主要内容,如果未能解决你的问题,请参考以下文章

__memcpy_ssse3() 分段错误

关于c中memcpy的使用

memcpy在啥情况下会失败

memcpy在啥情况下会失败

STM32对memcpy的调用导致hardfault(对memcpy本身的调用,而不是memcpy的执行)

arm gcc5的交叉编译-正确使用memcpy