I am using Qt 4.8. Is there any way to have a global try and catch block for whole project. Example, if my application has two .cpp files. Is it possible way to catch exception across both .cpp files?
First of all, be warned that Qt doesn't play nice with exceptions. It was designed back in those days when exceptions were rather obscure feature of C++ so the use of exceptions was not generally considered a good practice for a whole bunch of implementation-related reasons.
Also be warned that as of Qt 5.7 the exception safety is not feature complete as the official doc currently tells:
Preliminary warning: Exception safety is not feature complete! Common cases should work, but classes might still leak or even crash.
If you use signal-slot connections within your classes, it's best to handle exceptions inside the slots which may throw them. As of Qt 5.7 not doing so is considered undefined behaviour.
If you just want to do some cleanup and/or error logging on any occasionally uncaught exception, you can either wrap the entire main() contents into try/catch block as the previous answer suggests or alternatively you can wrap the Qt's main event loop into such a block:
QApplication app(argc, argv);
...
try {
app.exec();
}
catch (const std::exception &) {
// clean up here, e.g. save the session
// and close all config files.
return 0; // exit the application
}
You can put in brackets the entire contents of your main() function as follows::
int main(int argc, char *argv[])
{
int ret = 0;
try
{
QApplication a(argc, argv);
QWidget w;
w.show();
ret = a.exec();
}
catch(...)
{
/* ... */
}
return ret;
}
See also: std::set_terminate()
Related
Let's say we have the following code:
#include <exception>
void funcA() {
funcB();
}
void funcB() {
funcC();
}
void funcC() {
funcD();
}
void funcD() {
throw std::runtime_error("Exception!!"); //3
}
void funcE() {
int * p;
delete p; //4
}
int main (int argc, char **argv) {
try {
funcA(); //1
} catch (std::exception exc) {
std::cerr << exc.what() << endl; //2
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
I want to print the stack trace with the line number of the thrown exception in a multi-threaded efficient way.
I've been checking the last couple of days the solutions and approaches people are doing but unfortunately nothing was useful in my case. I can use for example the boost library boost::stacktrace::stacktrace() in //2 or any other library but the problem here is I have to catch the exception to do this and this approach is not efficient if your code has hundreds of nested functions. You can't just go over all of them and wrap each one with try-catch and handle them separately.
So basically what I need to do is if an exception is thrown at //3 I should be able to print the stack trace of the exception in `//2
I'm aware of the stack unwinding and how it works, but as far as I understand whenever your code reaches the catch block this means that the exception stack has been unwinded and you can't get it. Please correct me if I'm wrong!
Is there a way at least to add something similar to middleware before unwinding the exception stack? Or do I have to do it manually?
Edit:
Also, what would happen when I can funcE() is a memory access exception but this exception is never caught. Is there a way to catch such kind of exceptions or at least print its stack trace before the crash?
Note:
I'm running my code on Linux and macOS, C++11 with Silicon web framework.
It's a big system so I'm trying to achieve some logging mechanism that can be used across the system.
I'm posting this in case anyone came across the same question and wanted a quick useful answer.
I've ended up overriding the main C++ throw exception behavior using this gist
I've changed a few things in the __cxa_throw function to tackle my own issue and used boost::stacktrace to get a more human-readable stack trace.
I want to write log files. My application could be run on Linux and Windows. I've pretty much figured out how to do it for the former, thanks to this example:
void SyslogMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
Q_UNUSED(context)
QByteArray localMsg = msg.toLocal8Bit();
switch (type)
{
case QtDebugMsg:
#ifdef __linux__
syslog(LOG_DEBUG, "Message (debug): %s", localMsg.constData());
#elif _WIN32
// WRITE INTO FILE
#else
#endif
break;
// etc.
}
}
int main()
{
// Install our message handler.
qInstallMessageHandler(SyslogMessageHandler);
// Send some messages, which should go to syslog.
qDebug("Debug log message from Qt test program");
}
source (2nd example)
However, I am wondering what would be the fastest way for Windows? Is using QFile or QTextStream an efficient way for writing this kind of information?
I was thinking about storing everything in a simple QString and then put everything in a file when the app closes or crashes (in the latter case, is that possible?).
Long Story short, OpenGL beginner/dabbler, Using GLFW for self study purpose.
I downloaded GLFW precompiled binaries from here
and I followed this tutorial (I know its for VS2010 specific but still)
I have read numerous questions on linker errors for VS2012 + GLFW 3.x set up.
None of them solved my problem.
Here is what I have in my code so far.
#define GLFW_DLL
#include <glfw3.h>
#pragma comment(lib,"glfw3.lib")
#pragma comment(lib,"glfw3dll.lib")
#pragma comment(lib,"opengl32.lib")
int main(int argc,char** argv)
{
GLFWwindow* window;
/* Initialize the library */
if (!glfwInit())
return -1;
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
/* Render here */
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
glfwTerminate();
return 0;
}
Here is what I have in my
VC include directory.
VC lib directory
VC linker input options
System32 DLL
Compilation is successful. However, I get
Why, what is wrong with this set up?
UPDATE::
I tried placing all the files (dlls, lib and headers) in the project folder, still no results,
I still get the same error message.
The easiest solution would be to use the static library rather than the dll, thus removing the need for the dll.
To do this you need to remove the define for GLFW_DLL so you file reads:
#include <glfw3.h>
main() // code follows
And you need to remove the glfw3dll.lib from the additional dependencies but leave glfw3.lib and opengl32.lib.
Is it possible to set a custom allocator for OpenCV 2.3.1? I have a memory pool created and I want OpenCV to use that pool for what it needs.
Is that possible?
If it is, how can it be done?
Updated:
I made some developments since last answer, but I still have some problems.
This is the code I have now:
CvAllocFunc allocCV()
{
return (CvAllocFunc) MEMPOOL->POOLalloc(sz);
}
CvFreeFunc deallocCV()
{
return (CvFreeFunc) MEMPOOL->POOLfree(ptr);
}
...
cvSetMemoryManager(allocCV(),deallocCV(),data);
Now, my question is, how can I have access to the size and the pointer to the data I want to allocate and later to deallocate?
Just found out:
The version of OpenCV I'm using (2.3.1) throws an error when using cvSetMemoryManager. The reason is in its source code:
void cvSetMemoryManager( CvAllocFunc, CvFreeFunc, void * )
{
CV_Error( -1, "Custom memory allocator is not supported" );
}
I was very disappointed with this. I guess I can't use a custom memory pool with OpenCV anymore!
Right from the docs
http://opencv.willowgarage.com/documentation/c/core_utility_and_system_functions_and_macros.html#setmemorymanager
Use the
void cvSetMemoryManager(CvAllocFunc allocFunc=NULL, CvFreeFunc freeFunc=NULL, void* userdata=NULL)
function.
Your code
cvSetMemoryManager(allocCV(),deallocCV(),data);
is WRONG.
See what happens: you call allocCV and deallocCV functions (they return some pointer which is quietly converted to cvAllocFunc) !
And this is only the beginning. See the docs for alloc/dealloc semantics. You should write allocCV/deallocCV with correct signatures.
void* CV_CDECL allocCV(size_t size, void* userdata)
{
return ((YourMemPoolTypeWhichIDoNotKnow*)userdata)->POOLalloc(size);
}
int CV_CDECL deallocCV(void* pptr, void* userdata)
{
return ((YourMemPoolTypeWhichIDoNotKnow*)userdata)->POOLfree(pptr);
}
and then pass your MEMPOOL in the 'userdata' parameter:
cvSetMemoryManager(&allocCV, &deallocCV, (void*)MEMPOOL);
This is a standard way for a library to provide user callbacks.
I need a event handler when ever shutdown message is send to system.
Can anyone help?
When ever we try to shutdown a system, and if any dialog box is open shutdown process terminates. I don't want this to happen in my application. i.e if any dialog box is open from my application and I try to shutdown my system then it should not block shutdown process. Is this implementation possible?
Thanks,
Rahul
Yes, look at NSWorkspaceWillPowerOffNotification
http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Reference/ApplicationKit/Classes/NSWorkspace_Class/Reference/Reference.html
try overriding QApplication::commitData it should be called whenever user shuts down the system and your application is still running.
This function deals with session
management. It is invoked when the
QSessionManager wants the application
to commit all its data.
Usually this means saving all open
files, after getting permission from
the user. Furthermore you may want to
provide a means by which the user can
cancel the shutdown.
below is an example (never tried it with macs; though works fine on my ubuntu):
main.cpp:
#include <QtGui/QApplication>
#include "mainwindow.h"
#include <QSessionManager>
class MyApplication : public QApplication
{
public:
MyApplication(int &argc, char **argv);
virtual void commitData(QSessionManager& sm);
};
MyApplication::MyApplication(int &argc, char **argv):
QApplication(argc, argv)
{
//???
}
void MyApplication::commitData(QSessionManager& sm)
{
// do smth here....
QApplication::commitData(sm);
}
int main(int argc, char *argv[])
{
MyApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
hope this helps, regards