今天在给车综的SDK做测试时,遇到了一个线程崩溃的问题。大概情形是我 用车综的SDK封装了一个类,在一个线程中定义了一个这个类的对象,然后再线程启动的时候,在线程的入口处即导致崩溃。然而以指针的形式来定义则没有问题。经大神指出是因为每个线程对于所使用的堆栈大小是有限制的,我的这个类对象占用的堆栈超出了限制。
以下资料参考博客关于线程堆栈大小的注意事项
每个线程独立拥有一个可配置大小的堆栈,一个线程内所有函数使用到的堆栈都依赖于这个栈,如果太多的变量、参数需要使用栈,则可能导致栈溢出。目前基础平台子系统通过配置环境变量,将默认堆栈大小设置为128K,可以减少这个问题的出现,但业务系统在编码时仍然 需要注意栈的使用,避免出现问题。
包括:
1、不要在函数内部定义过大的局部变量,如过大的结构体变量,联合变量,过大的字符串,数组等;
2、函数调用的深度也需要注意,如果函数 A 调用 B, B 再调用 C,而A/B/C每个函数定义了 10 K的局部变量,则总的栈空间需求将超过 30K;
3、不要直接将大的结构变量通过函数参数传递,这样也会消耗栈空间,可以通过指针或者引用的方式传递;
4、建议每个函数内部定义的变量大小控制在4-8K以下;
5、如果在运行中 COREDUMP,并且通过 GDB 的 WHERE 命令时看到刚进入某个函数就报错,连函数内的第一条调试语句都无法指向,则基本可以认为是栈空间不够导致的,可以尝试将栈空间配置大一点,如果问题不再出现,则可以确定问题。这时需要按照前面几点的要求修改代码,减少栈的使用。
这让我想起了之前在做英伟达硬解时,在线程内分配显存会导致崩溃,而把分配显存移到线程外则没有问题。大神猜测说是线程对显存的分配有限制。 在此一并记录。
另一篇关于修改线程堆栈大小博客设置线程堆栈大小