Skip to content

Commit a3c1326

Browse files
committed
use gdb only for crash reports (followup e4fed74)
1 parent 166b9cf commit a3c1326

File tree

1 file changed

+55
-92
lines changed

1 file changed

+55
-92
lines changed

src/app/main.cpp

+55-92
Original file line numberDiff line numberDiff line change
@@ -191,13 +191,6 @@ LONG WINAPI qgisCrashDump( struct _EXCEPTION_POINTERS *ExceptionInfo )
191191
}
192192
#endif
193193

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-
201194
void myPrint( const char *fmt, ... )
202195
{
203196
va_list ap;
@@ -211,95 +204,12 @@ void myPrint( const char *fmt, ... )
211204
#endif
212205
}
213206

214-
void dumpBacktrace( unsigned int depth = 0 )
207+
static void dumpBacktrace( unsigned int depth )
215208
{
216209
if ( depth == 0 )
217-
depth = 10;
210+
depth = 20;
218211

219212
#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\ncont\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-
303213
if ( access( "/usr/bin/c++filt", X_OK ) < 0 )
304214
{
305215
myPrint( "Stacktrace (c++filt NOT FOUND):\n" );
@@ -350,6 +260,55 @@ void dumpBacktrace( unsigned int depth = 0 )
350260
#endif
351261
}
352262

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+
353312
/*
354313
* Hook into the qWarning/qFatal mechanism so that we can channel messages
355314
* from libpng to the user.
@@ -392,8 +351,12 @@ void myMessageOutput( QtMsgType type, const char *msg )
392351
case QtFatalMsg:
393352
{
394353
myPrint( "Fatal: %s\n", msg );
354+
#if (defined(linux) && !defined(ANDROID)) || defined(__FreeBSD__)
355+
qgisCrash( -1 );
356+
#else
395357
dumpBacktrace( 256 );
396358
abort(); // deliberately dump core
359+
#endif
397360
}
398361
}
399362
}

0 commit comments

Comments
 (0)