$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [boost] [thread] thread_proxy's catch(...) destroys my stack info for unhandled exceptions
From: Dmitry Goncharov (dgoncharov_at_[hidden])
Date: 2008-12-27 07:07:19
Your f1() and f2() are callback function. If such a callback function 
throws an exception the program should be terminated, since the os 
cannot handle the exception for you.
That's reasonable to embrace callbacks like f1() with a catch all block 
and deal with the exception the way you want.
E.g.
void f1()
{
    try { throw 1;  }
    catch(...) {abort();} // Here is your core dump.
}
If everybody did that there would be no need for boost::thread to 
provide the catch all block.
BR, Dmitry
Roberto Gimenez wrote:
> When some unhandled exception is thrown inside my function, it would be good 
> that is isn't actually handled, so I could collect the stack info from the 
> core-dump. For example:
>
> #include <boost/thread.hpp>
>
> using namespace std;
> using namespace boost;
>
> void f1() { throw 1; }    
> void f2() { throw 1; }   
> void f() { f1(); f2(); }
>
> int main(int argc, char** argv)
> {
>     
>     thread t(f);
>     t.join();
>     
>     return (EXIT_SUCCESS);
> }
>
>
> Whe run it, the core-dump's stack info is:
>
> -----------------  lwp# 1 / thread# 1  --------------------
>  ffffffff7ecd2f20 __lwp_park (100108658, 100108640, ...
>  ffffffff7eccc748 cond_wait_queue (100108658, 100108640, ...
>  ffffffff7ecccca8 cond_wait (100108658, 100108640, ...
>  ffffffff7ecccce4 pthread_cond_wait (100108658, 100108640,...
>  ffffffff7f809ff4 void boost::thread::join() (ffffffff7ffff518, ...
>  0000000100004168 main (1, ffffffff7ffff608, ffffffff7ffff618, ...
>  0000000100003a7c _start (0, 0, 0, 0, 0, 0) + 17c
> -----------------  lwp# 2 / thread# 2  --------------------
>  ffffffff7ecd40a4 _lwp_kill (6, 0, ffffffff7edf7338, ...
>  ffffffff7ec4a68c abort (1, 1b8, ffffffff7f106f10, ...
>  ffffffff7f106a04 void __Cimpl::default_terminate() (0, 0, ...
>  ffffffff7f809770 thread_proxy (100108610, 1001086dd, 2c, ...
>  ffffffff7ecd2e7c _lwp_start (0, 0, 0, 0, 0, 0)
>
> With this information I cannot know where the exception was thrown.
>
>
> So I commented the catch(...) part in libs/thread/src/pthread/thread.cpp:
>
> extern "C"
> {
>     void* thread_proxy(void* param)
>     {
> 	boost::detail::thread_data_ptr thread_info = 
> 		static_cast<boost::detail::thread_data_base*>(param)->self;
> 	thread_info->self.reset();
> 	detail::set_current_thread_data(thread_info.get());
> 	try
> 	{
> 	    thread_info->run();
> 	}
> 	catch(thread_interrupted const&)
> 	{
> 	}
> 	//catch(...)
> 	//{
> 	//    std::terminate();
> 	//}
>
> 	detail::tls_destructor(thread_info.get());
> 	detail::set_current_thread_data(0);
> 	boost::lock_guard<boost::mutex> lock(thread_info->data_mutex);
> 	thread_info->done=true;
> 	thread_info->done_condition.notify_all();
> 	return 0;
>     }
> }
>
> And recompiled boost, now the core dump's stack info is the desired one:
>
> -----------------  lwp# 1 / thread# 1  --------------------
>  ffffffff7ecd2f20 __lwp_park (100108658, 100108640, 0, 4, 11fb1c, ...
>  ffffffff7eccc748 cond_wait_queue (100108658, 100108640, 0, 0, ...
>  ffffffff7ecccca8 cond_wait (100108658, 100108640, ffffffff7ed00358,...
>  ffffffff7ecccce4 pthread_cond_wait (100108658, 100108640, ...
>  ffffffff7f809f54 void boost::thread::join() (ffffffff7ffff518, ...
>  0000000100004168 main (1, ffffffff7ffff608, ffffffff7ffff618, ...
>  0000000100003a7c _start (0, 0, 0, 0, 0, 0) + 17c
> -----------------  lwp# 2 / thread# 2  --------------------
>  ffffffff7ecd40a4 _lwp_kill (6, 0, ffffffff7edf7338, ...
>  ffffffff7ec4a68c abort (1, 1b8, ffffffff7f106f10, ...
>  ffffffff7f106a04 void __Cimpl::default_terminate() (ffffffff7f214718, ... 
>  ffffffff7f1067f4 void __Cimpl::ex_terminate() (ffffffff7f2106c0, 0, 0, ...
>  ffffffff7f1074c8 _ex_throw_body (ffffffff7f2106c0, 0, ffffffff7e2fbf50, ...
>  ffffffff7f10740c void __Crun::ex_throw(void*,...
>  0000000100004064 void f1() (0, 0, ffffffff7edf7f80, ...
>  00000001000040fc void f() (ffffffff7f915528, 100108610, ...
>  00000001000053c0 void boost::detail::thread_data<void(*)()>::run() (...
>  ffffffff7f8095b4 thread_proxy (100108610, 3, 100106bd8, 100108610...
>  ffffffff7ecd2e7c _lwp_start (0, 0, 0, 0, 0, 0)
>
>
> I can know now where the unexpected/unhandled exception was thrown. 
> I could solve my problem partially, puting throw() exception specs 
> everywhere, so when some unexpected exception is thrown, the throw() 
> will stop it. Unfortunatelly, it whould stop at the calling function, 
> and the stack will tell me that some unexpected exception was thrown 
> by any of the functions inside the caller. This is worse than having 
> a stack info like the above one because in this case I wouldn't know 
> who raised the unexpected exception. In the above stack info I can know 
> who did it. 
>
> So why is:
>
> catch(...)
> {
>     std::terminate();
> }
>
> there? It looks unnecesary.
>
> _______________________________________________
> Unsubscribe & other changes: http://listarchives.boost.org/mailman/listinfo.cgi/boost
>