Пример #1
0
static void _dt_sigsegv_handler(int param)
{
  pid_t pid;
  gchar *name_used;
  int fout;
  gboolean delete_file = FALSE;
  char datadir[PATH_MAX] = { 0 };

  if((fout = g_file_open_tmp("darktable_bt_XXXXXX.txt", &name_used, NULL)) == -1)
    fout = STDOUT_FILENO; // just print everything to stdout

  dprintf(fout, "this is %s reporting a segfault:\n\n", PACKAGE_STRING);

  if(fout != STDOUT_FILENO) close(fout);

  dt_loc_get_datadir(datadir, sizeof(datadir));
  gchar *pid_arg = g_strdup_printf("%d", (int)getpid());
  gchar *comm_arg = g_strdup_printf("%s/gdb_commands", datadir);
  gchar *log_arg = g_strdup_printf("set logging on %s", name_used);

  if((pid = fork()) != -1)
  {
    if(pid)
    {
#ifdef __linux__
      // Allow the child to ptrace us
      prctl(PR_SET_PTRACER, pid, 0, 0, 0);
#endif
      waitpid(pid, NULL, 0);
      g_printerr("backtrace written to %s\n", name_used);
    }
    else
    {
      if(execlp("gdb", "gdb", darktable.progname, pid_arg, "-batch", "-ex", log_arg, "-x", comm_arg, NULL))
      {
        delete_file = TRUE;
        g_printerr("an error occurred while trying to execute gdb. please check if gdb is installed on your "
                   "system.\n");
      }
    }
  }
  else
  {
    delete_file = TRUE;
    g_printerr("an error occurred while trying to execute gdb.\n");
  }

  if(delete_file) g_unlink(name_used);
  g_free(pid_arg);
  g_free(comm_arg);
  g_free(log_arg);
  g_free(name_used);

  /* pass it further to the old handler*/
  _dt_sigsegv_old_handler(param);
}
Пример #2
0
static
void _dt_sigsegv_handler(int param)
{
  FILE *fd;
  gchar buf[PIPE_BUF];
  gchar *name_used;
  int fout;
  gboolean delete_file = FALSE;
  char datadir[DT_MAX_PATH_LEN];

  if((fout = g_file_open_tmp("darktable_bt_XXXXXX.txt", &name_used, NULL)) == -1)
    fout = STDOUT_FILENO; // just print everything to stdout

  dprintf(fout, "this is %s reporting a segfault:\n\n", PACKAGE_STRING);
  dt_loc_get_datadir(datadir, DT_MAX_PATH_LEN);
  gchar *command = g_strdup_printf("gdb %s %d -batch -x %s/gdb_commands", darktable.progname, (int)getpid(), datadir);

  if((fd = popen(command, "r")) != NULL)
  {
    gboolean read_something = FALSE;
    while((fgets(buf, PIPE_BUF, fd)) != NULL)
    {
      read_something = TRUE;
      dprintf(fout, "%s", buf);
    }
    pclose(fd);
    if(fout != STDOUT_FILENO)
    {
      if(read_something)
        g_printerr("backtrace written to %s\n", name_used);
      else
      {
        delete_file = TRUE;
        g_printerr("an error occured while trying to execute gdb. please check if gdb is installed on your system.\n");
      }
    }
  }
  else
  {
    delete_file = TRUE;
    g_printerr("an error occured while trying to execute gdb.\n");
  }

  if(fout != STDOUT_FILENO)
    close(fout);
  if(delete_file)
    g_unlink(name_used);
  g_free(command);
  g_free(name_used);

  /* pass it further to the old handler*/
  _dt_sigsegv_old_handler(param);
}