@@ -191,13 +191,6 @@ LONG WINAPI qgisCrashDump( struct _EXCEPTION_POINTERS *ExceptionInfo )
191
191
}
192
192
#endif
193
193
194
- #if (defined(linux) && !defined(ANDROID)) || defined(__FreeBSD__)
195
- void qgisCrash ( int signal )
196
- {
197
- qFatal ( " QGIS died on signal %d" , signal );
198
- }
199
- #endif
200
-
201
194
void myPrint ( const char *fmt, ... )
202
195
{
203
196
va_list ap;
@@ -211,95 +204,12 @@ void myPrint( const char *fmt, ... )
211
204
#endif
212
205
}
213
206
214
- void dumpBacktrace ( unsigned int depth = 0 )
207
+ static void dumpBacktrace ( unsigned int depth )
215
208
{
216
209
if ( depth == 0 )
217
- depth = 10 ;
210
+ depth = 20 ;
218
211
219
212
#if (defined(linux) && !defined(ANDROID)) || defined(__FreeBSD__)
220
- #if defined(linux) && !defined(ANDROID)
221
- if ( QgsLogger::debugLevel () >= 4 )
222
- {
223
- static int gdbRunning = -1 ;
224
- static int gdbpipe[2 ];
225
- static int gdbpid;
226
-
227
- if ( gdbRunning == -1 )
228
- {
229
- gdbRunning = 0 ;
230
-
231
- myPrint ( " starting gdb\n " );
232
- if ( access ( " /usr/bin/gdb" , X_OK ) == 0 )
233
- {
234
- // take full stacktrace using gdb
235
- // http://stackoverflow.com/questions/3151779/how-its-better-to-invoke-gdb-from-program-to-print-its-stacktrace
236
-
237
- char exename[512 ];
238
- int len = readlink ( " /proc/self/exe" , exename, sizeof ( exename ) - 1 );
239
- if ( len < 0 )
240
- {
241
- myPrint ( " Could not read link.\n " );
242
- }
243
- else
244
- {
245
- exename[ len ] = 0 ;
246
-
247
- if ( pipe ( gdbpipe ) == 0 )
248
- {
249
- char pidstr[32 ];
250
- snprintf ( pidstr, sizeof pidstr, " --pid=%d" , getpid () );
251
-
252
- gdbpid = fork ();
253
- fprintf ( stderr, " fork returned: %d\n " , gdbpid );
254
- if ( gdbpid == 0 )
255
- {
256
- close ( STDIN_FILENO ); // close stdin
257
- dup ( gdbpipe[0 ] ); // stdin from pipe
258
- close ( gdbpipe[1 ] ); // close writing end
259
-
260
- // attach, backtrace and continue
261
- char btcmd[32 ];
262
- snprintf ( btcmd, sizeof btcmd, " bt full %u" , depth );
263
-
264
- execl ( " /usr/bin/gdb" , " gdb" , " -q" , " -ex" , " set height 0" , " -n" , pidstr, " -ex" , " thread" , " -ex" , btcmd, " -ex" , " cont" , exename, NULL );
265
- perror ( " could not start gdb" );
266
- exit ( 0 );
267
- }
268
- else if ( gdbpid >= 0 )
269
- {
270
- close ( gdbpipe[0 ] ); // close reading end
271
- gdbRunning = 1 ;
272
- }
273
- else
274
- {
275
- myPrint ( " Could not start gdb (%d:%s).\n " , errno, strerror ( errno ) );
276
- }
277
- }
278
- else
279
- {
280
- myPrint ( " Could not create pipe (%d:%s).\n " , errno, strerror ( errno ) );
281
- }
282
- }
283
- }
284
- else
285
- {
286
- myPrint ( " gdb not available.\n " );
287
- }
288
- }
289
- else if ( gdbRunning == 1 )
290
- {
291
- myPrint ( " Stacktrace (using gdb):\n " );
292
- char btcmd[20 ];
293
- snprintf ( btcmd, sizeof btcmd, " bt full %u\n cont\n " , depth );
294
- if ( write ( gdbpipe[1 ], btcmd, strlen ( btcmd ) ) == ( int ) strlen ( btcmd ) && kill ( gdbpid, SIGINT ) == 0 )
295
- return ;
296
-
297
- myPrint ( " write error to gdb [%d:%s]\n " , errno, strerror ( errno ) );
298
- gdbRunning = 0 ;
299
- }
300
- }
301
- #endif
302
-
303
213
if ( access ( " /usr/bin/c++filt" , X_OK ) < 0 )
304
214
{
305
215
myPrint ( " Stacktrace (c++filt NOT FOUND):\n " );
@@ -350,6 +260,55 @@ void dumpBacktrace( unsigned int depth = 0 )
350
260
#endif
351
261
}
352
262
263
+ #if (defined(linux) && !defined(ANDROID)) || defined(__FreeBSD__)
264
+ void qgisCrash ( int signal )
265
+ {
266
+ fprintf ( stderr, " QGIS died on signal %d" , signal );
267
+
268
+ if ( access ( " /usr/bin/gdb" , X_OK ) == 0 )
269
+ {
270
+ // take full stacktrace using gdb
271
+ // http://stackoverflow.com/questions/3151779/how-its-better-to-invoke-gdb-from-program-to-print-its-stacktrace
272
+
273
+ char exename[512 ];
274
+ int len = readlink ( " /proc/self/exe" , exename, sizeof ( exename ) - 1 );
275
+ if ( len < 0 )
276
+ {
277
+ myPrint ( " Could not read link (%d:%s)\n " , errno, strerror ( errno ) );
278
+ }
279
+ else
280
+ {
281
+ exename[ len ] = 0 ;
282
+
283
+ char pidstr[32 ];
284
+ snprintf ( pidstr, sizeof pidstr, " --pid=%d" , getpid () );
285
+
286
+ int gdbpid = fork ();
287
+ if ( gdbpid == 0 )
288
+ {
289
+ // attach, backtrace and continue
290
+ execl ( " /usr/bin/gdbx" , " gdb" , " -q" , " -batch" , " -n" , pidstr, " -ex" , " thread" , " -ex" , " bt full" , exename, NULL );
291
+ perror ( " cannot exec gdb" );
292
+ exit ( 1 );
293
+ }
294
+ else if ( gdbpid >= 0 )
295
+ {
296
+ int status;
297
+ waitpid ( gdbpid, &status, 0 );
298
+ myPrint ( " gdb returned %d\n " , status );
299
+ }
300
+ else
301
+ {
302
+ myPrint ( " Cannot fork (%d:%s)\n " , errno, strerror ( errno ) );
303
+ dumpBacktrace ( 256 );
304
+ }
305
+ }
306
+ }
307
+
308
+ abort ();
309
+ }
310
+ #endif
311
+
353
312
/*
354
313
* Hook into the qWarning/qFatal mechanism so that we can channel messages
355
314
* from libpng to the user.
@@ -392,8 +351,12 @@ void myMessageOutput( QtMsgType type, const char *msg )
392
351
case QtFatalMsg:
393
352
{
394
353
myPrint ( " Fatal: %s\n " , msg );
354
+ #if (defined(linux) && !defined(ANDROID)) || defined(__FreeBSD__)
355
+ qgisCrash ( -1 );
356
+ #else
395
357
dumpBacktrace ( 256 );
396
358
abort (); // deliberately dump core
359
+ #endif
397
360
}
398
361
}
399
362
}
0 commit comments