仅当通过 makefile 执行程序时出现分段错误

Kul*_*ngh 0 c memory makefile

首先是我的程序的抽象:

\n\n
int main ()\n{\n    My_Struct1 ms1; // sizeof (My_Struct1) is 88712 B  -- L1\n    My_Struct2 ms2; // sizeof (My_Struct2) is 13208 B  -- L2\n\n    // 1. Invoke parser to fill in the two struct instances.  -- L3\n\n    printf ("%ul, %ul\\n", &ms1, &ms2) // -- **L3b** doesn\'t produce seg. fault.\n\n    my_fun (&ms1, &ms2); //  -- L4, does produce seg. fault.\n\n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果我使用makefile运行程序,则会在L4处发生分段错误(总是)。

\n\n

如果我直接从 shell (./executable)执行我的程序,那么有时会发生分段,但并非总是如此,但并非总是如此。

\n\n

错误是:分段错误:无法访问&ms1 和 &ms2 的 L4地址处的内存。错误的类型和位置是gdb指出的。

\n\n

我的猜测是,错误是由于结构的大小造成的。\n请详细解释一下发生了什么。

\n\n

即使将 My_Struct1 的大小减小到 8112 B,将 My_Struct2 减小到 1208 B,错误行为也是相同的。

\n\n

我正在研究:

\n\n
    \n
  • 乌班图14.04
  • \n
  • 英特尔\xc2\xae 核心\xe2\x84\xa2 i5-4200M CPU @ 2.50GHz \xc3\x97 4
  • \n
  • 3.8 GiB 内存
  • \n
  • 海湾合作委员会-4.8.4
  • \n
\n

Bas*_*tch 5

首先,使用所有警告和调试信息进行编译。可能CFLAGS= -g -Wall -Wextra在你的Makefile. 也许您有时可能会添加一些清理工具选项,例如-fsanitize=address或(那么在 2016 年 3 月将您的GCC编译器升级到GCC 5-fsanitize=undefined可能是值得的)。您可能还需要警告开发人员选项-Wstack-usage=1000 -fstack-usage

非常害怕未定义的行为。

然后,启用core(5)转储。可能有一些ulimit -c 100000(或任何实际的数字)~/.bashrc然后启动一个终端;使用cat /proc/self/limits(Linux 特定命令,与proc(5)相关)检查限制是否设置正确。请参阅setrlimit(2)

运行错误的测试,例如使用make test. 你会得到一个core垃圾场。用ls -l core和检查file core

最后,进行事后调试会话。如果您的二进制文件是someprog,请运行gdb someprog core. gdb您输入的第一个命令可能是bt

struct事实上,您在 . 中将相当大的局部变量声明为局部变量可能是错误的main。经验法则是将调用帧限制为最多几千字节(因此,调用堆栈中的局部变量永远不要超过一千字节)。所以我建议将你的大的放在struct堆中(因此使用mallocfree适当地阅读有关C动态内存分配的内容)。但 Linux 上的典型调用堆栈可能会增长到几兆字节。

另外,用valgrind运行你的程序

(void*)顺便说一句,指针的正确格式%p因此您添加的printf应该是

printf("ms1@%p, ms2@%p\n", (void*)&ms1, (void*)&ms2);
Run Code Online (Sandbox Code Playgroud)