我一直在使用C / C ++中的webrtc数据通道库和C中的wrote a program:
在debian docker容器上运行正常,在我的主机上openuse tumbleweed(所有x86_64和64bit),但在alpine linux容器(64bit x86_64)上,我在子进程中得到了一个SEGFAULT:
上面的函数来自程序的依赖“libnice”。它似乎是* agent == NULL,并且在caller's范围内无法使其为空。我甚至在函数调用之前插入了一个printf("Argument is %p", agent);
,它打印出了它的内存,我可以验证它不是空的。从反汇编中,它看起来像复制代理的内容(0x557a1d20)作为被调用者堆栈中的局部变量的行导致段错误。即使在make clean
和重新编译之后,此时始终会发生段错误。激活记录失败?堆栈腐败?
更新:我创建了一个更轻量级的容器并运行它,现在它在同一个priv_conn_keepalive_tick_unlocked
的不同位置进行了段错误。似乎设置了参数(注意0x7ffff7f9ad08):
由于我认为我可能会达到libmusl's默认堆栈限制80k,我使用getrlimit(RLIMIT_STACK, &rl)
来获取堆栈大小,看起来它已经是8 MB而不是80k。增加此限制似乎没有任何区别,除非我分配超过8 MB,我的程序早期崩溃内部 Gdb。 Gdb说它有一个未知信号“??”;在gdb之外,它在正常情况下崩溃,在正常情况下它通常会崩溃,而不会改变堆栈大小。
我不确定究竟是什么问题(堆栈损坏?)以及接下来要解决此问题的方法。
这是我的程序流程:
对于创建的每个对等体,使用fork()创建子进程。父< - >子通信由ZeroMQ完成,我使用协议缓冲区将子内部触发的任何回调(及其参数)转发到父进程中运行的事件循环。
因此,对于上述程序,有2个子进程和1个父进程。
重现的步骤:
/psl-librtcdcpp/examples/websocket_client/2in1
答案 0 :(得分:3)
在进一步调查中,崩溃是在一个指令写入一个与堆栈基指针略微大的负偏移,所以它可能只是一个简单的堆栈溢出。
解决此问题的正确方法是减少多余的堆栈使用量或在pthread_create
时明确请求大堆栈,但我看不到从哪里调用pthread_create
。快速检查以确认这是问题是通过在程序的早期某处执行以下操作来覆盖新线程的默认堆栈大小:
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, 1<<20); // 1 MB
pthread_setattr_default_np(&attr);
答案 1 :(得分:0)
将-Werror=implicit-function-declaration
添加到您的CFLAGS中,您将立即找到原因。关键线索是指针值0x557a1d20,这几乎肯定是将指针截断为32位的结果。当您未能声明返回指针的函数并且编译器(通过可靠的向后默认值)假定它返回int而不是产生错误时,会发生这种情况,然后允许从int到指针的隐式转换,尽管C语言不允许它。