分段错误仅在发布配置下发生
Posted
技术标签:
【中文标题】分段错误仅在发布配置下发生【英文标题】:Segmentation fault occurs only under release configuration 【发布时间】:2012-03-25 06:18:10 【问题描述】:出于某种奇怪的原因,当我切换到发布并在调试器之外运行它时,我的应用程序喜欢中断我。这对我有用,这对我没用
(Qt Creator 是 IDE)
使用调试配置进行调试 - ok 使用调试配置运行 - ok 使用发布配置进行调试 - ok 使用发布配置运行 - 应用程序崩溃我的 UI 是一个项目,一些东西的核心是一个单独的依赖项。在 Windows 上(使用 MSVCC 编译),我点击了一个菜单按钮,它最终调用了一个函数。在该函数中,应用程序在向向量添加新元素时中断。例如:
str *x = new str();
str *y = new str();
/* ...set some of x & y's members... */
vector.push_back(x); // works fine
vector.push_back(y); // causes crash
如果我注释掉 vector.push_back(y);
行,应用程序将继续没有问题,直到应用程序离开事件范围(即 OnMenuButtonClick
的结尾)。在 OS X 上,它类似于向向量添加元素的问题,除了我有:
std::vector<foo *> SomeFunction()
std::vector<foo *> returningVector;
/* do stuff */
std::vector<foo *> goo = GetFooObjects();
for (int i = 0; i < goo.size(); i++)
returningVector.push_back(goo[i]); // breaks here
那么,在没有附加调试器且不在调试配置下的情况下,这种奇怪行为的一些原因是什么?我已经检查以确保我的所有变量都已初始化,所以我很难过。如果要查看上面的代码,第一部分可以定位到@987654321@,第二部分可以定位到@987654322@。请原谅您认为“不好”的任何内容,如果您有无法包含的建议,请在 GitHub 上给我发消息。
编辑:
我对其进行了更深入的研究,并确切地找到了导致问题的原因,但不知道如何解决它。这是我的应用程序崩溃的函数(在 OS X 上):
vector<Drive *> Drive::GetFATXDrives( bool HardDisks )
vector<Drive *> Return;
if (HardDisks)
vector<DISK_DRIVE_INFORMATION> Disks = GetPhysicalDisks();
for (int i = 0; i < (int)Disks.size(); i++)
DISK_DRIVE_INFORMATION ddi = Disks.at(i);
// First, try reading the disk way
Streams::xDeviceStream* DS = NULL;
try
char path[0x200] = 0;
wcstombs(path, ddi.Path, wcslen(ddi.Path));
DS = new Streams::xDeviceStream(ddi.Path);
catch (xException& e)
continue;
if (DS == NULL || DS->Length() == 0 || DS->Length() < HddOffsets::Data)
// Disk is not of valid length
continue;
DS->SetPosition(HddOffsets::Data);
// Read the FATX partition magic
int Magic = DS->ReadInt32();
// Close the stream
DS->Close();
// Compare the magic we read to the *actual* FATX magic
if (Magic == FatxMagic)
Drive *d = new Drive(Disks.at(i).Path, Disks.at(i).FriendlyName, false);
Return.push_back(d);
vector<Drive *> LogicalDisks = GetLogicalPartitions();
for (int i = 0; i < (int)LogicalDisks.size(); i++)
Return.push_back(LogicalDisks.at(i));
return Return;
如果我将if (HardDisks)
更改为if (HardDisks = false)
,应用程序运行正常。因此,我查看了该范围,发现在vector<DISK_DRIVE_INFORMATION> Disks = GetPhysicalDisks();
之后,堆损坏或类似情况。我注意到这一点是因为在调试器中,调用该函数后,我的 HardDisks
bool 变为“false”,这与之前不同。
这里是GetPhysicalDisks
:
vector<Drive::DISK_DRIVE_INFORMATION> Drive::GetPhysicalDisks( void )
// RIGHT AFTER this vector is initialized, everything goes to hell
vector<Drive::DISK_DRIVE_INFORMATION> ReturnVector;
DIR *dir;
dirent *ent;
dir = opendir("/dev/");
if (dir != NULL)
// Read the shit
while ((ent = readdir(dir)) != NULL)
// Check the directory name, and if it starts with "disk" then keep it!
QRegExp exp("disk*");
exp.setPatternSyntax(QRegExp::Wildcard);
exp.setCaseSensitivity(Qt::CaseInsensitive);
if (exp.exactMatch(ent->d_name))
DISK_DRIVE_INFORMATION curdir;
memset(curdir.FriendlyName, 0, sizeof(curdir.FriendlyName));
memset(curdir.Path, 0, sizeof(curdir.Path));
char diskPath[0x50] = 0;
sprintf(diskPath, "/dev/r%s", ent->d_name);
mbstowcs(curdir.Path, diskPath, strlen(diskPath));
int device;
if ((device = open(diskPath, O_RDONLY)) > 0)
#ifdef __linux
hd_driveid hd;
if (!ioctl(device, HDIO_GET_IDENTITY, &hd))
swprintf(curdir.FriendlyName, strlen(hd) * 2, L"%hs", hd.model);
#elif defined __APPLE__
mbstowcs(curdir.FriendlyName, ent->d_name, strlen(ent->d_name));
#endif
ReturnVector.push_back(curdir);
return ReturnVector;
【问题讨论】:
你能把你的 push_back 放在 try .. catch 块中,看看你是遇到异常还是崩溃? 没有骰子。如果它确实有效,我仍然会积极寻找根本原因,因为它会消除问题而不一定解决它。 这并不是为了解决问题,但是如果您可以显示异常消息,它应该对您有所帮助。 我可能应该在之前说明我在崩溃之前附加了调试器,这就是我发现这是一个分段错误的原因。 “收到信号:下级停止,因为它收到了来自操作系统的信号。信号名称:SIGSEGV,信号含义:分段错误”。我也忘了在第一次回复时说谢谢。 如果 valgrind 的 memcheck 发现诸如无效读/写之类的问题,请在 Linux 或 OS X 上尝试。 【参考方案1】:虽然这不是关于发生了什么的真正答案,但我确实找到了解决问题的方法。查看上面的编辑,我编辑了我的Drive::GetFATXDrives
函数,如下所示:
vector<Drive *> Drive::GetFATXDrives( bool HardDisks )
// Initialize Disks vector up here
vector<DISK_DRIVE_INFORMATION> Disks;
// Call the function to get the hard disks
if (HardDisks)
Drive::GetPhysicalDisks(Disks);
vector<Drive *> ReturnVector;
if (HardDisks)
Streams::xDeviceStream* DS = NULL;
for (int i = 0; i < (int)Disks.size(); i++)
/* ... */
if (DS)
DS->Close();
delete DS;
vector<Drive *> LogicalDisks = GetLogicalPartitions();
for (int i = 0; i < LogicalDisks.size(); i++)
ReturnVector.push_back(LogicalDisks[i]);
return ReturnVector;
我的Drive::GetPhysicalDisks
函数现在采用vector<DISK_DRIVE_INFORMATION>
引用而不是返回一个。似乎在那之后我的程序就可以正常工作了。
【讨论】:
以上是关于分段错误仅在发布配置下发生的主要内容,如果未能解决你的问题,请参考以下文章