Thursday, August 21, 2014

SIGSEGV horror in the Qt project.

Had some problems in our project the application kept crashing with SIGSEGV error. We did not get a chance to catch the problem in the debugger making it hard to find. Found a neat trick on the internet, it's possible to add a handler for signals that catch the SIGSEGV and can print the stacktrace:
http://stackoverflow.com/questions/77005/how-to-generate-a-stacktrace-when-my-gcc-c-app-crashes

#include <stdio.h>
#include <execinfo.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>


void handler(int sig) {
  void *array[10];
  size_t size;

  // get void*'s for all entries on the stack
  size = backtrace(array, 10);

  // print out all the frames to stderr
  fprintf(stderr, "Error: signal %d:\n", sig);
  backtrace_symbols_fd(array, size, STDERR_FILENO);
  exit(1);
}

void baz() {
 int *foo = (int*)-1; // make a bad pointer
  printf("%d\n", *foo);       // causes segfault
}

void bar() { baz(); }
void foo() { bar(); }


int main(int argc, char **argv) {
  signal(SIGSEGV, handler);   // install our handler
  foo(); // this will call foo, bar, and baz.  baz segfaults.
}

It's also possible to catch other signals:
http://qt-project.org/doc/qt-4.8/unix-signals.html

Saturday, August 09, 2014

Qt connect is complaining that it can't find slot in super class when connecting sub class

Got an runtime error in the Qt application we are building, were connecting a signal with a slot, but when running the app we got this error message in the console:
Object::connect: No such slot mgccis::web::SuperClassWebservice::onReadyRead() in ServiceInterface\SubClassWebservice.cpp:37

The connect code in the SubClassWebservice looked like this:

connect(httpPost_parameterData_.data(), SIGNAL(readyRead()), this, SLOT(onReadyRead()));

There was a slot in the subClassWebservice, took a google search session to find out the real problem, found this on Stackoverflow:
http://stackoverflow.com/questions/4322224/qt-slots-and-inheritance-why-is-my-program-trying-to-connect-to-the-parent-inst

I've forgot to add the Q_OBJECT in the class declaration of the sub class.

Thursday, July 31, 2014

Change color on SVG item in Qt

This is a neat trick that can be good to know, found the solution in StackOverflow:
http://stackoverflow.com/questions/15123544/change-the-color-of-an-svg-in-qt/15124080#15124080

If you have for example an arrow that needs to be in different colors at different times in a Qt application, it's possible to change the color of an SVG item instead of adding several SVG items with different colors. 

QColor weightOutreachSupportArrowHorisontalColor = getWeightOutreachSupportArrowHorisontalColor();
yAxisIndicator_ = QSharedPointer<QGraphicsSvgItem>(new QGraphicsSvgItem(":/Icon/Icon/Arrow_x_30_30.svg",0));
QGraphicsColorizeEffect* weightOutreachSupportArrowHorisontalColorEffect = new QGraphicsColorizeEffect();
weightOutreachSupportArrowHorisontalColorEffect->setColor(weightOutreachSupportArrowHorisontalColor);
yAxisIndicator_->setGraphicsEffect(weightOutreachSupportArrowHorisontalColorEffect);
yAxisIndicator_->setZValue(100);
yAxisIndicator_->rotate(90);
yAxisIndicator_->setVisible(false);

scene_->addItem(yAxisIndicator_.data());

Monday, July 28, 2014

How to in Qt *.Pro-file disable: warning: C4996: 'sscanf': This function or variable may be unsafe. Consider using sscanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

Got a compiler error when using sscanf in QT Creator:
warning: C4996: 'sscanf': This function or variable may be unsafe. Consider using sscanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

To make sure other warnings wont't disappear in the spam like messages caused by the c++ compiler, we wanted to disable the warning.

Tried to do add this at the top of the main.cpp file but got the same error:
#define _CRT_SECURE_NO_WARNINGS

Adding this in the *.PRO file did the trick:

#Removes: warning: C4996: 'sscanf': This function or variable may be unsafe. Consider using sscanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
win32:{
    DEFINES +=  _CRT_SECURE_NO_WARNINGS
}


Wednesday, July 02, 2014

JSON-RPC with Fiddler

Needed to do a HTTP POST with a JSON RPC payload. Searched the web and there where a good explanation on StackOverflow explaining how to send  JSON string with fiddler:
Is it possible to make JSON requests using Fiddler's Request Builder?

Put the information together and adding the request in Raw and do Execute:

POST /StatusV1 HTTP/1.1
Host: localhost:8080
Content-Type: application/json; charset=utf-8
Content-Length: 81

{"method": "confirmRigModeKeySwitched", "params": ["correctPassword!"], "id": 99}





Worked as a charm!

Wednesday, June 25, 2014

error LNK2019: unresolved external symbol. Problem with linker in C++ is starting to give me gray hair.

Got this error message in the linker when I switched the project from statically linked to dynamically linked in the .Pro file:

StatusFacade.obj : error LNK2019: unresolved external symbol "private: enum mgccis::status::dto::StatusRigMode::Status __thiscall mgccis::status::StatusFacade::RigModeStatusToDto(enum mgccis::status::RigModeReply::Status)" (?RigModeStatusToDto@StatusFacade@status@mgccis@@AAE?AW4Status@StatusRigMode@dto@23@W44RigModeReply@23@@Z) referenced in function "public: class QString __thiscall mgccis::status::StatusFacade::getStatus(void)" (?getStatus@StatusFacade@status@mgccis@@QAE?AVQString@@XZ)


I just uncommented this row:
#CONFIG += staticlib #Nessesary only when running unit tests :(

The solution was easy, I had forgotten to set the class name on the methods in the cpp file, an honest mistake to do:
mgccis::status::dto::StatusOverloadTest::Status OverloadTestStatusToDto(mgccis::status::OverloadTestReply::Status overloadTestStatus)

Should be:
mgccis::status::dto::StatusOverloadTest::Status StatusFacade::OverloadTestStatusToDto(mgccis::status::OverloadTestReply::Status overloadTestStatus)


Strange that the linker did not complain when I statically linked the project. :)

Saturday, May 17, 2014

Solved: Qt Segmentation fault on MainWindow show() on line: inline void show() { setVisible(true); }

Writing this down so I'll remember in the future.

The application worked in Qt Creator in Windows, but in Linux we received Segmentation Fault when trying to run the application in the debugger.

Looking at the stacktrace only showed that it crashed in SetVisible on the main window.

0 __strlen_sse2 strlen.S 99 0x7e9520
1 XSetCommand /usr/lib/libX11.so.6 0xdbbb9f
2 XSetWMProperties /usr/lib/libX11.so.6 0xdc0601
3 QWidgetPrivate::create_sys(unsigned long, bool, bool) /opt/qt-4.8.4/lib/libQtGui.so.4 0x110db5e
4 QWidget::create(unsigned long, bool, bool) /opt/qt-4.8.4/lib/libQtGui.so.4 0x10bc73c
5 QWidget::setVisible(bool) /opt/qt-4.8.4/lib/libQtGui.so.4 0x10c20e5
6 QWidget::show qwidget.h 494 0x804fd0c
7 mgccis::shell::MainApplication::InitializeInterface mainapplication.cpp 29 0x804facc
8 main main.cpp 25 0x804efb0



It stopped on the line below, it made no sense all objects where initialized:

#ifndef Q_WS_WINCE
    inline void show() { setVisible(true); }
#else
    void show();
#endif



After some googling of the subject I found this forum post that described a problem that can cause this error message, it's the signature on the MainApplication that can causes the problem:
http://www.qtcentre.org/archive/index.php/t-45135.html?s=ea17a4ab05c00533d49f938c1da47077


But our solutionwas the opposite from the resolution in the forum post. We have our own builder class that gets the arguments from the main method and that passes the argument to the MainApplication, so in our case the solution was to send the argc parameter as value instead of a reference:

So the Change was from:
explicit MainApplication(int &argc, char* argv[]);


To this:
explicit MainApplication(int argc, char** argv);


After the change the application can be debugged in Windows and Linux and the error message made sense, we sent a reference to a temporary instance of the argc to the MainWindow that used when window is shown.