1 
2 /******************************************************************************
3 * MODULE     : tm_debug.cpp
4 * DESCRIPTION: Debugging facilities
5 * COPYRIGHT  : (C) 2011  Joris van der Hoeven
6 *              (C) 2008  Timo Bingmann from http://idlebox.net
7 *******************************************************************************
8 * This software falls under the GNU general public license version 3 or later.
9 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
10 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
11 ******************************************************************************/
12 
13 #include "tm_server.hpp"
14 #include "file.hpp"
15 #include "tm_link.hpp"
16 #include "sys_utils.hpp"
17 
18 bool rescue_mode= false;
19 
20 /******************************************************************************
21 * Status reports
22 ******************************************************************************/
23 
24 string
get_system_information()25 get_system_information () {
26   string r;
27   r << "System information:\n";
28   r << "  TeXmacs version  : "
29     << TEXMACS_VERSION << "\n";
30   r << "  Built by         : "
31     << BUILD_USER << "\n";
32   r << "  Building date    : "
33     << BUILD_DATE << "\n";
34   r << "  Operating system : "
35     << HOST_OS << "\n";
36   r << "  Vendor           : "
37     << HOST_VENDOR << "\n";
38   r << "  Processor        : "
39     << HOST_CPU << "\n";
40   r << "  Crash date       : "
41     << var_eval_system ("date") << "\n";
42   return r;
43 }
44 
45 string
path_as_string(path p)46 path_as_string (path p) {
47   if (is_nil (p)) return "[]";
48   string r= "[ ";
49   r << as_string (p->item);
50   p= p->next;
51   while (!is_nil (p)) {
52     r << ", " << as_string (p->item);
53     p= p->next;
54   }
55   r << " ]";
56   return r;
57 }
58 
59 string
get_editor_status_report()60 get_editor_status_report () {
61   string r;
62   r << "Editor status:\n";
63   server sv= get_server ();
64   editor ed= get_current_editor ();
65   path start_p, end_p;
66   ed->get_selection (start_p, end_p);
67   r << "  Root path          : "
68     << path_as_string (ed->rp) << "\n"
69     << "  Current path       : "
70     << path_as_string (ed->the_path ()) << "\n"
71     << "  Shifted path       : "
72     << path_as_string (ed->the_shifted_path ()) << "\n"
73     << "  Physical selection : "
74     << path_as_string (start_p) << " -- "
75     << path_as_string (end_p) << "\n";
76   if (start_p != end_p) {
77     selection sel;
78     ed->selection_get (sel);
79     r << "  Logical selection  : "
80       << path_as_string (sel->start) << " -- "
81       << path_as_string (sel->end) << "\n";
82   }
83   return r;
84 }
85 
86 void
tree_report(string & s,tree t,path p,int indent)87 tree_report (string& s, tree t, path p, int indent) {
88   for (int i=0; i<indent; i++) s << " ";
89   if (is_atomic (t)) {
90     s << raw_quote (t->label);
91     s << " -- " << path_as_string (p) << "\n";
92   }
93   else {
94     s << as_string (L(t));
95     s << " -- " << path_as_string (p) << "\n";
96     for (int i=0; i<N(t); i++)
97       tree_report (s, t[i], p * i, indent+2);
98   }
99 }
100 
101 string
tree_report(tree t,path p)102 tree_report (tree t, path p) {
103   string s;
104   tree_report (s, t, p, 0);
105   return s;
106 }
107 
108 /******************************************************************************
109 * Crash management
110 ******************************************************************************/
111 
112 string
get_crash_report(const char * msg)113 get_crash_report (const char* msg) {
114   string r;
115   r << "Error message:\n  " << msg << "\n"
116     << "\n" << get_system_information ()
117     << "\n" << get_editor_status_report ()
118     << "\n" << get_stacktrace ();
119   return r;
120 }
121 
122 void
tm_failure(const char * msg)123 tm_failure (const char* msg) {
124   if (rescue_mode) {
125     fprintf (stderr, "\nTeXmacs] Fatal unrecoverable error, %s\n", msg);
126 #ifdef DEBUG_ASSERT
127     return;
128 #endif
129     exit (1);
130   }
131   rescue_mode= true;
132   cerr << "\nTeXmacs] Fatal error, " << msg << "\n";
133 
134   //cerr << "Saving crash report...\n";
135   string report= get_crash_report (msg);
136   url dir ("$TEXMACS_HOME_PATH/system/crash");
137   url err= url_numbered (dir, "crash_report_", "");
138   if (!save_string (err, report))
139     cerr << "TeXmacs] Crash report saved in " << err << "\n";
140   else
141     cerr << "TeXmacs] Crash report could not be saved in "
142          << err << "\n"
143          << "TeXmacs] Dumping report below\n\n"
144          << report << "\n";
145 
146   //cerr << "Saving current buffer...\n";
147   server sv= get_server ();
148   editor ed= get_current_editor ();
149   string buf= tree_report (subtree (the_et, ed->rp), ed->rp);
150   url buf_err= glue (err, "_tree");
151   if (!save_string (buf_err, buf))
152     cerr << "TeXmacs] Current buffer report saved in " << buf_err << "\n";
153   else
154     cerr << "TeXmacs] Current buffer report could not be saved in "
155          << buf_err << "\n"
156          << "TeXmacs] Dumping report below\n\n"
157          << buf << "\n";
158 
159   //cerr << "Autosaving...\n";
160   call ("autosave-all");
161   //cerr << "Closing pipes...\n";
162   close_all_pipes ();
163   call ("quit-TeXmacs-scheme");
164   clear_pending_commands ();
165   //exit (1);
166 }
167