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

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.

Related

Memory leak if VCL Exception object is thrown with Message

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).

C++ data sharing between threads c++

Originally coming from Java, I'm having problem with data sharing between 2 threads in C++11. I have thoroughly read through the multithreading posts here without help and i would simply like to know why my approach is not OK C++ syntax for multithreading.
My application in short:
I have one thread reading a hardware sensor and dumping that data to some shared data monitor
I want another thread listening to data changes of that very monitor and draw some graphical stuff based on the new data (yes, I'm using conditional varible in my monitor)
Below is my Main class with the main method:
#include <cstdlib>
#include <iostream>
#include <thread>
#include <sweep/sweep.hpp>
#include <pcl/ModelCoefficients.h>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/features/normal_3d.h>
#include "include/LiDAR.h"
#include "include/Visualizer.h"
void run_LiDAR(LiDAR* lidar){
lidar->run();
}
void visualize(Visualizer* visualizer){
visualizer->run();
}
int main(int argc, char* argv[]) try {
Monitor mon; //The monitor holding shared data
LiDAR sensor(&mon); //Sensor object dumping data to the monitor
Visualizer vis(&mon); //Visualizer listening to data changes and updates the visuals accordingly
std::thread sweep_thread(run_LiDAR, &sensor); //Starting the LiDAR thread
std::cout << "Started Sweep thread" << std::endl;
std::thread visualizer_thread(visualize, vis);
std::cout << "Started Visualizer thread" << std::endl;
while(1){
//Do some calculations on the data in Monitor mon
mon.cluster();
}
}
The sensor thread dumping the data works good and so does the main thread running the clustering algorithms. However I get the following error message:
In file included from MY_DIRECTORY/Main.cpp:3: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/thread:336:5: error: attempt to use a deleted function
__invoke(_VSTD::move(_VSTD::get<1>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...);
If I comment the line:
std::thread visualizer_thread(visualize, vis);
My program builds and works...
What am I not getting?
Kind regards,
What is happening is that Visualizer doesn't have a move constructor.
std::thread visualizer_thread(visualize, vis);
visualize() expects a pointer.
As an aside, you should make you have a mechanism to end your threads in an orderly manner, since the data (sensor, vis) will destroy itself when main() exits, leaving the threads reading/writing to unallocated data on the stack!
Using dynamic allocation using std::unique_ptr or std::shared_ptr (which are moveable) can eliminate the issue.

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.

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.

Resources