Segmentation fault when testing migrated library from qt4 to qt5 - c++

I am testing this library but I am getting a segmentation fault whenever it reachs a certain line (the commented one below). This issue comes from this question - tldr the same problem on a much bigger project, so I decided to test the libraries separatedly and apparently this is what fails. This code works on a co-worker's 32bits machine using Qt4 (he handed me the code). I migrated it to Qt5 and compiled with a 32bit compiler and I am getting the segmentation fault. If I comment the offending line and the two below it the program runs (although its just an empty window).
What could be happening?
#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;
}
Debug info:
PS: What does it mean that some locals & expressions are in red?
EDIT
Alright, the only major changes I had to make in the library code were these:
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);
}
}
To this (there are more ifs but this illustrates it properly)
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);
}
}
In theory it should be the same shouldnt it? Although I do find strange that in the first snippet it uses -> instead of . when its not a pointer. I had to change it to that because I was getting these errors:
^
..\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");
^

In your changed code you have the line
ShapeAttribute vItPOI0 = attributes.at(i).find("POI0").value();
But if "POI0" is not found the find function would return end which is an iterator pointing to beyond the collection, and so it's value function would be causing undefined behavior.
As for the errors it seems that the QMap object is constant, and so you can't get non-const iterators. Just change to use AttributeSet::const_iterator instead and you can use the original function otherwise unmodified. This will probably fix your crashes, as then you don't have the risk of undefined behavior as described above.

Related

llvm basic block predecessors llvm pred_iterator out of range

I'm trying to iterator over the predecessors of a basic block and I'm getting using the following code:
for (::llvm::PredIterator PI = pred_begin(post_block); PI != pred_end(post_block); PI++)
{
::llvm::BasicBlock *pred = *PI;
if (pred != exec_block)
{ ...
In the line with the if statement, I'm getting the following error:
In instantiation of ‘llvm::PredIterator<Ptr, USE_iterator>::reference llvm::PredIterator<Ptr, USE_iterator>::operator*() const [with Ptr = llvm::BasicBlock; USE_iterator = llvm::Value::use_iterator_impl<llvm::Use>; llvm::PredIterator<Ptr, USE_iterator>::reference = llvm::BasicBlock*]’:LLVMTC.cpp:1489:31:
required from here /usr/local/include/llvm/Support/CFG.h:56:5: error: ‘const class llvm::Value::use_iterator_impl<llvm::Use>’ has no member named ‘atEnd’
assert(!It.atEnd() && "pred_iterator out of range!");
Does anyone have any ideas what might be causing this problem? I'm basing my code off of: http://llvm.org/docs/ProgrammersManual.html#iterating-over-predecessors-successors-of-blocks.
Thanks!
First it's important to address the difference between your approach and the one in the example you're referencing.
In the example, they're define an instance of the pred_iterator type, rather than the PredIterator class you've used, which is defined as
typedef PredIterator<BasicBlock, Value::user_iterator> pred_iterator
and then using the calling pred_begin which returns an instance of pred_iterator(BB) where BB is the basic block you pass.
In your case, you're creating an instance of the PredIterator class and assigning it to the BB pointer, then attempting to dereference upon which it hits this assert:
inline reference operator*() const {
assert(!It.atEnd() && "pred_iterator out of range!");
return cast<TerminatorInst>(*It)->getParent();
}
As an initial solution it might be helpful to try and completely mimic the method used by the example, and then if you still need to use your method, try and diagnose the problem by observing how the typing for PredIterator is defined.
I've been looking though the svn history, Since LLVM 3.5, CFG.h has been moved from include/llvm/Support to include/llvm/IR. So you may want to use the following
#include "llvm/IR/CFG.h"
instead of
#include "llvm/Support/CFG.h"

How to convert void* to foo* to comply with C++?

I am trying to compile a code written in C (ndpiReader.c program that comes with nDPI library, hosted here). I'm using Qt Creator and GCC compiler.
After doing some research here and here, I notice that compiling C code with C++ compiler is not the best idea. But I didn't get the answer of how to do this conversion and make this code C++ compatible.
When I try to run the code in Qt Creator I get the error bellow:
error: invalid conversion from 'void*' to 'ndpi_flow_struct*' [-fpermissive]
if((newflow->ndpi_flow = malloc_wrapper(size_flow_struct)) == NULL) {
^
If more info is needed to solve the problem please leave a comment. I'm new to C++ so detailed answers with links are so much appreciated.
Edit: here is malloc_wrapper() function's code
static void *malloc_wrapper(unsigned long size) {
current_ndpi_memory += size;
if(current_ndpi_memory > max_ndpi_memory)
max_ndpi_memory = current_ndpi_memory;
return malloc(size);
}
You're seeing this error because in c++, types should have an exact match.
As we can see, the malloc_wrapper() function returns a void * and your newflow->ndpi_flow is of type ndpi_flow_struct*. So while compiling using c++ compiler, you've to add the cast, like
if((newflow->ndpi_flow=(ndpi_flow_struct*)malloc_wrapper(size_flow_struct)) == NULL) { . . .
to force the compiler in believing that the return value of malloc_wrapper() is of type (ndpi_flow_struct*).
or even better, the static cast<> (keeping in mind the C++ aspect), like
if(( newflow->ndpi_flow =
static_cast<ndpi_flow_struct*>malloc_wrapper(size_flow_struct)) == NULL) { . . .
Related Reading: A detailed answer on C++ Casting.
Usually, we just write
if((newflow->ndpi_flow = (ndpi_flow_struct*)malloc_wrapper(size_flow_struct)) == NULL) {

Random segmentation faults?

Note, problem has been identified, refer to second section for current detail and the third section for the most likely reason and a question on how to remedy it
I'm writing a program in Qt and I stopped a couple days ago at a segmentation fault problem. It seemed to complain about memory not being allocated. I searched around and couldn't figure out why there was an allocation problem and I took a break. Now, looking at it again, the segmentation fault is still there, but it's in a completely different, mostly unrelated function. What could be causing these random segmentation faults?
For some concreteness, in this case, I am currently getting a segmentation fault here:
Q_DECL_CONSTEXPR inline int QSize::height() const
{ return ht; }
I was getting it here before I commented out the lines (the last three lines)
qDebug() << QString("---SETTINGS DEBUG---")+QString("\r\n")<<
"netProcPage: "+netProcPage.url()+"\r\n" <<
"mapSize.width(): "+QString::number(mapSize.width())+"\r\n"<<
"mapSize.height(): "+QString::number(mapSize.height())+"\r\n"<<
"mapZoom: "+QString::number(mapZoom)+"\r\n"<<
"mappxSize.width(): "+QString::number(mappxSize.width())+"\r\n"<<
"mappxSize.height(): "+QString::number(mappxSize.height())+"\r\n"<<
"UserCoords[0]: "+QString::number(UserCoords[0])+"\r\n"<<
"UserCoords[1]: "+QString::number(UserCoords[1])+"\r\n"<<
"mapCoordOffsets[0]: "+QString::number(mapCoordOffsets[0])+"\r\n"<<
"mapCoordOffsets[1]: "+QString::number(mapCoordOffsets[1])+"\r\n"<<
"getWindowSize.width(): "+QString::number(getWindowSize.width())+"\r\n"<<
"getWindowSize.height(): "+QString::number(getWindowSize.height())+"\r\n"<<
"mappxOffsets[0]: "+QString::number(mappxOffsets[0])+"\r\n"<<
"mappxOffsets[1]: "+QString::number(mappxOffsets[1])+"\r\n"<<
QString("---END SETTINGS DEBUG---")+QString("\r\n");
Before then, without changing anything (just waiting a couple days and a couple restarts later), it was here:
mkeMap.genMap(QString("Map1"), tempmapSize, tempmapZoom, mapDisp->ui);
In the MainWindow class constructor complaining about tempmapSize, which is defined by:
QSize tempmapSize;
tempmapSize = settings->mapSize; //<--- The error might be coming from here, is there an alternative?
which is where the segmentation faults have been associated with. This is the settings class:
#include "settings.h"
Settings::Settings(QWidget *parent)
{
netProcPage = "http://localhost:81";
// Max image size is 32767x32767 pixels (divided by 4*mapZoom since 4 panes are used at mapZoom zoom)
// If max mapZoom is 20, max size of map is 409x409, or 408x408 to keep it even
mapSize.setWidth(250);
mapSize.setHeight(250);
mapZoom = 10;
mappxSize.setWidth(mapSize.width()*mapZoom);
mappxSize.setHeight(mapSize.height()*mapZoom);
//downloadMap(netProcPage,"getMap","Username","Password");
//makeMap("bingbong",mapSize,mapZoom);
UserCoords[0] = 0;
UserCoords[1] = 0;
mapCoordOffsets[0] = UserCoords[0] + .5 * mapSize.width();
mapCoordOffsets[1] = UserCoords[1] + .5 * mapSize.height();
//getWindowSize.setWidth(parent->width());
//getWindowSize.setHeight(parent->height());
getWindowSize.setWidth(500);
getWindowSize.setHeight(500);
mappxOffsets[0] = UserCoords[0]*mapZoom + .5 * getWindowSize.width() - .5 * mappxSize.width();
mappxOffsets[1] = UserCoords[1]*mapZoom + .5 * getWindowSize.height() - .5 * mappxSize.height();
}
void Settings::debug()
{
qDebug() << QString("---SETTINGS DEBUG---")+QString("\r\n")<<
"netProcPage: "+netProcPage.url()+"\r\n" <<
"mapSize.width(): "+QString::number(mapSize.width())+"\r\n"<<
"mapSize.height(): "+QString::number(mapSize.height())+"\r\n"<<
"mapZoom: "+QString::number(mapZoom)+"\r\n"<<
"mappxSize.width(): "+QString::number(mappxSize.width())+"\r\n"<<
"mappxSize.height(): "+QString::number(mappxSize.height())+"\r\n"<<
"UserCoords[0]: "+QString::number(UserCoords[0])+"\r\n"<<
"UserCoords[1]: "+QString::number(UserCoords[1])+"\r\n"<<
"mapCoordOffsets[0]: "+QString::number(mapCoordOffsets[0])+"\r\n"<<
"mapCoordOffsets[1]: "+QString::number(mapCoordOffsets[1])+"\r\n"<<
"getWindowSize.width(): "+QString::number(getWindowSize.width())+"\r\n"<<
"getWindowSize.height(): "+QString::number(getWindowSize.height())+"\r\n";//<<
//"mappxOffsets[0]: "+QString::number(mappxOffsets[0])+"\r\n"<<
//"mappxOffsets[1]: "+QString::number(mappxOffsets[1])+"\r\n"<<
//QString("---END SETTINGS DEBUG---")+QString("\r\n");
}
QSize* Settings::getmapSize()
{
return &mapSize;
}
int Settings::getmapZoom()
{
return mapZoom;
}
---
Here's the problem (identified)
I've refactored the code as suggested and I have pinpointed the exact problem, but I don't know how to fix it.
void makeMap::genMap(QString name, QPointF* inSize, int* zoom, Ui::MapDisp* ui)
{
QVector<QString> mapvector;
QPointF mapSize = *inSize; // <--- The problem is right here
...
}
The problem occurs when dereferencing the QPointF object found in an earlier instance of Settings, which was sent to genMap(...).
The call was done like this:
QPointF* tempmapSize;
tempmapSize = settings->getmapSize();
int* tempmapZoom = settings->getmapZoom();
mkeMap.genMap(QString("Map1"), tempmapSize, tempmapZoom, mapDisp->ui);
Wherever I moved the dereference (*Settings::inSize*, or *inSize), that's where the error occurred (in the debugger). Everything has been compiling fine.
When running the program, it crashes with this error:
Starting C:\program-debug.exe...
ASSERT failure in QVector<T>::operator[]: "index out of range", file ../../../../../Qt/5.2.0/mingw48_32/include/QtCore/qvector.h, line 369
Invalid parameter passed to C runtime function.
Invalid parameter passed to C runtime function.
C:\program-debug.exe exited with code 3
This reference to QVector<T> is referring to later in genMap,
void makeMap::genMap(QString name, QPointF* inSize, int* zoom, Ui::MapDisp* ui)
{
QVector<QString> mapvector;
QPointF mapSize = *inSize; //<---Here's the segmentation fault
/* Using this instead of the above works, as well as replacing zoom which causes another segmentation fault when dereferenced
QPointF mapSize;
mapSize.setX(250);
mapSize.setY(250);
int zoom0 = 10;
*/
QFile file(name+"_"+QString::number(mapSize.x())+"x"+QString::number(mapSize.y())+".rtsmap");
file.open(QIODevice::WriteOnly | QIODevice::Text);
QTextStream out(&file);
mapvector.resize(mapSize.x() * mapSize.y());
for(int x = 0; x < mapSize.x(); x++){
for(int y = 0; y < mapSize.y(); y++){
uint decimalcolor = (((qSin(x)+1) + (qSin(y)+1))/4)>1?16777215:(((qSin(x)+1) + (qSin(y)+1))/4)*16777214;
QString hexadecimalcolor;
hexadecimalcolor.setNum(decimalcolor,16);
mapvector[index(x, y, mapSize)] = "#" + hexadecimalcolor;
//drawRect(x*10,y*10,10,10,"#"+hexadecimalcolor,zoom);
out << "#" << hexadecimalcolor+'\n';
}
}
file.close();
drawMap(mapvector,zoom0,ui,mapSize);
}
In Short
I think the problem is a dangling pointer. More specifically, when I pass the settings pointer to the class constructor, here:
MapCtrl::MapCtrl(QWidget *parent, Settings *settingsIn) :
QWidget(parent),
ui(new Ui::MapCtrl)
{
ui->setupUi(this);
mapDisp = new MapDisp(parent, settingsIn);
addMap();
settings = settingsIn;
}
The pointer settingsIn probably gets deleted at the end of the constructor with settings still pointing there, so later when I dereference a value from settings, it doesn't exist, causing a segmentation fault. So, the question is, how do I prevent the pointer called settingsIn from getting deleted at the end of the constructor?
requested code
Here's where the MapCtrl construtor MapCtrl::MapCtrl gets invoked and Settings is instantiated:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
wScr = new WelcomeScreen(this);
Settings *settings = new Settings(this);
mapCtrl = new MapCtrl(parent,settings);
...
}
solution (thanks to Kuba Ober for the guidance and the plethora of useful C++ knowledge)
In addition to checking for dangling pointers and fixing some possible causes, the final step was to change this:
MapCtrl::MapCtrl(QWidget *parent, Settings *settingsIn) :
QWidget(parent),
ui(new Ui::MapCtrl)
{
ui->setupUi(this);
mapDisp = new MapDisp(parent, settingsIn);
addMap();
qDebug() << "bingbong!!" << settingsIn->mapSize.x();
settings = settingsIn;
}
to this:
MapCtrl::MapCtrl(QWidget *parent, Settings *settingsIn) :
QWidget(parent),
ui(new Ui::MapCtrl)
{
ui->setupUi(this);
mapDisp = new MapDisp(parent, settingsIn);
qDebug() << "bingbong!!" << settingsIn->mapSize.x();
settings = settingsIn;
addMap();
}
settings was being set after a function that needed settings to be set.
In your entire codebase:
Get rid of places where you return Qt containers (QSize, QList, etc.) by pointer, and replace them with returning them by value.
Declare accessor methods const.
E.g. change Settings::getmapSize() to the below, idiomatic, code:
QSize Settings::getmapSize() const
{
return mapSize;
}
Use QPointF for coordinates, instead of naked arrays. Pass those into methods/functions by either value or const reference; the former may actually work a tad faster on modern hardware and compilers.
E.g. change the code in the constructor to be like this:
mapCoordOffsets = UserCoords + (toPoint(mapSize) * .5);
Where
static QPointF toPoint(const QSize & size) {
return QPointF(size.width(), size.height());
}
Get rid of the C-style output parameters, like in
void makeMap::genMap(..., QPointF* inSize, int* zoom, ...)
If you're returning something, simply return a structure that's called, say MapParams or somesuch:
MapParams makeMap::genMap(...);
If you're taking a structure and potentially modifying it, just modify it and return the modified one:
MapParams makeMap::genMap(..., MapParams params) {
...
params.size = ...;
params.zoom = ...;
...
return params;
}
My worry is that somewhere you're passing a bogus pointer or otherwise a pointer is obfuscating a lifetime issue. Naked pointers in modern C++ are highly suspect, and your code seems to use a lot of them for no good reason at all. Output parameters implemented with pointers are C-ism that has no place in modern C++.
Another common bug could be this: you have a Settings * settings member in the MainWindow class. Then you happily create a Settings * local variable in MainWindow constructor, but the MainWindow::settings member remains uninitialized. That's why you should always prepend member names with m_, so that they are harder to confuse with local variables. Ideally, you should use initializer lists to initialize members in a constructor.
When doing debugging, when you see an assert about out-of-bounds access, you need to debug its cause. A debugger should stop on such an assert, if not then you've got something misconfigured (what's your exact platform and toolset?). Whatever happens afterwards is meaningless if it was a write access, as memory has been overwritten, and you're chasing squirrels at this point.
Doing those things cuts down a whole bunch of errors that you've possibly made in your code. It may not fix your problem, but will get you on a good trajectory towards the solution.

Cuda Thrust String or Char Sort

I am trying to sort string with cuda thrust .
I found a sample on this link
https://github.com/bzip2-cuda/bzip2-cuda/blob/master/tst/string_sort_try0.cu
when i try to compile i get the following error message. What can I do to fix it?
"Error 1 error : **no instance of overloaded function "thrust::pointer<Element, Tag, Reference, Derived>::operator= [with Element=char, Tag=thrust::device_system_tag, Reference=thrust::device_reference<char>, Derived=thrust::device_ptr<char>]" matches the argument list** C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.5\include\thrust\device_ptr.h 109 1 CharSort "
a part of code block is
class device_string
{
public:
int cstr_len;
char* raw;
thrust::device_ptr<char> cstr;
static char* pool_raw;
static thrust::device_ptr<char> pool_cstr;
static thrust::device_ptr<char> pool_top;
// Sets the variables up the first time its used.
__host__ static void init()
{
static bool v = true;
if( v )
{
v = false;
pool_cstr = thrust::device_malloc(POOL_SZ);
pool_raw = (char*)raw_pointer_cast( pool_cstr );
pool_top = pool_cstr;
}
}
// Destructor for device variables used.
You can work around that particular issue by changing this line of code:
pool_cstr = thrust::device_malloc(POOL_SZ);
to this:
pool_cstr = thrust::device_malloc<char>(POOL_SZ);
But as #Eric indicates, once you fix that you will run into other issues trying to compile this code.
EDIT: Actually the remaining problems appear to be all warnings, and an executable is produced which seems to run correctly (with the above fix).

Problem with GtkTextBuffer , Confusing Runtime Error. Need Help?

I am using this code:
class editbook
{
GtkWidget* _nbook;
std::vector<GtkWidget*> _srcset; //and so on...
...........................................................................................
void editbook::add_page()
{
GtkWidget* tmp = gtk_source_view_new();
_srcset.push_back(tmp);
gtk_notebook_append_page(GTK_NOTEBOOK(_nbook),tmp,gtk_label_new("untitled"));
}
...........................................................................................
void editbook::set_text(const std::string& text)
{
int index = gtk_notebook_get_current_page(GTK_NOTEBOOK(_nbook));
GtkTextBuffer* tbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(_srcset[index]));
gtk_text_buffer_set_text(GTK_TEXT_BUFFER(tbuffer),text.c_str(),-1);
}
Compiles fine. But gives this weird runtime error:
Segementation Fault: return 139
I have traced down the problem to: gtk_text_view_get_buffer(GTK_TEXT_VIEW(_srcset[index]));
NOTE: I am using GtkSourceView instead of GtkTextView, but that may not be a problem because I am gettin the same error when I try GtkTextView.
NOTE: I am using Gtk 2x
NOTE: I am not sure whether to tag this question with C or C++. bec. Gtk+ is a C lib. But I am using C++. So I'll just tag both for now.
The problem in your code could be that the child widget added to GtkNotebook through gtk_notebook_append_page is not visible, try showing the child widget through gtk_widget_show call. Something on these lines :
void editbook::add_page()
{
GtkWidget* tmp = gtk_source_view_new();
_srcset.push_back(tmp);
gtk_widget_show(tmp); //Show the child widget to make it visible
gtk_notebook_append_page(GTK_NOTEBOOK(_nbook),tmp,gtk_label_new("untitled"));
}
When you use gtk_notebook_get_current_page if none of the child widget are visible then it returns -1, which I think might be happening in your case & as index is -1 when you use operator[] which doesn't check for bounds the program crashes. I strongly suggest you use vector::at instead of using operator[] so that you get std::out_of_range exception during run time to indicate the problem. You could use:
void editbook::set_text(const std::string& text)
{
int index = gtk_notebook_get_current_page(GTK_NOTEBOOK(_nbook));
GtkTextBuffer* tbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(_srcset.at(index)));
gtk_text_buffer_set_text(GTK_TEXT_BUFFER(tbuffer),text.c_str(),-1);
}
Hope this helps!