How can I find out what causes undefined behaviour in my program? - c++

My Qt application consists of four screens that can be switched. These screens are added to a QStackedLayout Class with addWidget(). The switching between screens happens with setCurrentWidget().
Adding some variables in the header file in one of the screens(/classes) always causes the program to crash. Debugging gives me a segfault at adwidget() where I try to add that screen to the Layout.
Now if I clean all before the build it always works. Also if just change something in the header file of some other class (can be any header file) and I rebuild only that one header file it works aswell.
It only happens with that one screen(/class). It doesn't matter what type of variable I add. Doesn't matter if they are public or private. The class is almost identical with others that work without any problem. When I compile I get no warnings or errors. It just crashes at addwidget().
Is there any way to find out whats going on?
edit:
This is the result of valgrind memcheck:
Line 18 in compassdebugscreen.cpp is: QString const strCalib3DStartBtn = "Start Calib 3D";
Line 14 in main.cpp is: QApplication a(argc, argv)

Related

SFML : drawing from different files

I'm working on a SFML project that contains several different files and classes. The problem is : in every file, there is some drawing, and the sf::RenderWindow* defined in the main file seems to be out of scope here, therefore I can't link these drawing with the main window. I've tried to redefine sf::RenderWindow in every header files, and it doesn't work as well (a black screen appear and disappear promptly). The error was : Access violation reading location. But when I group everything in one file, things work well but it looks really messy.
I also found this question asked on another forum, and the answers were "using reference and external method", which is a bit vague to me. Any help on this linking problem would be appreciated :(
I think that answer meant something like:
void draw_in_class (sf::RenderWindow* window){
window->draw(...);
}
in class, and then you can use 'draw_in_class' in main:
#include"class.h"
... // Define sf::RenderWindow here
draw_in_class(&window);

c++ .cpp file not found error page during breakpoint debugging

My code compiles and runs without any error messages, however I commented out a line (and it still runs with no errors) but the code executed as if the line was not commented out.
I set a breakpoint and tried to step into the function where the problem seemed to be, but when I tried to step in I was instead sent to this screen
If I press the "Browse and find button.cpp", then I am immediately shown this message
If I press "yes" then it shows me the correct file, with the line commented out, but then proceeds to execute the commented out line as if it was not commented out at all.
Pressing "no" closes the box, however selecting the correct .cpp file just opens it up again.
I've made sure the file is saved, and restarted visual studio, and the problem persists.
Here is the surrounding code:
The function that brings me to this page
vector<GameObject*> gameObjects;
for each (auto object in gameObjects)
{
object->Render();
}
Button is a templated class and inherits from PhysicsObject which inherits from GameObject
Render() is a virtual method of object and PhysicsObject
The code that should not be executed but is
template<class T>
void Button<T>::Render()
{
//PhysicsObject::Render();
}
I've never seen any error like this before and it only seems to tell me it's a problem when I step through the code with a breakpoint.
I have no idea how to even search for this kind of error message and I have no idea what it means or what caused it.
I did not edit my code during execution and I didn't change anything about the structure of my project, this was working before.

What could be the cause for runtime "can't find linker symbol for virtual table..." error in Qt?

This question was asked in similar ways multiple times, for example at stackoverflow or forum.qt.io or qtcentre.org. The problem is that this error message is so vague that one solution cannot be applied to another scenario. Most of the threads are dead in the middle of the discussion though :-(
So the complete error message that I get in my Qt application is:
can't find linker symbol for virtual table for "OneOfMyClasses" value
found "QString::shared_null" instead
The OneOfMyClasses changes depending on various things, the QString::shared_null stays the same for all errors that I get. Here is a screenshot of my logging console:
Why is the font color pink, so who is printing this message?
Why do I only see this message when I set a breakpoint and step through my code? This message does not appear when simply running the application.
The point where it happens is in this function in the source line right before the current position (yellow arrow):
So according to the message I stepped into m_pStateWidget->insertNavLabel(...) and the error message is printed somewhere in the constructors inside Qt related to the QString class. So I tried the following, which moves the problem away from this code location:
When doing this I get the same error message a few code lines below with another class name in the message, note that the QString::shared_null stays the same.
It appears to me that I have some sort of corrupted memory.
How should I start investigating this issue? I'm afraid to change the code because this might hide the problem as described above.
What's up with the QString::shared_null? I have found that others often see the same in their error messages.
Thank you for any hint or help! :-)
Edit: It's becoming really interesting now. I have stepped into every single function just right before the message is printed and I ended up with these error messages:
at this location:
When I navigate through the call stack in QtCreator the error is printed again and again everytime I select another function in the stack.
Does this mean that the debugger is printing the message and that it is simply too stupid to resolve some sort of vtable stuff for me or does this mean that I have serious trouble going on?
Cause:
Somewhere in your code , you might have overrun the actual memory
Example 1 :
int elmArray[10];
for(int i = 0; i < 20; ++i)
{
elmArray[i] = 0;
}
In the above case, actual array size is 10 but we are assigning values to the index beyond 10.
Example 2:
char* cpyString;
strcpy(cpyString , "TEST");
These scenarios might end up in writing the values into other objects. Mostly could corrupt the virtual table.This gives the above warning.
Fix:
As you know, just correct the code as below.
Example :
int elmArray[10];
for(int i = 0; i < 10; ++i)
{
elmArray[i] = 0;
}
char cpyString[10];
strcpy(cpyString , "TEST");
In your case seems like, you are assigning the QTString::shared_null to some uninitialized string.
There are various threads on different websites where the
can not find linker symbol for virtual table
problem is discussed. Few explain why the problem exists, although some solutions are given to specific examples. Having experienced difficulty with this, I would like to share what I have learned.
First this error message only appeared for Linux builds, it did not show up for Windows builds.
In my case the problem was caused by a second call into a non-reentrant method from the same thread. Once I found the problem, it was easy to fix by using a static busy flag, and simply returning when busy was called a second time. In a nutshell that was the problem and solution. But how did I get into this mess?
Well the non-rentrant method was actually a Qt slot. Since I knew there was a possibility of the second call (actually an emit) being made from the first, the connect was set up with Qt::QueuedConnection. However, I later put up a splash screen QSplashScreen while the function was processing. Little did I realize that QSplashScreen::repaint() called QApplication::processEvents() which dispatched the second offending emit.
So I could have fixed the problem by removing the QSplashScreen and using a QLabel. However, while either works nicely in Windows, neither actually works in Linux, they put up a semi-transparent window and don't paint the contents (even repaint() and or processEvents() doesn't do it). So that is probably a Qt Linux bug, which is another story.

Qt QFileDialog::setDirectory funny behavior in Ubuntu 12.04

I have a class that inherits from QFileDialog. In the constructor, I call setDirectory and pass in the last directory visited (which the class keeps track of; see code below). On Windows, this works fine. And if I show the dialog multiple times, it is internally smart enough to resume at the last location (e.g. where the user saved a file before). This is the desired behavior.
On Ubuntu 12.04 (GCC 4.8 compiler), on the other hand, the system does not automatically resume where last left off if I call showFileDialog multiple times. So I tried adding the setDirectory call within that function as commented below, but that didn't change anything. Furthermore, if I take out setDirectory from the constructor so it is only called in showFileDialog, the file dialog opens to the folder from which the program was run. (i.e. setDirectory didn't work.) Subsequent calls to showFileDialog will open a file dialog starting in the directory requested.
So it seems like the call has a delayed effectiveness. Is this a Qt bug, or mine? Either way, how can I get the setDirectory call to be effective?
Example code:
QString FileDialog::defaultDir = QDir::homePath();
FileDialog::FileDialog(QWidget *parentWindow /*, ...*/)
: QFileDialog(parentWindow)
{
setDirectory(defaultDir);
//...
}
QString FileDialog::showFileDialog()
{
// Adding setDirectory(defaultDir) here doesn't help.
if(!exec())
{
return QString::null;
}
defaultDir = directory().path();
//...
}
It is not clear from the code above how you know that the path was changed. I'm not sure that directory() is responsible for that.
Consider using void QFileDialog::directoryEntered(const QString & directory) signal.
Workaround found:
I happen to set the dialog title (setWindowTitle()) every time I open a FileDialog. If I connect to the QFileDialog::windowTitleChanged signal and call setDirectory within the slot, it is effective.
This is an unintuitive workaround though, so I am open to better answers.

QtCreator build returns collect2: ld returned exit status 1

While building several different projects in QtCreator, I have run across the following build error:
collect2: ld returned 1 exit status
After only changing a few things (that should not change anything significant in the build), it will go away if it has already appeared, or it will appear if it's not there.
In my current program for a school project, I am trying to compile rock03.cpp. It's the only file in the build, and has the main() method. I had just run it successfully, and went back to change the order of some if()s, now, I get only two relevant warnings:
overriding commands for target 'rock03.o'
and
ignoring old commands for target 'rock03.o'
along with the error in question.
Does anyone know why this would happen? I cannot seem to reproduce the error with any reasonable certainty, and QtCreator is not complaining about any thing before I build.
Thanks
If the only message error is this one concerning linker, the reason can be that your program is still running and linker can not access to the binary file. Be sure your application was stopped or kill it if still running.
Qtcreator never checks if previous run was stopped before compiling.
This happens to me because I make a declaration in the header file, then delete the function in the cpp file and I forget to delete the decleration in the header. For example...
//header file
class CLASS : public Q_OBJECT
{
...
protected:
void mouseMoveEvent(QMouseEvent*);
}
//source file
void CLASS::mouseMoveEvent(QMouseEvent*e)
{
...
}
//I'll delete this, then forget to delete "void mouseMoveEvent(QMouseEvent*);" in the header file
The compiler output is really helpful if you're just getting this as an error, but the first candidate is probably that you've still got the output program open, and it can't write to the file, because that'll give you a solitary collect2 error like this
This error may also occur because of problems with linkage, for example, you forgot to declare some static variables from header file using 'extern' directive.
In my case, folder permissions were the problem. Checking the "Compile Output" window is crucial for finding out what exactly the problem is. (QtCreator is the opposite of Visual Studio in that regard, so it takes some getting used to.) I tried setting the permissions properly, but after that didn't seem to work, in the end I deactivated shadow build and then I went to "Tools/Options/Build&Run/General/Projects Directory" and set "Directory" to ".". Then it finally compiled. "It" being the kmap2qmap project in Qt 5.11.
Just my 2 cents in case anyone might find them useful.
This happens when you do not close your main app (so the output executable is still running, but without any visible window). An example:
int main() {
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
This app ends fine when you close the main window, but this code
int main() {
QApplication a(argc, argv);
QDialog w;
w.exec();
return a.exec();
}
doesn't close the app when you close the dialog (at least for me).
A solution is to create always your main window and make sure you close it.
In my case it was declaring the clear virtual function.
void virtual Func(MouseEvent*); // Error.
void virtual Func(MouseEvent*) = 0; // Well!
There could be many more reasons for the error. But for me, on removing of unused SLOTS from the class the problem was solved.
I had the same problem. My resolution is - implement all virtual functions and all slots declarations.
Checking the "Compile Output" pane reveals that the .pro file was trying to link the same .cpp file twice.