Tizen 2.1 release
[platform/core/uifw/e17.git] / src / bin / e_signals.c
1 /*
2  * NOTE TO FreeBSD users. Install libexecinfo from
3  * ports/devel/libexecinfo and add -lexecinfo to LDFLAGS
4  * to add backtrace support.
5  */
6 #include "e.h"
7
8 #ifdef HAVE_EXECINFO_H
9 # include <execinfo.h>
10 #endif
11
12 static volatile Eina_Bool _e_x_composite_shutdown_try = 0;
13
14 static void
15 _e_x_composite_shutdown(void)
16 {
17 //   Ecore_X_Display *dpy;
18    Ecore_X_Window root;
19
20    if (_e_x_composite_shutdown_try) return; /* we failed :-( */
21    _e_x_composite_shutdown_try = 1;
22
23 //   dpy = ecore_x_display_get();
24    root = ecore_x_window_root_first_get();
25
26    /* ignore errors, we really don't care at this point */
27    ecore_x_composite_unredirect_subwindows(root, ECORE_X_COMPOSITE_UPDATE_MANUAL);
28    _e_x_composite_shutdown_try = 0;
29 }
30
31 #define _e_write_safe(fd, buf) _e_write_safe_int(fd, buf, sizeof(buf))
32
33 static void
34 _e_write_safe_int(int fd, const char *buf, size_t size)
35 {
36    while (size > 0)
37      {
38         ssize_t done = write(fd, buf, size);
39         if (done >= 0)
40           {
41              buf += done;
42              size -= done;
43           }
44         else
45           {
46              if ((errno == EAGAIN) || (errno == EINTR))
47                continue;
48              else
49                {
50                   perror("write");
51                   return;
52                }
53           }
54      }
55 }
56
57 static void
58 _e_gdb_print_backtrace(int fd)
59 {
60    char cmd[1024];
61    size_t size;
62    int ret;
63
64    // FIXME: we are in a segv'd state. do as few function calls and things
65    // depending on a known working state as possible. this also prevents the
66    // white box allowing recovery or deeper gdbing, thus until this works
67    // properly, it's disabled (properly means always reliable, always
68    // printf bt and allows e to continue and pop up box, perferably allowing
69    // debugging in the gui etc. etc.
70    return;
71
72    if (getenv("E_NO_GDB_BACKTRACE"))
73      return;
74
75    size = snprintf(cmd, sizeof(cmd),
76                    "gdb --pid=%d "
77                    "-ex 'thread apply all bt' "
78                    "-ex detach -ex quit", getpid());
79
80    if (size >= sizeof(cmd))
81      return;
82
83    _e_write_safe(fd, "EXECUTING GDB AS: ");
84    _e_write_safe_int(fd, cmd, size);
85    _e_write_safe(fd, "\n");
86    ret = system(cmd); // TODO: use popen() or fork()+pipe()+exec() and save to 'fd'
87 }
88
89 #define _e_backtrace(msg) _e_backtrace_int(2, msg, sizeof(msg))
90 static void
91 _e_backtrace_int(int fd, const char *msg, size_t msg_len)
92 {
93    char attachmsg[1024];
94    void *array[255];
95    size_t size;
96
97    return; // disable. causes hangs and problems
98
99    _e_write_safe_int(fd, msg, msg_len);
100    _e_write_safe(fd, "\nBEGIN TRACEBACK\n");
101    size = backtrace(array, 255);
102    backtrace_symbols_fd(array, size, fd);
103    _e_write_safe(fd, "END TRACEBACK\n");
104
105    size = snprintf(attachmsg, sizeof(attachmsg),
106                    "debug with: gdb --pid=%d\n", getpid());
107    if (size < sizeof(attachmsg))
108      _e_write_safe_int(fd, attachmsg, size);
109
110    _e_gdb_print_backtrace(fd);
111 }
112
113 /* a tricky little devil, requires e and it's libs to be built
114  * with the -rdynamic flag to GCC for any sort of decent output.
115  */
116 EAPI void
117 e_sigseg_act(int x __UNUSED__, siginfo_t *info __UNUSED__, void *data __UNUSED__)
118 {
119    _e_backtrace("**** SEGMENTATION FAULT ****");
120    _e_x_composite_shutdown();
121    ecore_x_pointer_ungrab();
122    ecore_x_keyboard_ungrab();
123    ecore_x_ungrab();
124    ecore_x_sync();
125    e_alert_show(SIGSEGV);
126 }
127
128 EAPI void
129 e_sigill_act(int x __UNUSED__, siginfo_t *info __UNUSED__, void *data __UNUSED__)
130 {
131    _e_backtrace("**** ILLEGAL INSTRUCTION ****");
132    _e_x_composite_shutdown();
133    ecore_x_pointer_ungrab();
134    ecore_x_keyboard_ungrab();
135    ecore_x_ungrab();
136    ecore_x_sync();
137    e_alert_show(SIGILL);
138 }
139
140 EAPI void
141 e_sigfpe_act(int x __UNUSED__, siginfo_t *info __UNUSED__, void *data __UNUSED__)
142 {
143    _e_backtrace("**** FLOATING POINT EXCEPTION ****");
144    _e_x_composite_shutdown();
145    ecore_x_pointer_ungrab();
146    ecore_x_keyboard_ungrab();
147    ecore_x_ungrab();
148    ecore_x_sync();
149    e_alert_show(SIGFPE);
150 }
151
152 EAPI void
153 e_sigbus_act(int x __UNUSED__, siginfo_t *info __UNUSED__, void *data __UNUSED__)
154 {
155    _e_backtrace("**** BUS ERROR ****");
156    _e_x_composite_shutdown();
157    ecore_x_pointer_ungrab();
158    ecore_x_keyboard_ungrab();
159    ecore_x_ungrab();
160    ecore_x_sync();
161    e_alert_show(SIGBUS);
162 }
163
164 EAPI void
165 e_sigabrt_act(int x __UNUSED__, siginfo_t *info __UNUSED__, void *data __UNUSED__)
166 {
167    _e_backtrace("**** ABORT ****");
168    _e_x_composite_shutdown();
169    ecore_x_pointer_ungrab();
170    ecore_x_keyboard_ungrab();
171    ecore_x_ungrab();
172    ecore_x_sync();
173    e_alert_show(SIGABRT);
174 }