【发布时间】:2011-08-30 13:14:36
【问题描述】:
我试图消除段错误的常见原因,例如取消引用空指针,但我很难过。此错误不会出现在我的调试模式下的测试机器上,但会出现在我的生产机器上发布编译。两者都设置为 /O0 以消除这种可能性。当我注释掉字符串分配时,段错误消失了,现在我只需要了解发生了什么,以便我可以修复它。
可能有一些更明显的东西,但另一个复杂的问题是该代码正在由内核模式应用程序调用,而供应商关于为系统编写安全代码的唯一说明是“每个需要任何东西的函数来自操作系统或必须等待来自操作系统的任何东西都不起作用”(逐字)。
union {
REAL_T real[8];
char byte[64];
} fileName;
void transferFilenames () {
string tempname;
// This is from an api I must use, it retrieves values from NVRAM on
// an accessory board. Specifically it will return 8 REAL_T values
// and store them starting at &filename.real[0], inp/outpArray are
// globals defined elsewhere.
inpArray.I7_ARRAY.INDEX = 2903;
inpArray.I7_ARRAY.LEN = 8;
inpArray.I7_ARRAY.Z_PAR_PTR = &fileName.real[0];
b_array ( READ_CYCLE_PARAMS, &status, &inpArray, &outpArray );
// if status != 0, there was an error
if ( status == 0 ) {
// there is no guarantee of being null terminated
fileName.byte[63] = 0;
/* This test code didn't fix the problem
int i;
char myStr[64];
for ( i = 0; i < 64; i++ )
myStr[i] = fileName.byte[i];
if ( myStr[0] != '\0' )
string mystring( myStr ); // seg fault
*/
tempname.assign( fileName.byte ); // Throws seg fault
// tempname.assign( &fileName.byte[0] ); // try to be more explicit
// controlBlock is a global class defined elsewhere
controlBlock->setFileName ( tempname, ISINPUT);
} else {
controlBlock->setFileName( "BAD", ISINPUT );
}
return;
}
当我重载控制块以直接获取 char* controlBlock->setFileName( &fileName.byte[0] ) 并完全删除字符串分配时,分段错误消失了。重载所做的只是将 char* 分配给本地字符串并调用常规方法。
我在幕后缺少什么?
【问题讨论】:
-
你的核心文件/调试器说
fileName.byte是什么时候崩溃? -
@MarkB 程序崩溃时没有创建转储文件。实时系统不支持实时调试,而宽松的计时系统不存在此错误。
-
我之前已经注释掉了这个块中的所有代码,除了 assign 语句和段错误仍然存在。将其反转并仅留下注释的分配删除了段错误。
-
你也在其他地方使用 std::string 吗?它确实在堆上分配,而不是在堆栈上。
-
添加到 murrekatt 的评论中,并在我的回答之后我的:子句 需要操作系统中的任何内容或必须等待操作系统中的任何内容的每个功能都将不起作用阻止您使用大量 C++ 库。有问题的系统很可能按照
malloc (size_t) {kill (0, SEGBUS); }的方式实现malloc
标签: c++ string segmentation-fault unions