测试从 qt4 迁移到 qt5 的库时出现分段错误
Posted
技术标签:
【中文标题】测试从 qt4 迁移到 qt5 的库时出现分段错误【英文标题】:Segmentation fault when testing migrated library from qt4 to qt5 【发布时间】:2014-05-14 12:02:16 【问题描述】:我正在测试这个库,但每当它到达某一行时我就会遇到分段错误(下面的注释行)。这个问题来自this question - 在一个更大的项目中遇到同样的问题,所以我决定单独测试这些库,显然这就是失败的原因。此代码适用于使用 Qt4 的同事的 32 位机器(他将代码交给了我)。我将它迁移到 Qt5 并使用 32 位编译器编译,但我遇到了分段错误。如果我评论有问题的行和它下面的两个,程序就会运行(尽管它只是一个空窗口)。 会发生什么?
#include "qenctest.h"
#include <QLibrary>
#include <QtWidgets/QMessageBox>
typedef void (*encRefresh)(QPainter*);
encRefresh enc_refresh = NULL;
typedef void (*encResize)(QSize);
encResize enc_resize = NULL;
typedef QENCSignaler* (*encInit)(QString);
typedef void (*encOpenFile)(QString);
QENCTest::QENCTest(QWidget *parent, Qt::WindowFlags flags)
: QMainWindow(parent, flags)
ui.setupUi(this);
QLibrary _qenc("qenc");
encInit enc_init;
encOpenFile enc_openFile;
enc_init = (encInit) _qenc.resolve("init"); // I checked and it does load the library and the symbol succesfully
enc_openFile = (encOpenFile) _qenc.resolve("openFile");
enc_resize = (encResize) _qenc.resolve("resize");
enc_refresh = (encRefresh) _qenc.resolve("refresh");
QString path = "encfg";
QENCSignaler* qencSignaler = enc_init(path); // Throws segfault here
connect(qencSignaler, SIGNAL(newChart(Chart*)), this, SLOT(qencNewChart(Chart*)));
connect(qencSignaler, SIGNAL(startReadChart(char*)), this, SLOT(qencStartReadChart(char*)));
enc_openFile("PL2BAPOL.000");
int _s = 0;
调试信息:
PS: 一些本地人和表达式是红色的是什么意思?
编辑
好的,我必须对库代码进行的唯一主要更改是:
AttributeSet::iterator vItPOI = attributes.at(i).find("POI");
if (vItPOI == attributes.at(i).end()) continue;
AttributeSet::iterator vItPOI0 = attributes.at(i).find("POI0");
if (vItPOI0 == attributes.at(i).end()) continue;
if (vItPOI -> getStringValue() == "Bankowoæ" &&
selectedPOI & POI_BANKING)
if (vItPOI0 -> getStringValue() == "Placówka banku")
drawSymbol(painter, x, y, POI_BANKING);
对此(还有更多的ifs,但这很好地说明了它)
ShapeAttribute vItPOI = attributes.at(i).find("POI").value();
if (attributes.at(i).find("POI") == attributes.at(i).end()) continue;
ShapeAttribute vItPOI0 = attributes.at(i).find("POI0").value();
if (attributes.at(i).find("POI0") == attributes.at(i).end()) continue;
if (vItPOI . getStringValue() == "Bankowo��" &&
selectedPOI & POI_BANKING)
if (vItPOI0 . getStringValue() == "Plac�wka banku")
drawSymbol(painter, x, y, POI_BANKING);
理论上应该是一样的吧?尽管我确实觉得奇怪的是,在第一个 sn-p 中它使用 -> 而不是 .当它不是指针时。我不得不将其更改为,因为我收到了这些错误:
^
..\qenc\ShapeLandPOI.cpp: In member function 'virtual void ShapeLandPOI::draw(QPainter*)':
..\qenc\ShapeLandPOI.cpp:74:62: error: conversion from 'QMap<QString, ShapeAttribute>::const_iterator' to non-scalar type 'QMap<QString, ShapeAttribute>::iterator' requested
AttributeSet::iterator vItPOI = attributes.at(i).find("POI");
^
..\qenc\ShapeLandPOI.cpp:76:64: error: conversion from 'QMap<QString, ShapeAttribute>::const_iterator' to non-scalar type 'QMap<QString, ShapeAttribute>::iterator' requested
AttributeSet::iterator vItPOI0 = attributes.at(i).find("POI0");
^
【问题讨论】:
你可以进入库代码吗? @ratchetfreak 不,先生,如果我尝试这样做,我会得到反汇编代码,我能得到的最远是上面显示的第 4 级 反汇编代码很好,这意味着它是负责错误的库而不是您的加载代码 @ratchetfreak 问题是我从库中获得了代码并将其从 Qt4 迁移到 Qt5,我在发布模式下构建它并使用与此应用程序相同的编译器。也许我应该小心地再次迁移它? 您可能应该重建库的调试版本,并尝试调试它,因为故障似乎在那里。它可能包含一些似乎适用于 Qt4 但不再适用的未定义行为。 【参考方案1】:在您更改的代码中,您有一行
ShapeAttribute vItPOI0 = attributes.at(i).find("POI0").value();
但如果 "POI0"
未找到,find
函数将返回 end
,它是一个指向 集合的迭代器,因此 value
函数将导致 @987654321 @。
至于错误,QMap
对象似乎是常量,因此您无法获得非常量迭代器。只需更改为使用AttributeSet::const_iterator
,您就可以使用原始功能,否则未修改。这可能会解决您的崩溃问题,因为这样您就不会有上述未定义行为的风险。
【讨论】:
我仍然遇到问题,但这绝对是问题的重要部分,我已经设法更好地找到问题,谢谢。以上是关于测试从 qt4 迁移到 qt5 的库时出现分段错误的主要内容,如果未能解决你的问题,请参考以下文章
在 Python Pandas 中使用 read_parquet 从 AWS S3 读取镶木地板文件时出现分段错误