boost thread list - c++

I have code similar to below. The code below gives SIGSEGV and points to list::push_back. Is this the right way to use list of boost threads?
struct mythread{
static void myfunc() {
while(1){ }
}
};
int f(){
std::list<boost::thread *> pool;
pool.push_back(new boost::thread(mythread::myfunc));
}
Environment: gcc 4.4.5 on Ubuntu, linked with libboost_thread.a and -lpthread. I am not using c++0x flag.
Regards,
Chubsdad
Note 2: I also get SIGSEGV for the code
pool.push_back(new boost::thread(NULL);

Try taking the address of the function pointer:
pool.push_back(new boost::thread(&mythread::myfunc));

Related

Why does a lock_guard on a mutex reference produce C26110

The following code in a Visual Studio Professional 2019 project (version 16.3.6) produces a warning:
#include <thread>
#include <future>
class Foo {
public:
mutable std::recursive_mutex _writingMutex;
std::recursive_mutex& writingMutex() const { return _writingMutex; }
};
int main()
{
Foo a;
std::lock_guard<std::recursive_mutex> lock(a.writingMutex()); // produces C26110
std::lock_guard<std::recursive_mutex> lock2(a._writingMutex); // no warning
}
The first lock produces the warning C26110:
Warning C26110 Caller failing to hold lock 'lock' before calling function 'std::lock_guard::~lock_guard'
Why is this so? Does passing the mutex as reference not work?
Based on the compilation result of Alan and the comment of rustyx, I will answer my own question:
This is likely to be a code analysis bug in Visual Studio. Looks like C26110 can't recognize a mutex via a reference. The issue was reported here and I added my minimal example as comment there. The issue persists in the most recent version 16.3.7 as well

Why do I get a segmentation fault when adding ltalloc with MinGW

I tried to build my application with ltalloc. I tried it with MinGW32 4.9.1 and MinGW64-32 4.9.2.
It compiles and links fine but when I run it a Segmentation Fault occurs. Debugging pinpointed the problem to the following code:
#include <pthread.h>
#pragma weak pthread_once
#pragma weak pthread_key_create
#pragma weak pthread_setspecific
static pthread_key_t pthread_key;
static pthread_once_t init_once = PTHREAD_ONCE_INIT;
static void init_pthread_key() { pthread_key_create(&pthread_key, release_thread_cache); }
static thread_local int thread_initialized = 0;
static void init_pthread_destructor()//must be called only when some block placed into a thread cache's free list
{
if (unlikely(!thread_initialized))
{
thread_initialized = 1;
if (pthread_once)
{
pthread_once(&init_once, init_pthread_key); // <--- THIS CAUSES THE SEGSEGV
pthread_setspecific(pthread_key, (void*)1);//set nonzero value to force calling of release_thread_cache() on thread terminate
}
}
}
As far as I know both versions support thread-local storage natively. The Wiki of of ltalloc also wrote the following:
Warning: in some builds of MinGW there is a problem with emutls and order of execution of thread destructor (all thread local variables destructed before it), and termination of any thread will lead to application crash.
Unfortunately this warning doesn't tell me anything. Googling it also didn't make me smarter.
Out of the blue, try this:
static void init_pthread_key(void)
{
if (pthread_key_create)
{
pthread_key_create(&pthread_key, release_thread_cache);
}
}
Also adding full error checking to the pthread_* might not only help during debugging.

thread_local seems broken on Mac OSX 10.7.2 under gcc 4.9.1

this is my first time here...
I'm trying to uses multithreaded C++ code.
I'm on a Mac OSX 10.7.2.
Because the OS and compiler are so old and don't support c++11,
I followed the instructions here
https://solarianprogrammer.com/2013/06/11/compiling-gcc-mac-os-x/
I seem to have a working gcc 4.9.1, but then I tried doing some
multi-threading.
#include <thread>
using namespace std;
class X {
public:
char *p;
X() : p(0) { }
~X() { if (p) delete[] p; }
void set(int n) { p = new char[n]; }
};
void task()
{
static thread_local X x;
x.set(8*23);
}
int main()
{
thread t1(task);
thread t2(task);
thread t3(task);
thread t4(task);
thread t5(task);
t1.join();
t2.join();
t3.join();
t4.join();
t5.join();
}
Well, if I compile this as
/usr/gcc-4.9.1/bin/g++-4.9.1 -g -std=c++11 simple.c
I get errors like this:
a.out(50392,0x100605000) malloc: * error for object 0x137fe130400db0: pointer being freed was not allocated
* set a breakpoint in malloc_error_break to debug
Illegal instruction: 4
a.out(50405,0x102a70000) malloc: * error for object 0x137fcf22500060: pointer being freed was not allocated
* set a breakpoint in malloc_error_break to debug
Illegal instruction: 4
I tried adding -pthread and -lpthread as command-line options, but that didn't help.
I added print statement too, which revealed that the addresses in the error messages were the addresses of the static local objects themselves.
Maybe I'm trying to run this in an environment that is just too out of date.
Or maybe the right runtime is not getting linked in.
I'm not sure if anyone out there can help...maybe I just need to get access to
a more up-to-date system.
Thanks!!

Catching exception from a specialized method

Let's consider the following three files.
tclass.h:
#include <iostream>
#include <vector>
template<typename rt>
class tclass
{
public:
void wrapper()
{
//Storage is empty
for(auto it:storage)
{
}
try
{
thrower();
}
catch(...)
{
std::cout << "Catch in wrapper\n";
}
}
private:
void thrower(){}
std::vector<int> storage;
};
spec.cpp:
#include "tclass.h"
//The exact type does not matter here, we just need to call the specialized method.
template<>
void tclass<long double>::thrower()
{
//Again, the exception may have any type.
throw (double)2;
}
main.cpp:
#include "tclass.h"
#include <iostream>
int main()
{
tclass<long double> foo;
try
{
foo.wrapper();
}
catch(...)
{
std::cerr << "Catch in main\n";
return 4;
}
return 0;
}
I use Linux x64, gcc 4.7.2, the files are compiled with this command:
g++ --std=c++11 *.cpp
First test: if we run the program above, it says:
terminate called after throwing an instance of 'double'
Aborted
Second test: if we comment for(auto it:storage) in the tclass.h file, the program will catch the exception in main function. WATWhy? Is it a stack corruption caused by an attempt to iterate over the empty vector?
Third test: lets uncomment back the for(auto it:storage) line and move the method specialization from spec.cpp to main.cpp. Then the exception is caught in wrapper. How is it possible and why does possible memory corruption not affect this case?
I also tried to compile it with different optimization levels and with -g, but results were the same.
Then I tried it on Windows 7 x64, VS2012 express, compiling with x64 version of cl.exe with no extra command line arguments. At the first test this program produced no output, so I think it just crashed silently, so the result is similar with Linux version. For the second test it produced no output again, so result is different from Linux. For the third test the result was similar with Linux result.
Are there any errors in this code so they can lead to such behavior? May the results of the first test be caused by possible bug in compilers?
With your code, I have with gcc 4.7.1:
spec.cpp:6: multiple definition of 'tclass<long double>::thrower()'
You may correct your code by declaring the specialization in your .h as:
template<> void tclass<long double>::thrower();

Boost.Interprocess: testcase gives different results if compiled with or without optimization (GCC)

I'm having some troubles with Boost.Interprocess allocators when compiling with optimization. I managed to get this down to a 40 lines testcase, most of which is boilerplate. Just have a look at create() and main() functions in the code below.
#include <iostream>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
namespace interp = boost::interprocess;
struct interp_memory_chunk
{
interp::managed_shared_memory chunk;
interp_memory_chunk ()
{
interp::shared_memory_object::remove ("GCC_interprocess_test");
chunk = interp::managed_shared_memory (interp::create_only, "GCC_interprocess_test", 0x10000);
}
~interp_memory_chunk ()
{
interp::shared_memory_object::remove ("GCC_interprocess_test");
}
};
typedef interp::allocator <int, interp::managed_shared_memory::segment_manager> allocator_type;
inline void
create (allocator_type& allocator, allocator_type::value_type& at, int value)
{
allocator.construct (allocator.address (at), value);
}
int
main ()
{
interp_memory_chunk memory;
allocator_type allocator (memory.chunk.get_segment_manager ());
allocator_type::pointer data = allocator.allocate (1);
create (allocator, *data, 0xdeadbeef);
std::cout << std::hex << *data << "\n";
}
When compiling this without optimization:
g++ interprocess.cpp -lboost_thread -o interprocess
and running, the output is deadbeef, as expected.
However, when compiling with optimization:
g++ -O1 interprocess.cpp -lboost_thread -o interprocess
running gives 0, not what is expected.
So, I'm not sure where the problem is. Is this a bug in my program, i.e. do I invoke some UB? Is it a bug in Boost.Interprocess? Or maybe in GCC?
For the record, I observe this behavior with GCC 4.6 and 4.5, but not with GCC 4.4 or Clang. Boost version is 1.46.1 here.
EDIT: Note that having create() as a separate function is essential, which might indicate that problem arises when GCC inlines it.
As others have suggested, one solution is try to find the minimial set of optimisation flags you need to trigger your problem, using -O1 -fno....
Other options:
Use Valgrind and see what it comes up with
Try compiling with "-fdump-tree-all", this generates a bunch of intermediate compiled files. You can then see if the compiled code has any differences. These intermediate files are still in C++, so you don't need to know assembler. They are pretty much human readable, and certainly diffable.