Memory leak if VCL Exception object is thrown with Message - string

I find it hard to believe, but code that throws a VCL Exception somehow leaks memory.
Have created a MVE to convince myself that this is really happening.
So here's a basic C++ console application, using VCL, that just repeatedly throws the same exception and tries to catch it.
#include <vcl.h>
#include <windows.h>
#pragma hdrstop
#pragma argsused
#include <tchar.h>
#include <stdio.h>
int _tmain(int argc, _TCHAR* argv[])
{
while (true){
try {
throw Exception(L"This is my Exception Message");
} catch (const Exception & e) {
}
}
return 0;
}
When you run this code outside the debugger, it leaks like a seave.
If you run this code under the debugger, it leaks at a slower rate.
If you instead pass an integer (i.e. throw Exception(42)), there is still a leak.
At this point I was hoping to avoid the complicated dance that UnicodeString performs.
The question is: why does this leak?
Have I missed something or am I using Exception the wrong way?
Found this to happen at least with XE7.
With XE11, the leak only occurs if the exception is thrown from a subroutine.
(these are the only versions available to me).
We have the JCL library installed, if that's a factor.

In my experience, exceptions often lead to destructors not being called for local variables (even for non-VCL classes). In this case, it seems destructor isn't even called for Exception class itself.
Possible solution is to update C++ Builder and stop using the classic compiler (Project Options -> C++ Compiler).
The exact memory leak in your question is reported fixed in version 10.3.0 (RSP-11916), and reported broken again (still open) in version 10.3.2 (RSP-27271). Another report says this only occurs in modern versions when optimizations are not enabled (RSP-30118).

Related

C++11: Clang on Mac doesn't catch exception thrown by std::thread function?

I've got a very simple program as:
#include <iostream>
#include <string>
#include <thread>
using namespace std;
struct N{
string s;
N(){}
~N(){cout<<"N dtor"<<endl;}
};
void f(){
N n;
throw 0;
}
int main(){
try{
thread a(f), b(f);
a.join();
b.join();
}catch(exception& e){
cout<<e.what()<<endl;
}
return 0;
}
On my mac+clang environment, the running result is:
libc++abi.dylib: terminating with uncaught exception of type int
Abort trap: 6
It doesn't print the "N dtor" as I expected. So my question, if std::thread function throws an exception, how to catch/deal with it? There's no guarantee that the code inside a thread function doesn't throw any exception.
I tried it on linux, and the exception could be caught and print:
Enable multithreading to use std::thread: Operation not permitted
Thanks a lot.
If an exception is thrown in a thread, it must be caught in the same thread (or not at all). In your example, the try block can catch exceptions specifically from the attempts to create or join the threads, but not exceptions caused by code running in the threads.
And if you think about it, this is how it has to be. Your example tries to ensure that you don't leave the try block until the threads have completed, but that's not something that can generally be guaranteed. Even in your example, if the join calls tried to throw exceptions that originated in the target thread (they don't, but for the sake of argument...), you'd never reach the join(b) call and nothing would guarantee that you're still in the try block when b's thread throws its exception.
The flow control for one thread to catch another's exception simply doesn't work. If you need this kind of functionality, you could put an exception handler in the worker thread and have it communicate exception state back to the master thread using established inter-thread communication mechanisms.

VC++ native mutex heap corruption

I have a native c++ library that gets used by a managed C++ application. The native library is compiled with no CLR support and the managed C++ application with it (/CLR compiler option).
When I use a std::mutex in the native library I get a heap corruption when the owning native class is deleted. The use of mutex.h is blocked by managed C++ so I'm guessing that could be part of the reason.
The minimal native class that demonstrates the issue is:
Header:
#pragma once
#include <stdio.h>
#ifndef __cplusplus_cli
#include <mutex>
#endif
namespace MyNamespace {
class SomeNativeLibrary
{
public:
SomeNativeLibrary();
~SomeNativeLibrary();
void DoSomething();
#ifndef __cplusplus_cli
std::mutex aMutex;
#endif
};
}
Implementation:
#include "SomeNativeLibrary.h"
namespace MyNamespace {
SomeNativeLibrary::SomeNativeLibrary()
{}
SomeNativeLibrary::~SomeNativeLibrary()
{}
void SomeNativeLibrary::DoSomething(){
printf("I did something.\n");
}
}
Managed C++ Console Application:
int main(array<System::String ^> ^args)
{
Console::WriteLine(L"Unit Test Console:");
MyNamespace::SomeNativeLibrary *someNativelib = new MyNamespace::SomeNativeLibrary();
someNativelib->DoSomething();
delete someNativelib;
getchar();
return 0;
}
The heap corruption debug error occurs when the attempt is made to delete the someNativeLib pointer.
Is there anything I can do to use a std::mutex safely in the native library or is there an alternative I could use? In my live code the mutex is used for is to ensure that only a single thread accesses a std::vector.
The solution was to use a CRITICAL_SECTION as the lock instead. It's actually more efficient than a mutex in my case anyway since the lock is only for threads in the same process.
Not sure were you reading your own post but there is a clue in your code:
#ifndef __cplusplus_cli
std::mutex aMutex;
#endif
Member 'aMutex' compiles only if compile condition '__cplusplus_cli' is undefined.
So the moment you included that header in Managed C++ it vanished from definition.
So your Native project and Managed project have mismatch in class definition for beginners == mostly ends in Access Violation if attempted to write to location beyond class memory (non existing member in CLI version if instantiated there).
Or just HEAP CORRUPTION in managed code to put it simply.
So what you have done is no go, ever!
But I was actually amazed that you managed to include native lib, and successfully compile both projects. I must ask how did you hack project properties to manage that. Or you just may have found yet another bug ;)
About question: for posterity
Yes CRITICAL_SECTION helps, Yes it's more faster from mutex since it is implemented in single process and some versions of it even in hardware (!). Also had plenty of changes since it's introduction and some nasty DEAD-LOCKS issues.
example: https://microsoft.public.win32.programmer.kernel.narkive.com/xS8sFPCG/criticalsection-deadlock-with-owningthread-of-zero
end up just killing entire OS. So lock only very small piece of code that actually only accesses the data, and exit locks immediately.
As replacement, you could just use plain "C" kernel mutex or events if not planning cross-platform support (Linux/iOS/Android/Win/MCU/...).
There is a ton of other replacements coming from Windows kernel.
// mutex
https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-createmutexw
HANDLE hMutex = CreateMutex(NULL, TRUE, _T("MutexName"));
NOTE: mutex name rules 'Global' vs 'Local'.
// or event
https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-createeventw
HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, _T("EventName"));
to either set, or clear/reset event state, just call SetEvent(hEvent), or ResetEvent(hEvent).
To wait for signal (set) again simply
int nret = WaitForSingleObject(hEvent, -1);
INFINITE define (-1) wait for infinity, a value which can be replaced with actual milliseconds timeout, and then return value could be evaluated against S_OK. If not S_OK it's most likely TIMEOUT.
There is a sea of synchronization functions/techniques depending on which you actually need to do !?:
https://learn.microsoft.com/en-us/windows/win32/sync/synchronization-functions
But use it with sanity check.
Since you might be just trying to fix wrong thing in the end, each solution depends on the actual problem. And the moment you think it's too complex know it's wrong solution, simplest solutions were always best, but always verify and validate.

Thread, ansi c signal and Qt

I'm writing a multithread plugin based application. I will not be the plugins author. So I would wish to avoid that the main application crashes cause of a segmentation fault in a plugin. Is it possible? Or the crash in the plugin definitely compromise also the main application status?
I wrote a sketch program using qt cause my "real" application is strongly based on qt library. Like you can see I forced the thread to crash calling the trimmed function on a not-allocated QString. The signal handler is correctly called but after the thread is forced to quit also the main application crashes. Did I do something wrong? or like I said before what I'm trying to do is not achievable?
Please note that in this simplified version of the program I avoided to use plugins but only thread. Introducing plugins will add a new critical level, I suppose. I want to go on step by step. And, overall, I want to understand if my target is feasible. Thanks a lot for any kind of help or suggestions everyone will try to give me.
#include <QString>
#include <QThread>
#include<csignal>
#include <QtGlobal>
#include <QtCore/QCoreApplication>
class MyThread : public QThread
{
public:
static void sigHand(int sig)
{
qDebug("Thread crashed");
QThread* th = QThread::currentThread();
th->exit(1);
}
MyThread(QObject * parent = 0)
:QThread(parent)
{
signal(SIGSEGV,sigHand);
}
~MyThread()
{
signal(SIGSEGV,SIG_DFL);
qDebug("Deleted thread, restored default signal handler");
}
void run()
{
QString* s;
s->trimmed();
qDebug("Should not reach this point");
}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
MyThread th(&a);
th.run();
while (th.isRunning());
qDebug("Thread died but main application still on");
return a.exec();
}
I'm currently working on the same issue and found this question via google.
There are several reasons your source is not working:
There is no new thread. The thread is only created, if you call QThread::start. Instead you call MyThread::run, which executes the run method in the main thread.
You call QThread::exit to stop the thread, which is not supposed to directly stop a thread, but sends a (qt) signal to the thread event loop, requesting it to stop. Since there is neither a thread nor an event loop, the function has no effect. Even if you had called QThread::start, it would not work, since writing a run method does not create a qt event loop. To be able to use exit with any QThread, you would need to call QThread::exec first.
However, QThread::exit is the wrong method anyways. To prevent the SIGSEGV, the thread must be called immediately, not after receiving the (qt) signal in its event loop. So although generally frowned upon, in this case QThread::terminate has to be called
But it is generally said to be unsafe to call complex functions like QThread::currentThread, QThread::exit or QThread::terminate from signal handlers, so you should never call them there
Since the thread is still running after the signal handler (and I'm not sure even QThread::terminate would kill it fast enough), the signal handler exits to where it was called from, so it reexecutes the instruction causing the SIGSEGV, and the next SIGSEGV occurs.
Therefore I have used a different approach, the signal handler changes the register containing the instruction address to another function, which will then be run, after the signal handler exits, instead the crashing instruction. Like:
void signalHandler(int type, siginfo_t * si, void* ccontext){
(static_cast<ucontext_t*>(ccontext))->Eip = &recoverFromCrash;
}
struct sigaction sa;
memset(&sa, 0, sizeof(sa)); sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = &signalHandler;
sigaction(SIGSEGV, &sa, 0);
The recoverFromCrash function is then normally called in the thread causing the SIGSEGV. Since the signal handler is called for all SIGSEGV, from all threads, the function has to check which thread it is running in.
However, I did not consider it safe to simply kill the thread, since there might be other stuff, depending on a running thread. So instead of killing it, I let it run in an endless loop (calling sleep to avoid wasting CPU time). Then, when the program is closed, it sets a global variabel, and the thread is terminated. (notice that the recover function must never return, since otherwise the execution will return to the function which caused the SIGSEGV)
Called from the mainthread on the other hand, it starts a new event loop, to let the program running.
if (QThread::currentThread() != QCoreApplication::instance()->thread()) {
//sub thread
QThread* t = QThread::currentThread();
while (programIsRunning) ThreadBreaker::sleep(1);
ThreadBreaker::forceTerminate();
} else {
//main thread
while (programIsRunning) {
QApplication::processEvents(QEventLoop::AllEvents);
ThreadBreaker::msleep(1);
}
exit(0);
}
ThreadBreaker is a trivial wrapper class around QThread, since msleep, sleep and setTerminationEnabled (which has to be called before terminate) of QThread are protected and could not be called from the recover function.
But this is only the basic picture. There are a lot of other things to worry about: Catching SIGFPE, Catching stack overflows (check the address of the SIGSEGV, run the signal handler in an alternate stack), have a bunch of defines for platform independence (64 bit, arm, mac), show debug messages (try to get a stack trace, wonder why calling gdb for it crashes the X server, wonder why calling glibc backtrace for it crashes the program)...

Pthread library initialization

I have created wrappers around the pthread functions using dlopen and dlsym, in order to debug and profile some issues occurring in my application. The profiler passes all of the unit tests. Unfortunately, it appears that I have bypassed some library initialization because getenv now returns null to all input. If I remove the profiler, the proper operation of getenv returns.
I believe that the issue is that the compiler has not linked in Libpthread because it does not see any symbols requested from the library at link time. I have looked through the glib source but have not found an obvious run time initialization function that I can load and execute with dlsym.
I have stepped into getenv and found that __environ=null with the overrides compiled in. However, environ contains the proper values. __environ has the proper variables after removing the profiler.
Also, getenv appears to work with the pthread overrides on Ubuntu 10.04, with glibc 2.11. Unfortunately, upgrading is not an appealing option due to existing product distribution.
Linux 2.6.31
Glib 2.5
My init code:
inline int init_pthreads_debugger(void)
{
static int recursion=0;
if(!real_pthread_create)
{
// we know that we are single threaded here, because we override pthread_create and
// call this function. Therefore, recursion does not have to be guarded.
if(recursion)
{
return 0;
}
recursion = 1;
init_heap();
void * handle = dlopen("libpthread.so.0",RTLD_NOW);
real_pthread_cond_timedwait =(real_pthread_cond_timedwait_t)dlsym(handle,"pthread_cond_timedwait");
// more pthread initialization functions here.
//do me last to make sure any recursion in dlsym/dlopen is caught
real_pthread_create =(real_pthread_create_t)dlsym(handle,"pthread_create");
recursion = 0;
}
return 1;
}
//an example override
int pthread_cond_timedwait(pthread_cond_t *c, pthread_mutex_t * m, const struct timespec * t)
{
if(!init_pthreads_debugger()) return 0; //no thread, no sync needed.
int ret;
int condition_count;
ptd_note_unblock((void *)m,&condition_count);
ret=real_pthread_cond_timedwait(c,m,t);
ptd_note_block((void *)m,&condition_count);
return ret;
}
thanks for any help.
I have created wrappers around the pthread functions using dlopen and dlsym
I suspect that you are attempting to build a library interposer, similar to this one.
This approach is very unlikely to succeed in general for pthread functions, because both dlopen and dlsym themselves call pthread_mutex_lock and pthread_mutex_unlock (and possibly others), as does the dynamic loader itself.

std::future exception on gcc experimental implementation of C++0x

I'm experimenting with C++0x threading, partially implemented in gcc 4.5 and I've got a problem, which I can't understand. Let's have a look on this code
#include <future>
#include <iostream>
int main()
{
std::cout << std::async([]() { return 10; }).get() << std::endl;
}
it's quite simple and should work, but it's not. It throws std::system_error
terminate called after throwing an instance of 'std::system_error'
what():
Aborted
what() returns empty string, so there is no error information at all. More then that, it wasn't working on the online compiler, which uses gcc 4.5 as well, but now it works. You can see it here
http://liveworkspace.org/code/f3003d62a758e047a880920c84f1241c
but yesterday it was throwing the same exception (though, no changes has been made on the server). Do you know what is the issue?
Thanks.
Try linking with -lpthread. For some reason the thread library does compile without pthreads but crashes at runtime.

Resources