测试从 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 的库时出现分段错误的主要内容,如果未能解决你的问题,请参考以下文章

更改默认网关时出现分段错误

获取 QString 时出现分段错误

在 Python Pandas 中使用 read_parquet 从 AWS S3 读取镶木地板文件时出现分段错误

迁移 Qt4 至 Qt5 的几个主要环节(数据库插件别拷错了地方)

从 C 调用汇编函数时出现分段错误错误

访问共享内存时出现分段错误