]> git.sesse.net Git - casparcg/blob - common/os/linux/signal_handlers.cpp
[linux] Don't overwrite thread name if it is already set.
[casparcg] / common / os / linux / signal_handlers.cpp
1 #include "../general_protection_fault.h"
2
3 #include "../../except.h"
4 #include "../../log.h"
5 #include "../../thread_info.h"
6
7 #include <signal.h>
8 #include <pthread.h>
9
10 namespace caspar {
11
12 struct floating_point_exception : virtual caspar_exception {};
13 struct segmentation_fault_exception : virtual caspar_exception {};
14
15 void catch_fpe(int signum)
16 {
17         try
18         {
19                 CASPAR_THROW_EXCEPTION(floating_point_exception());
20         }
21         catch (...)
22         {
23                 CASPAR_LOG_CURRENT_EXCEPTION();
24                 throw;
25         }
26 }
27
28 void catch_segv(int signum)
29 {
30         try
31         {
32                 CASPAR_THROW_EXCEPTION(segmentation_fault_exception());
33         }
34         catch (...)
35         {
36                 CASPAR_LOG_CURRENT_EXCEPTION();
37                 throw;
38         }
39 }
40
41 void do_install_handlers()
42 {
43         signal(SIGFPE, catch_fpe);
44         signal(SIGSEGV, catch_segv);
45 }
46
47 void install_gpf_handler()
48 {
49         ensure_gpf_handler_installed_for_thread();
50 }
51
52 void ensure_gpf_handler_installed_for_thread(
53                 const char* thread_description)
54 {
55         static const int MAX_LINUX_THREAD_NAME_LEN = 15;
56         static auto install = []() { do_install_handlers(); return 0; } ();
57
58         auto& for_thread = get_thread_info();
59         
60         if (thread_description && for_thread.name.empty())
61         {
62                 for_thread.name = thread_description;
63
64                 if (std::strlen(thread_description) > MAX_LINUX_THREAD_NAME_LEN)
65                 {
66                         char truncated[MAX_LINUX_THREAD_NAME_LEN + 1];
67                         std::memcpy(truncated, thread_description, MAX_LINUX_THREAD_NAME_LEN);
68                         truncated[MAX_LINUX_THREAD_NAME_LEN] = 0;
69                         pthread_setname_np(pthread_self(), truncated);
70                 }
71                 else
72                         pthread_setname_np(pthread_self(), thread_description);
73         }
74 }
75
76 }