首先是我的程序的抽象:
int main ()
{
My_Struct1 ms1; // sizeof (My_Struct1) is 88712 B -- L1
My_Struct2 ms2; // sizeof (My_Struct2) is 13208 B -- L2
// 1. Invoke parser to fill in the two struct instances. -- L3
printf ("%ul, %ul\n", &ms1, &ms2) // -- **L3b** doesn't produce seg. fault.
my_fun (&ms1, &ms2); // -- L4, does produce seg. fault.
return 0;
}
如果我使用 makefile 运行我的程序,则 L4 (始终)会发生分段错误。
如果我直接从shell (./executable)执行我的程序,则分段确实发生有时但不总是。
错误是:分段错误:无法在L4的地址访问& ms1和& ms2两者的内存。错误的类型和位置是 gdb 指出的。
我的猜测是错误是由于结构的大小。 请详细说明目前的情况。
即使将My_Struct1的大小减小到8112 B并将My_Struct2减小到1208 B,错误也是相同的。
我正在努力:
答案 0 :(得分:3)
首先,编译所有警告&调试信息。可能在CFLAGS= -g -Wall -Wextra
中使用Makefile
。也许您可能有时添加一些sanitize instrumentation options,例如-fsanitize=address
或-fsanitize=undefined
(那么将GCC编译器升级到{{3}可能是值得的在2016年3月)。您可能还需要-Wstack-usage=1000
GCC 5& -fstack-usage
warning。
然后,启用undefined behavior转储。您的ulimit -c 100000
可能会有一些~/.bashrc
(或任何数字是现实的),然后启动新终端;检查cat /proc/self/limits
(一个与core(5)相关的特定于Linux的命令),确定了限制。请参阅proc(5)。
运行您的错误测试,例如与make test
。您将获得core
转储。查看ls -l core
和file core
。
最后,做一个事后调试会话。如果您的二进制文件为someprog
,请运行gdb someprog core
。您输入的第一个gdb
命令可能是bt
实际上,在struct
中声明相当大的main
作为局部变量可能是错误的。经验法则是最多将你的调用框架限制为几千字节(因此,setrlimit(2)中的局部变量永远不会超过千字节)。因此,我建议您将大struct
放入堆中(因此请适当使用malloc
和free
,阅读call stack)。但是Linux上的典型调用堆栈可以增长到几兆字节。
另外,使用C dynamic memory allocation
运行您的程序 BTW,(void*)
中%p
指针的正确格式,因此您添加的printf
应为
printf("ms1@%p, ms2@%p\n", (void*)&ms1, (void*)&ms2);