extern EAPI Eina_Bool starting;
extern EAPI Eina_Bool stopping;
extern EAPI Eina_Bool restart;
+extern EAPI Eina_Bool e_nopause;
extern EAPI Eina_Bool e_precache_end;
extern EAPI Eina_Bool x_fatal;
}
EAPI void
-e_alert_show(int sig)
+e_alert_show(void)
{
- char *args[4];
- pid_t pid;
-
-#define E_ALERT_EXE "/enlightenment/utils/enlightenment_alert"
-
- args[0] = alloca(strlen(e_prefix_lib_get()) + strlen(E_ALERT_EXE) + 1);
- strcpy(args[0], e_prefix_lib_get());
- strcat(args[0], E_ALERT_EXE);
-
- args[1] = alloca(10);
- snprintf(args[1], 10, "%d", sig);
-
- args[2] = alloca(21);
- snprintf(args[2], 21, "%lu", (long unsigned int)getpid());
-
- args[3] = NULL;
-
- pid = fork();
- if (pid < -1)
- goto restart_e;
-
- if (pid == 0)
- {
- /* The child process */
- execvp(args[0], args);
- }
- else
+ if (!e_nopause)
{
- /* The parent process */
- pid_t ret;
- int status = 0;
-
- do
- {
- ret = waitpid(pid, &status, 0);
- if (errno == ECHILD)
- break ;
- }
- while (ret != pid);
-
- if (status == 0)
- goto restart_e;
-
- if (!WIFEXITED(status))
- goto restart_e;
-
- if (WEXITSTATUS(status) == 1)
- goto restart_e;
-
- exit(-11);
+ fprintf(stderr, "PAUSE !\n");
+ pause();
}
-
- restart_e:
- if (getenv("E_START_MTRACK"))
- e_util_env_set("MTRACK", "track");
- ecore_app_restart();
+ return ;
}
EINTERN int e_alert_init(void);
EINTERN int e_alert_shutdown(void);
-EAPI void e_alert_show(int sig);
+EAPI void e_alert_show(void);
#endif
#endif
static int ret = 0, sig = 0;
static pid_t pid;
static Eina_Bool tainted = EINA_TRUE;
+static const char *backtrace = NULL;
int
main(int argc, char **argv)
sig = atoi(argv[i]); // signal
else if (i == 2)
pid = atoi(argv[i]); // E's pid
+ else if (i == 3)
+ backtrace = argv[i];
}
tmp = getenv("E17_TAINTED");
if (!tainted)
{
- snprintf(msg, sizeof(msg),
- "This is not meant to happen and is likely a sign of \n"
- "a bug in Enlightenment or the libraries it relies \n"
- "on. You can gdb attach to this process (%d) now \n"
- "to try debug it or you could exit, or just hit \n"
- "restart to try and get your desktop back the way \n"
- "it was.\n"
- "\n"
- "Please compile E17 and EFL with -g in your CFLAGS.\n", pid);
+ if (backtrace)
+ {
+ snprintf(msg, sizeof(msg),
+ "This is not meant to happen and is likely a sign of \n"
+ "a bug in Enlightenment or the libraries it relies \n"
+ "on. You will find an backtrace of E17 (%d) in :\n"
+ "'%s'\n"
+ "Before reporting issue, compile latest E17 and EFL\n"
+ "from svn with '-g -ggdb3' in your CFLAGS.\n"
+ "You can then report this crash on :\n"
+ "http://trac.enlightenment.org/e/.\n",
+ pid, backtrace);
+ }
+ else
+ {
+ snprintf(msg, sizeof(msg),
+ "This is not meant to happen and is likely a sign of \n"
+ "a bug in Enlightenment or the libraries it relies \n"
+ "on. You can gdb attach to this process (%d) now \n"
+ "to try debug it or you could exit, or just hit \n"
+ "restart to try and get your desktop back the way \n"
+ "it was.\n"
+ "\n"
+ "Please compile latest svn E17 and EFL with\n"
+ "-g and -ggdb3 in your CFLAGS.\n", pid);
+
+ }
}
else
{
"a sign of a bug, but you are using unsupported\n"
"modules; before reporting this issue, please\n"
"unload them and try to see if the bug is still\n"
- "there.\n");
+ "there. Also update to latest svn and be sure to\n"
+ "compile E17 and EFL with -g and -ggdb3 in your CFLAGS");
}
strcpy(warn, "");
EAPI Eina_Bool starting = EINA_TRUE;
EAPI Eina_Bool stopping = EINA_FALSE;
EAPI Eina_Bool restart = EINA_FALSE;
+EAPI Eina_Bool e_nopause = EINA_FALSE;
static void
_xdg_data_dirs_augment(void)
really_know = EINA_TRUE;
else if (!strcmp(argv[i], "-locked"))
locked = EINA_TRUE;
+ else if (!strcmp(argv[i], "-nopause"))
+ e_nopause = EINA_TRUE;
else if ((!strcmp(argv[i], "-h")) ||
(!strcmp(argv[i], "-help")) ||
(!strcmp(argv[i], "--help")))
}
}
-static void
-_e_gdb_print_backtrace(int fd __UNUSED__)
-{
- // FIXME: we are in a segv'd state. do as few function calls and things
- // depending on a known working state as possible. this also prevents the
- // white box allowing recovery or deeper gdbing, thus until this works
- // properly, it's disabled (properly means always reliable, always
- // printf bt and allows e to continue and pop up box, perferably allowing
- // debugging in the gui etc. etc.
-#if 0
- char cmd[1024];
- size_t size;
- int ret;
-
- if (getenv("E_NO_GDB_BACKTRACE"))
- return;
-
- size = snprintf(cmd, sizeof(cmd),
- "gdb --pid=%d "
- "-ex 'thread apply all bt' "
- "-ex detach -ex quit", getpid());
-
- if (size >= sizeof(cmd))
- return;
-
- _e_write_safe(fd, "EXECUTING GDB AS: ");
- _e_write_safe_int(fd, cmd, size);
- _e_write_safe(fd, "\n");
- ret = system(cmd); // TODO: use popen() or fork()+pipe()+exec() and save to 'fd'
-#endif
-}
-
-#define _e_backtrace(msg) _e_backtrace_int(2, msg, sizeof(msg))
-static void
-_e_backtrace_int(int fd, const char *msg, size_t msg_len)
-{
- char attachmsg[1024];
- void *array[255];
- size_t size;
-
- return; // disable. causes hangs and problems
-
- _e_write_safe_int(fd, msg, msg_len);
- _e_write_safe(fd, "\nBEGIN TRACEBACK\n");
- size = backtrace(array, 255);
- backtrace_symbols_fd(array, size, fd);
- _e_write_safe(fd, "END TRACEBACK\n");
-
- size = snprintf(attachmsg, sizeof(attachmsg),
- "debug with: gdb --pid=%d\n", getpid());
- if (size < sizeof(attachmsg))
- _e_write_safe_int(fd, attachmsg, size);
-
- _e_gdb_print_backtrace(fd);
-}
-
/* a tricky little devil, requires e and it's libs to be built
* with the -rdynamic flag to GCC for any sort of decent output.
*/
EAPI void
e_sigseg_act(int x __UNUSED__, siginfo_t *info __UNUSED__, void *data __UNUSED__)
{
- _e_backtrace("**** SEGMENTATION FAULT ****");
_e_x_composite_shutdown();
ecore_x_pointer_ungrab();
ecore_x_keyboard_ungrab();
ecore_x_ungrab();
ecore_x_sync();
- e_alert_show(SIGSEGV);
+ e_alert_show();
}
EAPI void
e_sigill_act(int x __UNUSED__, siginfo_t *info __UNUSED__, void *data __UNUSED__)
{
- _e_backtrace("**** ILLEGAL INSTRUCTION ****");
_e_x_composite_shutdown();
ecore_x_pointer_ungrab();
ecore_x_keyboard_ungrab();
ecore_x_ungrab();
ecore_x_sync();
- e_alert_show(SIGILL);
+ e_alert_show();
}
EAPI void
e_sigfpe_act(int x __UNUSED__, siginfo_t *info __UNUSED__, void *data __UNUSED__)
{
- _e_backtrace("**** FLOATING POINT EXCEPTION ****");
_e_x_composite_shutdown();
ecore_x_pointer_ungrab();
ecore_x_keyboard_ungrab();
ecore_x_ungrab();
ecore_x_sync();
- e_alert_show(SIGFPE);
+ e_alert_show();
}
EAPI void
e_sigbus_act(int x __UNUSED__, siginfo_t *info __UNUSED__, void *data __UNUSED__)
{
- _e_backtrace("**** BUS ERROR ****");
_e_x_composite_shutdown();
ecore_x_pointer_ungrab();
ecore_x_keyboard_ungrab();
ecore_x_ungrab();
ecore_x_sync();
- e_alert_show(SIGBUS);
+ e_alert_show();
}
EAPI void
e_sigabrt_act(int x __UNUSED__, siginfo_t *info __UNUSED__, void *data __UNUSED__)
{
- _e_backtrace("**** ABORT ****");
_e_x_composite_shutdown();
ecore_x_pointer_ungrab();
ecore_x_keyboard_ungrab();
ecore_x_ungrab();
ecore_x_sync();
- e_alert_show(SIGABRT);
+ e_alert_show();
}
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/utsname.h>
+#include <sys/ptrace.h>
#include <limits.h>
#include <fcntl.h>
#ifdef HAVE_ALLOCA_H
# include <alloca.h>
#endif
+#include <signal.h>
+
#include <Eina.h>
+static Eina_Bool tainted = EINA_FALSE;
+
static void env_set(const char *var, const char *val);
EAPI int prefix_determine(char *argv0);
int i, valgrind_mode = 0;
int valgrind_tool = 0;
int valgrind_gdbserver = 0;
- char buf[16384], **args, *p;
+ char buf[16384], **args, *home;
char valgrind_path[PATH_MAX] = "";
const char *valgrind_log = NULL;
Eina_Bool really_know = EINA_FALSE;
+ Eina_Bool restart = EINA_TRUE;
eina_init();
+
+ /* reexcute myself with dbus-launch if dbus-launch is not running yet */
+ if ((!getenv("DBUS_SESSION_BUS_ADDRESS")) &&
+ (!getenv("DBUS_LAUNCHD_SESSION_BUS_SOCKET")))
+ {
+ char **dbus_argv;
+
+ dbus_argv = alloca(argc + 3 + sizeof (char *));
+ dbus_argv[0] = "dbus-launch";
+ dbus_argv[1] = "--exit-with-session";
+ copy_args(dbus_argv + 2, argv, argc);
+ dbus_argv[2 + argc] = NULL;
+ execvp("dbus-launch", dbus_argv);
+ }
+
prefix_determine(argv[0]);
env_set("E_START", argv[0]);
else
printf("Unknown valgrind option: %s\n", argv[i]);
}
+ else if (!strcmp(argv[i], "-display"))
+ {
+ i++;
+ env_set("DISPLAY", argv[i]);
+ }
else if (!strcmp(argv[i], "-massif"))
valgrind_tool = 1;
else if (!strcmp(argv[i], "-callgrind"))
putchar('\n');
/* mtrack memory tracker support */
- p = getenv("HOME");
- if (p)
+ home = getenv("HOME");
+ if (home)
{
FILE *f;
/* if you have ~/.e-mtrack, then the tracker will be enabled
* using the content of this file as the path to the mtrack.so
* shared object that is the mtrack preload */
- snprintf(buf, sizeof(buf), "%s/.e-mtrack", p);
+ snprintf(buf, sizeof(buf), "%s/.e-mtrack", home);
f = fopen(buf, "r");
if (f)
{
env_set("LD_PRELOAD", buf);
env_set("MTRACK", "track");
env_set("E_START_MTRACK", "track");
- snprintf(buf, sizeof(buf), "%s/.e-mtrack.log", p);
+ snprintf(buf, sizeof(buf), "%s/.e-mtrack.log", home);
env_set("MTRACK_TRACE_FILE", buf);
}
fclose(f);
}
}
- /* try dbus-launch */
+ /* run e directly now */
snprintf(buf, sizeof(buf), "%s/enlightenment", eina_prefix_bin_get(pfx));
args = alloca((argc + 2 + VALGRIND_MAX_ARGS) * sizeof(char *));
- if ((!getenv("DBUS_SESSION_BUS_ADDRESS")) &&
- (!getenv("DBUS_LAUNCHD_SESSION_BUS_SOCKET")))
- {
- args[0] = "dbus-launch";
- args[1] = "--exit-with-session";
-
- i = 2 + valgrind_append(args + 2, valgrind_gdbserver, valgrind_mode, valgrind_tool, valgrind_path, valgrind_log);
- args[i++] = buf;
- copy_args(args + i, argv + 1, argc - 1);
- args[i + argc - 1] = NULL;
- execvp("dbus-launch", args);
- }
-
- /* dbus-launch failed - run e direct */
i = valgrind_append(args, valgrind_gdbserver, valgrind_mode, valgrind_tool, valgrind_path, valgrind_log);
args[i++] = buf;
copy_args(args + i, argv + 1, argc - 1);
args[i + argc - 1] = NULL;
- execv(args[0], args);
+ /* execv(args[0], args); */
+
+ /* not run at the moment !! */
+
+
+ /* Now looping until */
+ while (restart)
+ {
+ pid_t child;
+
+ tainted = EINA_FALSE;
+ child = fork();
+
+ if (child < 0) /* failed attempt */
+ return -1;
+ else if (child == 0)
+ {
+ /* in the child */
+ ptrace(PTRACE_TRACEME, 0, NULL, NULL);
+
+ execv(args[0], args);
+ return 0; /* We failed, 0 mean normal exit from E with no restart or crash so let exit */
+ }
+ else
+ {
+ /* in the parent */
+ pid_t result;
+ int status;
+ Eina_Bool done = EINA_FALSE;
+
+ ptrace(PTRACE_ATTACH, child, NULL, NULL);
+
+ result = waitpid(child, &status, 0);
+
+ if (WIFSTOPPED(status))
+ ptrace(PTRACE_CONT, child, NULL, NULL);
+
+ while (!done)
+ {
+ result = waitpid(child, &status, 0);
+
+ if (result == child)
+ {
+ if (WIFSTOPPED(status))
+ {
+ char buffer[4096];
+ char *backtrace = NULL;
+ siginfo_t sig;
+ int r;
+ int back;
+
+ r = ptrace(PTRACE_GETSIGINFO, child, NULL, &sig);
+ back = r == 0 &&
+ sig.si_signo != SIGTRAP ? sig.si_signo : 0;
+
+ if (r != 0 ||
+ (sig.si_signo != SIGSEGV &&
+ sig.si_signo != SIGILL &&
+ sig.si_signo != SIGFPE &&
+ sig.si_signo != SIGBUS &&
+ sig.si_signo != SIGABRT))
+ {
+ ptrace(PTRACE_CONT, child, NULL, back);
+ continue ;
+ }
+
+ /* E17 should be in pause, we can detach */
+ ptrace(PTRACE_DETACH, child, NULL, back);
+
+ /* And call gdb if available */
+ if (home)
+ {
+ /* call e_sys gdb */
+ snprintf(buffer, 4096,
+ "%s/enlightenment/utils/enlightenment_sys gdb %i %s/.xsession-errors",
+ eina_prefix_lib_get(pfx),
+ child,
+ home);
+ r = system(buffer);
+
+ fprintf(stderr, "called gdb with '%s' = %i\n",
+ buffer, WEXITSTATUS(r));
+
+ snprintf(buffer, 4096,
+ "%s/.xsession-errors",
+ home);
+
+ backtrace = strdup(buffer);
+ }
+
+ /* call e_alert */
+ snprintf(buffer, 4096,
+ backtrace ? "%s/enlightenment/utils/enlightenment_alert %i %i %s" : "%s/enlightenment/utils/enlightenment_alert %i %i %s",
+ eina_prefix_lib_get(pfx),
+ sig.si_signo,
+ child,
+ backtrace);
+ r = system(buffer);
+
+ /* kill e */
+ kill(child, SIGKILL);
+
+ if (WEXITSTATUS(r) != 1)
+ {
+ restart = EINA_FALSE;
+ }
+ }
+ else if (!WIFEXITED(status))
+ {
+ done = EINA_TRUE;
+ }
+ }
+ else if (result == - 1)
+ {
+ done = EINA_TRUE;
+ restart = EINA_FALSE;
+ }
+ }
+ }
+
+ }
- printf("FAILED TO RUN:\n");
- printf(" %s\n", buf);
- perror("execv");
return -1;
}