diff -r 000000000000 -r 1918ee327afb src/corelib/kernel/qcrashhandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/corelib/kernel/qcrashhandler.cpp Mon Jan 11 14:00:40 2010 +0000 @@ -0,0 +1,420 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/************************************************************************* + * + * stacktrace.c 1.2 1998/12/21 + * + * Copyright (c) 1998 by Bjorn Reese + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND + * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. + * + ************************************************************************/ + +#include "qplatformdefs.h" +#include "private/qcrashhandler_p.h" +#include "qbytearray.h" // for qvsnprintf() + +#ifndef QT_NO_CRASHHANDLER + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +QtCrashHandler QSegfaultHandler::callback = 0; + +#if defined(__GLIBC__) && (__GLIBC__ >= 2) && !defined(__UCLIBC__) && !defined(QT_LINUXBASE) +QT_BEGIN_INCLUDE_NAMESPACE +# include "qstring.h" +# include +QT_END_INCLUDE_NAMESPACE + +static void print_backtrace(FILE *outb) +{ + void *stack[128]; + int stack_size = backtrace(stack, sizeof(stack) / sizeof(void *)); + char **stack_symbols = backtrace_symbols(stack, stack_size); + fprintf(outb, "Stack [%d]:\n", stack_size); + if(FILE *cppfilt = popen("c++filt", "rw")) { + dup2(fileno(outb), fileno(cppfilt)); + for(int i = stack_size-1; i>=0; --i) + fwrite(stack_symbols[i], 1, strlen(stack_symbols[i]), cppfilt); + pclose(cppfilt); + } else { + for(int i = stack_size-1; i>=0; --i) + fprintf(outb, "#%d %p [%s]\n", i, stack[i], stack_symbols[i]); + } +} +static void init_backtrace(char **, int) +{ +} + +#else /* Don't use the GLIBC callback */ +/* Code sourced from: */ +QT_BEGIN_INCLUDE_NAMESPACE +#include +#include +#include +#include +#include +#if defined(Q_OS_IRIX) && defined(USE_LIBEXC) +# include +#endif +QT_END_INCLUDE_NAMESPACE + + +static char *globalProgName = NULL; +static bool backtrace_command(FILE *outb, const char *format, ...) +{ + + bool ret = false; + char buffer[50]; + + /* + * Please note that vsnprintf() is not ASync safe (ie. cannot safely + * be used from a signal handler.) If this proves to be a problem + * then the cmd string can be built by more basic functions such as + * strcpy, strcat, and a home-made integer-to-ascii function. + */ + va_list args; + char cmd[512]; + va_start(args, format); + qvsnprintf(cmd, 512, format, args); + va_end(args); + + char *foo = cmd; +#if 0 + foo = "echo hi"; +#endif + if(FILE *inb = popen(foo, "r")) { + while(!feof(inb)) { + int len = fread(buffer, 1, sizeof(buffer), inb); + if(!len) + break; + if(!ret) { + fwrite("Output from ", 1, strlen("Output from "), outb); + strtok(cmd, " "); + fwrite(cmd, 1, strlen(cmd), outb); + fwrite("\n", 1, 1, outb); + ret = true; + } + fwrite(buffer, 1, len, outb); + } + fclose(inb); + } + return ret; +} + +static void init_backtrace(char **argv, int argc) +{ + if(argc >= 1) + globalProgName = argv[0]; +} + +static void print_backtrace(FILE *outb) +{ + /* + * In general dbx seems to do a better job than gdb. + * + * Different dbx implementations require different flags/commands. + */ +#if defined(Q_OS_AIX) + if(backtrace_command(outb, "dbx -a %d 2>/dev/null </dev/null </dev/null <&1 </dev/null </dev/null </dev/null </dev/null </dev/null </dev/null </dev/null </dev/null </dev/null <&1 < </dev/null </dev/null <