1 /* gimpdebug
2  * Copyright (C) 2018 Jehan <jehan@gimp.org>
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 /*
19  * GimpDebug simply displays a dialog with debug data (backtraces,
20  * version, etc.), proposing to create a bug report. The reason why it
21  * is a separate executable is simply that when the program crashed,
22  * even though some actions are possible before exit() by catching fatal
23  * errors and signals, it may not be possible to allocate memory
24  * anymore. Therefore creating a new dialog is an impossible action.
25  * So we call instead a separate program, then exit.
26  */
27 
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <string.h>
31 
32 #include <sys/stat.h>
33 
34 #include <gio/gio.h>
35 #include <glib.h>
36 #include <glib/gi18n.h>
37 
38 #include <gtk/gtk.h>
39 
40 #include "app/widgets/gimpcriticaldialog.h"
41 
42 
43 
44 int
main(int argc,char ** argv)45 main (int    argc,
46       char **argv)
47 {
48   const gchar *program;
49   const gchar *pid;
50   const gchar *reason;
51   const gchar *message;
52   const gchar *bt_file      = NULL;
53   const gchar *last_version = NULL;
54   const gchar *release_date = NULL;
55   gchar       *trace        = NULL;
56   gchar       *error;
57   GtkWidget   *dialog;
58 
59   if (argc != 6 && argc != 8)
60     {
61       g_print ("Usage: gimp-debug-tool-2.0 [PROGRAM] [PID] [REASON] [MESSAGE] [BT_FILE] "
62                "([LAST_VERSION] [RELEASE_TIMESTAMP])\n");
63       exit (EXIT_FAILURE);
64     }
65 
66   program = argv[1];
67   pid     = argv[2];
68   reason  = argv[3];
69   message = argv[4];
70 
71   error   = g_strdup_printf ("%s: %s", reason, message);
72 
73   bt_file = argv[5];
74   g_file_get_contents (bt_file, &trace, NULL, NULL);
75 
76   if (trace == NULL || strlen (trace) == 0)
77     exit (EXIT_FAILURE);
78 
79   if (argc == 8)
80     {
81       last_version = argv[6];
82       release_date = argv[7];
83     }
84 
85   gtk_init (&argc, &argv);
86 
87   dialog = gimp_critical_dialog_new (_("GIMP Crash Debug"), last_version,
88                                      release_date ? g_ascii_strtoll (release_date, NULL, 10) : -1);
89   gimp_critical_dialog_add (dialog, error, trace, TRUE, program,
90                             g_ascii_strtoull (pid, NULL, 10));
91   g_free (error);
92   g_free (trace);
93   g_signal_connect (dialog, "delete-event",
94                     G_CALLBACK (gtk_main_quit), NULL);
95   g_signal_connect (dialog, "destroy",
96                     G_CALLBACK (gtk_main_quit), NULL);
97 
98   gtk_widget_show (dialog);
99   gtk_main ();
100 
101   exit (EXIT_SUCCESS);
102 }
103