summaryrefslogtreecommitdiff
path: root/sal/osl/unx/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'sal/osl/unx/signal.c')
-rw-r--r--sal/osl/unx/signal.c1099
1 files changed, 0 insertions, 1099 deletions
diff --git a/sal/osl/unx/signal.c b/sal/osl/unx/signal.c
deleted file mode 100644
index 1b8a5e51d..000000000
--- a/sal/osl/unx/signal.c
+++ /dev/null
@@ -1,1099 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2000, 2010 Oracle and/or its affiliates.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org. If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- ************************************************************************/
-
-
-/* system headers */
-#include "system.h"
-
-#define MAX_STACK_FRAMES 256
-
-#if defined( MACOSX )
-
-#if defined( INTEL )
-#include "backtrace.h"
-#define INCLUDE_BACKTRACE
-#define STACKTYPE "MacOsX_X86"
-#endif /* INTEL */
-
-#endif /* MACOSX */
-
-#ifdef LINUX
-#include <execinfo.h>
-#include <link.h>
-#define INCLUDE_BACKTRACE
-#define STACKTYPE "Linux"
-#endif
-
-#ifdef SOLARIS
-
-#include "backtrace.h"
-#define INCLUDE_BACKTRACE
-
-#if defined( SPARC )
-#define STACKTYPE "Solaris_Sparc"
-#elif defined( INTEL )
-#define STACKTYPE "Solaris_X86"
-#else
-#define STACKTYPE "Solaris_Unknown"
-#endif
-
-#endif /* defined SOLARIS */
-
-#include <osl/diagnose.h>
-#include <osl/mutex.h>
-#include <osl/signal.h>
-#include <osl/process.h>
-#include <osl/thread.h>
-#include <sal/macros.h>
-#include <rtl/bootstrap.h>
-#include <rtl/digest.h>
-
-#include "file_path_helper.h"
-
-#define ACT_IGNORE 1
-#define ACT_EXIT 2
-#define ACT_SYSTEM 3
-#define ACT_HIDE 4
-#ifdef SAL_ENABLE_CRASH_REPORT
-# define ACT_ABORT 5
-#else
-# define ACT_ABORT ACT_SYSTEM
-#endif
-
-#define MAX_PATH_LEN 2048
-
-typedef struct _oslSignalHandlerImpl
-{
- oslSignalHandlerFunction Handler;
- void* pData;
- struct _oslSignalHandlerImpl* pNext;
-} oslSignalHandlerImpl;
-
-static struct SignalAction
-{
- int Signal;
- int Action;
- void (*Handler)(int);
-} Signals[] =
-{
- { SIGHUP, ACT_IGNORE, NULL }, /* hangup */
- { SIGINT, ACT_EXIT, NULL }, /* interrupt (rubout) */
- { SIGQUIT, ACT_EXIT, NULL }, /* quit (ASCII FS) */
- { SIGILL, ACT_SYSTEM, NULL }, /* illegal instruction (not reset when caught) */
-/* changed from ACT_ABOUT to ACT_SYSTEM to try and get collector to run*/
- { SIGTRAP, ACT_ABORT, NULL }, /* trace trap (not reset when caught) */
-#if ( SIGIOT != SIGABRT )
- { SIGIOT, ACT_ABORT, NULL }, /* IOT instruction */
-#endif
- { SIGABRT, ACT_ABORT, NULL }, /* used by abort, replace SIGIOT in the future */
-#ifdef SIGEMT
- { SIGEMT, ACT_SYSTEM, NULL }, /* EMT instruction */
-/* changed from ACT_ABORT to ACT_SYSTEM to remove handler*/
-/* SIGEMT may also be used by the profiler - so it is probably not a good
-plan to have the new handler use this signal*/
-#endif
- { SIGFPE, ACT_ABORT, NULL }, /* floating point exception */
- { SIGKILL, ACT_SYSTEM, NULL }, /* kill (cannot be caught or ignored) */
- { SIGBUS, ACT_ABORT, NULL }, /* bus error */
- { SIGSEGV, ACT_ABORT, NULL }, /* segmentation violation */
-#ifdef SIGSYS
- { SIGSYS, ACT_ABORT, NULL }, /* bad argument to system call */
-#endif
- { SIGPIPE, ACT_HIDE, NULL }, /* write on a pipe with no one to read it */
- { SIGALRM, ACT_EXIT, NULL }, /* alarm clock */
- { SIGTERM, ACT_EXIT, NULL }, /* software termination signal from kill */
- { SIGUSR1, ACT_SYSTEM, NULL }, /* user defined signal 1 */
- { SIGUSR2, ACT_SYSTEM, NULL }, /* user defined signal 2 */
- { SIGCHLD, ACT_SYSTEM, NULL }, /* child status change */
-#ifdef SIGPWR
- { SIGPWR, ACT_IGNORE, NULL }, /* power-fail restart */
-#endif
- { SIGWINCH, ACT_IGNORE, NULL }, /* window size change */
- { SIGURG, ACT_EXIT, NULL }, /* urgent socket condition */
-#ifdef SIGPOLL
- { SIGPOLL, ACT_EXIT, NULL }, /* pollable event occurred */
-#endif
- { SIGSTOP, ACT_SYSTEM, NULL }, /* stop (cannot be caught or ignored) */
- { SIGTSTP, ACT_SYSTEM, NULL }, /* user stop requested from tty */
- { SIGCONT, ACT_SYSTEM, NULL }, /* stopped process has been continued */
- { SIGTTIN, ACT_SYSTEM, NULL }, /* background tty read attempted */
- { SIGTTOU, ACT_SYSTEM, NULL }, /* background tty write attempted */
- { SIGVTALRM, ACT_EXIT, NULL }, /* virtual timer expired */
- { SIGPROF, ACT_SYSTEM, NULL }, /* profiling timer expired */
-/*Change from ACT_EXIT to ACT_SYSTEM for SIGPROF is so that profiling signals do
-not get taken by the new handler - the new handler does not pass on context
-information which causes 'collect' to crash. This is a way of avoiding
-what looks like a bug in the new handler*/
- { SIGXCPU, ACT_ABORT, NULL }, /* exceeded cpu limit */
- { SIGXFSZ, ACT_ABORT, NULL } /* exceeded file size limit */
-};
-const int NoSignals = sizeof(Signals) / sizeof(struct SignalAction);
-
-static sal_Bool bErrorReportingEnabled = sal_True;
-static sal_Bool bInitSignal = sal_False;
-static oslMutex SignalListMutex;
-static oslSignalHandlerImpl* SignalList;
-static sal_Bool bDoHardKill = sal_False;
-static sal_Bool bSetSEGVHandler = sal_False;
-static sal_Bool bSetWINCHHandler = sal_False;
-static sal_Bool bSetILLHandler = sal_False;
-
-static void SignalHandlerFunction(int);
-
-static void getExecutableName_Impl (rtl_String ** ppstrProgName)
-{
- rtl_uString * ustrProgFile = 0;
- osl_getExecutableFile (&ustrProgFile);
- if (ustrProgFile)
- {
- rtl_uString * ustrProgName = 0;
- osl_systemPathGetFileNameOrLastDirectoryPart (ustrProgFile, &ustrProgName);
- if (ustrProgName != 0)
- {
- rtl_uString2String (
- ppstrProgName,
- rtl_uString_getStr (ustrProgName), rtl_uString_getLength (ustrProgName),
- osl_getThreadTextEncoding(),
- OUSTRING_TO_OSTRING_CVTFLAGS);
- rtl_uString_release (ustrProgName);
- }
- rtl_uString_release (ustrProgFile);
- }
-}
-
-static sal_Bool is_soffice_Impl (void)
-{
- sal_Int32 idx = -1;
- rtl_String * strProgName = 0;
-
- getExecutableName_Impl (&strProgName);
- if (strProgName)
- {
- idx = rtl_str_indexOfStr (rtl_string_getStr (strProgName), "soffice");
- rtl_string_release (strProgName);
- }
- return (idx != -1);
-}
-
-static sal_Bool InitSignal()
-{
- int i;
- struct sigaction act;
- struct sigaction oact;
- sigset_t unset;
-
- if (is_soffice_Impl())
- {
- sal_uInt32 argi;
- sal_uInt32 argc;
- rtl_uString *ustrCommandArg = 0;
-
- argc = osl_getCommandArgCount();
- for ( argi = 0; argi < argc; argi++ )
- {
- if (osl_Process_E_None == osl_getCommandArg (argi, &ustrCommandArg))
- {
- if (0 == rtl_ustr_ascii_compare (rtl_uString_getStr (ustrCommandArg), "-bean"))
- {
- bDoHardKill = sal_True;
- break;
- }
- }
- }
- if (ustrCommandArg)
- {
- rtl_uString_release (ustrCommandArg);
- ustrCommandArg = 0;
- }
-
- // WORKAROUND FOR SEGV HANDLER CONFLICT
- //
- // the java jit needs SIGSEGV for proper work
- // and we need SIGSEGV for the office crashguard
- //
- // TEMPORARY SOLUTION:
- // the office sets the signal handler during startup
- // java can than overwrite it, if needed
- bSetSEGVHandler = sal_True;
-
- // WORKAROUND FOR WINCH HANDLER (SEE ABOVE)
- bSetWINCHHandler = sal_True;
-
- // WORKAROUND FOR ILLEGAL INSTRUCTION HANDLER (SEE ABOVE)
- bSetILLHandler = sal_True;
- }
-
- SignalListMutex = osl_createMutex();
-
- act.sa_handler = SignalHandlerFunction;
- act.sa_flags = SA_RESTART;
-
- sigfillset(&(act.sa_mask));
-
- /* Initialize the rest of the signals */
- for (i = 0; i < NoSignals; i++)
- {
- /* hack: stomcatd is attaching JavaVM wich dont work with an sigaction(SEGV) */
- if ((bSetSEGVHandler || Signals[i].Signal != SIGSEGV)
- && (bSetWINCHHandler || Signals[i].Signal != SIGWINCH)
- && (bSetILLHandler || Signals[i].Signal != SIGILL))
- {
- if (Signals[i].Action != ACT_SYSTEM)
- {
- if (Signals[i].Action == ACT_HIDE)
- {
- struct sigaction ign;
-
- ign.sa_handler = SIG_IGN;
- ign.sa_flags = 0;
- sigemptyset(&ign.sa_mask);
-
- if (sigaction(Signals[i].Signal, &ign, &oact) == 0)
- Signals[i].Handler = oact.sa_handler;
- else
- Signals[i].Handler = SIG_DFL;
- }
- else
- if (sigaction(Signals[i].Signal, &act, &oact) == 0)
- Signals[i].Handler = oact.sa_handler;
- else
- Signals[i].Handler = SIG_DFL;
- }
- }
- }
-
- /* Clear signal mask inherited from parent process (on Mac OS X, upon a
- crash soffice re-execs itself from within the signal handler, so the
- second soffice would have the guilty signal blocked and would freeze upon
- encountering a similar crash again): */
- if (sigemptyset(&unset) < 0 ||
- pthread_sigmask(SIG_SETMASK, &unset, NULL) < 0)
- {
- OSL_TRACE("sigemptyset or pthread_sigmask failed");
- }
-
- return sal_True;
-}
-
-static sal_Bool DeInitSignal()
-{
- int i;
- struct sigaction act;
-
- act.sa_flags = 0;
- sigemptyset(&(act.sa_mask));
-
- /* Initialize the rest of the signals */
- for (i = NoSignals - 1; i >= 0; i--)
- if (Signals[i].Action != ACT_SYSTEM)
- {
- act.sa_handler = Signals[i].Handler;
-
- sigaction(Signals[i].Signal, &act, NULL);
- }
-
- osl_destroyMutex(SignalListMutex);
-
- return sal_False;
-}
-
-#if defined (SAL_ENABLE_CRASH_REPORT) && defined(INCLUDE_BACKTRACE)
-
-/*****************************************************************************/
-/* Generate MD5 checksum */
-/*****************************************************************************/
-
-static sal_uInt32 calc_md5_checksum( const char *filename, sal_uInt8 *pChecksum, sal_uInt32 nChecksumLen )
-{
- sal_uInt32 nBytesProcessed = 0;
-
- FILE *fp = fopen( filename, "r" );
-
- if ( fp )
- {
- rtlDigest digest = rtl_digest_createMD5();
-
- if ( digest )
- {
- size_t nBytesRead;
- sal_uInt8 buffer[4096];
- rtlDigestError error = rtl_Digest_E_None;
-
- while ( rtl_Digest_E_None == error &&
- 0 != (nBytesRead = fread( buffer, 1, sizeof(buffer), fp )) )
- {
- error = rtl_digest_updateMD5( digest, buffer, nBytesRead );
- nBytesProcessed += nBytesRead;
- }
-
- if ( rtl_Digest_E_None == error )
- {
- error = rtl_digest_getMD5( digest, pChecksum, nChecksumLen );
- }
-
- if ( rtl_Digest_E_None != error )
- nBytesProcessed = 0;
-
- rtl_digest_destroyMD5( digest );
- }
-
- fclose( fp );
- }
-
- return nBytesProcessed;
-}
-
-/*****************************************************************************/
-/* Call crash reporter */
-/*****************************************************************************/
-
-/* Helper function to encode and write a string to a stream */
-
-static int fputs_xml( const char *string, FILE *stream )
-{
- int result = 0;
-
- while ( result >= 0 && *string )
- {
- switch( *string )
- {
- case '&':
- result = fputs( "&amp;", stream );
- break;
- case '<':
- result = fputs( "&lt;", stream );
- break;
- case '>':
- result = fputs( "&gt;", stream );
- break;
- default:
- result = fputc( *string, stream );
- break;
- }
-
- string++;
- }
-
- return result;
-}
-#endif
-
-/* Create intermediate files and run crash reporter */
-
-#define REPORTENV_PARAM "-crashreportenv:"
-
-#if defined SAL_ENABLE_CRASH_REPORT && defined INCLUDE_BACKTRACE && \
- defined LINUX
-
-typedef struct
-{
- const char *name;
- ElfW(Off) offset;
-} dynamic_entry;
-
-static int
-callback(struct dl_phdr_info *info, size_t size, void *data)
-{
- const ElfW(Phdr) *pDynamic = NULL;
-
- if (size == sizeof(struct dl_phdr_info))
- {
- int i;
- for (i = 0; i < info->dlpi_phnum; ++i)
- {
- if (info->dlpi_phdr[i].p_type == PT_DYNAMIC)
- {
- pDynamic = &(info->dlpi_phdr[i]);
- break;
- }
- }
- }
-
- if (pDynamic)
- {
- char buffer[100];
- int len;
- char exe[PATH_MAX];
- const char *dsoname = info->dlpi_name;
-
- dynamic_entry* entry = (dynamic_entry*)data;
-
- if (strcmp(dsoname, "") == 0)
- {
- snprintf(buffer, sizeof(buffer), "/proc/%d/exe", getpid());
- if ((len = readlink(buffer, exe, PATH_MAX)) != -1)
- {
- exe[len] = '\0';
- dsoname = exe;
- }
- }
-
- if (strcmp(dsoname, entry->name) == 0)
- {
- entry->offset = pDynamic->p_offset;
- return 1;
- }
- }
- return 0;
-}
-
-/* Get the location of the .dynamic section offset for the given elf file.
- * i.e. same as the "Offset" value shown for DYNAMIC from readelf -l foo
- *
- * We want to know this value so that if the binaries have been modifed
- * by prelink then we can still process the call stack on server side
- * by comparing this value to that of an "un-prelinked but known to be
- * otherwise equivalent" version of those binaries and adjust the call
- * stack addresses by the differences between .dynamic addresses so as
- * to be able to map the prelinked addresses back to the unprelinked
- * addresses
- *
- * cmc@openoffice.org
- */
-static ElfW(Off)
-dynamic_section_offset(const char *name)
-{
- dynamic_entry entry;
-
- entry.name = name;
- entry.offset = 0;
-
- dl_iterate_phdr(callback, &entry);
-
- return entry.offset;
-}
-#endif
-
-static int ReportCrash( int Signal )
-{
-#ifdef SAL_ENABLE_CRASH_REPORT
- static sal_Bool bCrashReporterExecuted = sal_False;
- sal_Bool bAutoCrashReport = sal_False;
-
- sal_uInt32 argi;
- sal_uInt32 argc;
- rtl_uString *ustrCommandArg = NULL;
-
- if ( !bErrorReportingEnabled )
- return -1;
-
- argc = osl_getCommandArgCount();
-
- for ( argi = 0; argi < argc; argi++ )
- {
- if ( osl_Process_E_None == osl_getCommandArg( argi, &ustrCommandArg ) )
- {
- if ( 0 == rtl_ustr_ascii_compare( rtl_uString_getStr( ustrCommandArg ), "-nocrashreport" ) )
- {
- rtl_uString_release( ustrCommandArg );
- return -1;
- }
- else if ( 0 == rtl_ustr_ascii_compare( rtl_uString_getStr( ustrCommandArg ), "-autocrashreport" ) )
- {
- bAutoCrashReport = sal_True;
- }
- else if ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength(
- rtl_uString_getStr( ustrCommandArg ), rtl_uString_getLength( ustrCommandArg ),
- REPORTENV_PARAM, strlen(REPORTENV_PARAM) )
- )
- {
- rtl_uString *ustrEnvironment = NULL;
- rtl_String *strEnv = NULL;
-
- rtl_uString_newFromStr( &ustrEnvironment, rtl_uString_getStr( ustrCommandArg ) + strlen(REPORTENV_PARAM) );
-
- if ( ustrEnvironment )
- {
- rtl_uString2String(
- &strEnv,
- rtl_uString_getStr( ustrEnvironment ), rtl_uString_getLength( ustrEnvironment ),
- osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS
- );
-
- if ( strEnv )
- {
- putenv( rtl_string_getStr( strEnv ) );
- rtl_string_release( strEnv );
- }
-
- rtl_uString_release( ustrEnvironment );
- }
-
- }
-
- }
- }
-
- if ( ustrCommandArg )
- rtl_uString_release( ustrCommandArg );
-
- if ( !bCrashReporterExecuted )
- {
- int i;
- /* struct sigaction act; */
-
- for (i = 0; i < NoSignals; i++)
- {
- if (Signals[i].Signal == Signal && Signals[i].Action == ACT_ABORT )
- {
- int ret;
- char szShellCmd[512] = { '\0' };
- char *pXMLTempName = NULL;
- char *pStackTempName = NULL;
- char *pChecksumTempName = NULL;
-
-#ifdef INCLUDE_BACKTRACE
- char szXMLTempNameBuffer[L_tmpnam];
- char szChecksumTempNameBuffer[L_tmpnam];
- char szStackTempNameBuffer[L_tmpnam];
-
- void *stackframes[MAX_STACK_FRAMES];
- int iFrame;
- int nFrames = backtrace( stackframes, SAL_N_ELEMENTS(stackframes) );
-
- FILE *xmlout = NULL, *stackout = NULL, *checksumout = NULL;
- int fdxml, fdstk, fdchksum;
-
- strncpy( szXMLTempNameBuffer, P_tmpdir, sizeof(szXMLTempNameBuffer) );
- strncat( szXMLTempNameBuffer, "/crxmlXXXXXX", sizeof(szXMLTempNameBuffer) );
-
- strncpy( szStackTempNameBuffer, P_tmpdir, sizeof(szStackTempNameBuffer) );
- strncat( szStackTempNameBuffer, "/crstkXXXXXX", sizeof(szStackTempNameBuffer) );
-
- strncpy( szChecksumTempNameBuffer, P_tmpdir, sizeof(szChecksumTempNameBuffer) );
- strncat( szChecksumTempNameBuffer, "/crchkXXXXXX", sizeof(szChecksumTempNameBuffer) );
-
- fdxml = mkstemp(szXMLTempNameBuffer);
- fdstk = mkstemp(szStackTempNameBuffer);
- fdchksum = mkstemp(szChecksumTempNameBuffer);
-
- xmlout = fdopen( fdxml , "w" );
- stackout = fdopen( fdstk , "w" );
- checksumout = fdopen( fdchksum, "w" );
-
- pXMLTempName = szXMLTempNameBuffer;
- pStackTempName = szStackTempNameBuffer;
- pChecksumTempName = szChecksumTempNameBuffer;
-
-
- if ( xmlout && stackout && checksumout )
- {
- fprintf( xmlout, "<errormail:Stack type=\"%s\">\n", STACKTYPE );
-
- fprintf( checksumout, "<errormail:Checksums type=\"MD5\">\n" );
-
- for ( iFrame = 0; iFrame < nFrames; iFrame++ )
- {
- Dl_info dl_info;
-
- fprintf( stackout, "0x%" SAL_PRIxUINTPTR ":",
- SAL_INT_CAST(sal_uIntPtr, stackframes[iFrame]) );
-
- fprintf( xmlout, "<errormail:StackInfo pos=\"%d\" ip=\"0x%" SAL_PRIxUINTPTR "\"",
- iFrame,
- SAL_INT_CAST(sal_uIntPtr, stackframes[iFrame])
- );
-
- memset( &dl_info, 0, sizeof(dl_info) );
-
- /* dladdr may fail */
- if ( dladdr( stackframes[iFrame], &dl_info) )
- {
- const char *dli_fname = NULL;
- char *dli_fdir = NULL;
- char szDirectory[PATH_MAX];
- char szCanonicDirectory[PATH_MAX];
-
- /* Don't expect that dladdr filled all members of dl_info */
-
- dli_fname = dl_info.dli_fname ? strrchr( dl_info.dli_fname, '/' ) : NULL;
- if ( dli_fname )
- {
- ++dli_fname;
- memcpy( szDirectory, dl_info.dli_fname, dli_fname - dl_info.dli_fname );
- szDirectory[dli_fname - dl_info.dli_fname] = 0;
-
- dli_fdir = realpath( szDirectory, szCanonicDirectory ) ? szCanonicDirectory : szDirectory;
-
- if ( *dli_fdir && dli_fdir[ strlen(dli_fdir) - 1 ] != '/' )
- strcat( dli_fdir, "/" );
- }
- else
- dli_fname = dl_info.dli_fname;
-
- /* create checksum of library on stack */
- if ( dli_fname )
- {
- sal_uInt8 checksum[RTL_DIGEST_LENGTH_MD5];
-
- sal_uInt32 nBytesProcessed = calc_md5_checksum(
- dl_info.dli_fname, checksum, sizeof(checksum) );
- if ( nBytesProcessed )
- {
- int j;
-
- fprintf( checksumout, "<errormail:Checksum sum=\"0x" );
- for ( j = 0; j < 16; fprintf( checksumout, "%02X", checksum[j++] ) );
- fprintf( checksumout,
- "\" bytes=\"%lu\" file=\"%s\"/>\n",
- SAL_INT_CAST(
- unsigned long, nBytesProcessed),
- dli_fname );
- }
- }
-
- if ( dl_info.dli_fbase && dl_info.dli_fname )
- {
-#ifdef LINUX
- ElfW(Off) dynamic_offset = dynamic_section_offset(dl_info.dli_fname);
- fprintf( stackout, " 0x%" SAL_PRI_SIZET "x:", dynamic_offset);
-#endif
-
- fprintf( stackout, " %s + 0x%" SAL_PRI_PTRDIFFT "x",
- dl_info.dli_fname,
- (char*)stackframes[iFrame] - (char*)dl_info.dli_fbase
- );
-
- fprintf( xmlout, " rel=\"0x%" SAL_PRI_PTRDIFFT "x\"", (char *)stackframes[iFrame] - (char *)dl_info.dli_fbase );
- if ( dli_fname )
- fprintf( xmlout, " name=\"%s\"", dli_fname );
-
- if ( dli_fdir )
- fprintf( xmlout, " path=\"%s\"", dli_fdir );
-
-#ifdef LINUX
- fprintf( xmlout, " dynamicoffset=\"0x%" SAL_PRI_SIZET "x\"", dynamic_offset );
-#endif
- }
- else
- fprintf( stackout, " ????????" );
-
- if ( dl_info.dli_sname && dl_info.dli_saddr )
- {
- fputs( " (", stackout );
- fputs_xml( dl_info.dli_sname, stackout );
- fprintf( stackout, " + 0x%" SAL_PRI_PTRDIFFT "x)",
- (char*)stackframes[iFrame] - (char*)dl_info.dli_saddr );
-
- fputs( " ordinal=\"", xmlout );
- fputs_xml( dl_info.dli_sname, xmlout );
- fprintf( xmlout, "+0x%" SAL_PRI_PTRDIFFT "x\"",
- (char *)stackframes[iFrame] - (char *)dl_info.dli_saddr );
- }
-
- }
- else /* dladdr failed */
- {
- fprintf( stackout, " ????????" );
- }
-
- fprintf( stackout, "\n" );
- fprintf( xmlout, "/>\n" );
-
- }
-
- fprintf( xmlout, "</errormail:Stack>\n" );
- fprintf( checksumout, "</errormail:Checksums>\n" );
- }
- else
- {
- pXMLTempName = NULL;
- pStackTempName = NULL;
- pChecksumTempName = NULL;
- }
-
- if ( stackout )
- fclose( stackout );
- if ( xmlout )
- fclose( xmlout );
- if ( checksumout )
- fclose( checksumout );
-
- if ( pXMLTempName && pChecksumTempName && pStackTempName )
-#endif /* INCLUDE_BACKTRACE */
- {
- rtl_uString * crashrep_url = NULL;
- rtl_uString * crashrep_path = NULL;
- rtl_String * crashrep_path_system = NULL;
- rtl_string2UString(
- &crashrep_url,
- RTL_CONSTASCII_USTRINGPARAM(
- "$BRAND_BASE_DIR/program/crashrep"),
- OSTRING_TO_OUSTRING_CVTFLAGS);
- rtl_bootstrap_expandMacros(&crashrep_url);
- osl_getSystemPathFromFileURL(crashrep_url, &crashrep_path);
- rtl_uString2String(
- &crashrep_path_system,
- rtl_uString_getStr(crashrep_path),
- rtl_uString_getLength(crashrep_path),
- osl_getThreadTextEncoding(),
- (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
- | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR));
- rtl_uString_release(crashrep_url);
- rtl_uString_release(crashrep_path);
-#if defined INCLUDE_BACKTRACE && (defined LINUX || defined MACOSX)
- snprintf( szShellCmd, SAL_N_ELEMENTS(szShellCmd),
- "%s -p %d -s %d -xml %s -chksum %s -stack %s -noui%s",
- rtl_string_getStr(crashrep_path_system),
- getpid(),
- Signal,
- pXMLTempName,
- pChecksumTempName,
- pStackTempName,
- bAutoCrashReport ? " -send" : "" );
-#elif defined INCLUDE_BACKTRACE && defined SOLARIS
- snprintf( szShellCmd, SAL_N_ELEMENTS(szShellCmd),
- "%s -p %d -s %d -xml %s -chksum %s -noui%s",
- rtl_string_getStr(crashrep_path_system),
- getpid(),
- Signal,
- pXMLTempName,
- pChecksumTempName,
- bAutoCrashReport ? " -send" : "" );
-#else
- snprintf( szShellCmd, SAL_N_ELEMENTS(szShellCmd),
- "%s -p %d -s %d -noui%s",
- rtl_string_getStr(crashrep_path_system),
- getpid(), Signal, bAutoCrashReport ? " -send" : "" );
-#endif
- rtl_string_release(crashrep_path_system);
- }
-
- ret = szShellCmd[0] == '\0' ? -1 : system( szShellCmd );
-
- if ( pXMLTempName )
- unlink( pXMLTempName );
-
- if ( pStackTempName )
- unlink( pStackTempName );
-
- if ( pChecksumTempName )
- unlink( pChecksumTempName );
-
- if ( -1 != ret )
- {
- bCrashReporterExecuted = sal_True;
- return 1;
- }
- else
- return -1;
-
- }
- }
-
- return 0;
- }
-
- return 1;
-#else /* defined SAL_ENABLE_CRASH_REPORT */
- /* the utility crash_report is not build, so do the same as when
- the option -nocrashreport is used */
- (void) Signal; // avoid warnings
- return -1;
-#endif /* defined SAL_ENABLE_CRASH_REPORT */
-}
-
-static void PrintStack( int sig )
-{
-#ifdef INCLUDE_BACKTRACE
- void *buffer[MAX_STACK_FRAMES];
- int size = backtrace( buffer, SAL_N_ELEMENTS(buffer) );
-#endif
-
- fprintf( stderr, "\n\nFatal exception: Signal %d\n", sig );
-
-#if defined( MACOSX ) && !defined( INCLUDE_BACKTRACE )
- fprintf( stderr, "Please turn on Enable Crash Reporting and\nAutomatic Display of Crashlogs in the Console application\n" );
-#else
-#ifdef INCLUDE_BACKTRACE
- if ( size > 0 )
- {
- fputs( "Stack:\n", stderr );
- backtrace_symbols_fd( buffer, size, fileno(stderr) );
- }
-#endif
-#endif
-}
-
-static oslSignalAction CallSignalHandler(oslSignalInfo *pInfo)
-{
- oslSignalHandlerImpl* pHandler = SignalList;
- oslSignalAction Action = osl_Signal_ActCallNextHdl;
-
- while (pHandler != NULL)
- {
- if ((Action = pHandler->Handler(pHandler->pData, pInfo))
- != osl_Signal_ActCallNextHdl)
- break;
-
- pHandler = pHandler->pNext;
- }
-
- return Action;
-}
-
-void CallSystemHandler(int Signal)
-{
- int i;
- struct sigaction act;
-
- for (i = 0; i < NoSignals; i++)
- {
- if (Signals[i].Signal == Signal)
- break;
- }
-
- if (i < NoSignals)
- {
- if ((Signals[i].Handler == NULL) ||
- (Signals[i].Handler == SIG_DFL) ||
- (Signals[i].Handler == SIG_IGN) ||
- (Signals[i].Handler == SIG_ERR))
- {
- switch (Signals[i].Action)
- {
- case ACT_EXIT: /* terminate */
- /* prevent dumping core on exit() */
- _exit(255);
- break;
-
- case ACT_ABORT: /* terminate witch core dump */
- ReportCrash( Signal );
- act.sa_handler = SIG_DFL;
- act.sa_flags = 0;
- sigemptyset(&(act.sa_mask));
- sigaction(SIGABRT, &act, NULL);
- PrintStack( Signal );
- abort();
- break;
-
- case ACT_IGNORE: /* ignore */
- break;
-
- default: /* should never happen */
- OSL_ASSERT(0);
- }
- }
- else
- (*Signals[i].Handler)(Signal);
- }
-}
-
-
-/*****************************************************************************/
-/* SignalHandlerFunction */
-/*****************************************************************************/
-void SignalHandlerFunction(int Signal)
-{
- oslSignalInfo Info;
- struct sigaction act;
-
- Info.UserSignal = Signal;
- Info.UserData = NULL;
-
- switch (Signal)
- {
- case SIGBUS:
- case SIGILL:
- case SIGSEGV:
- case SIGIOT:
-#if ( SIGIOT != SIGABRT )
- case SIGABRT:
-#endif
- Info.Signal = osl_Signal_AccessViolation;
- break;
-
- case -1:
- Info.Signal = osl_Signal_IntegerDivideByZero;
- break;
-
- case SIGFPE:
- Info.Signal = osl_Signal_FloatDivideByZero;
- break;
-
- case SIGINT:
- case SIGTERM:
- case SIGQUIT:
- case SIGHUP:
- Info.Signal = osl_Signal_Terminate;
- break;
-
- default:
- Info.Signal = osl_Signal_System;
- break;
- }
-
- ReportCrash( Signal );
-
- /* Portal Demo HACK !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
- if (bDoHardKill && (Info.Signal == osl_Signal_AccessViolation))
- _exit(255);
- /* Portal Demo HACK !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
-
-
- switch (CallSignalHandler(&Info))
- {
- case osl_Signal_ActCallNextHdl:
- CallSystemHandler(Signal);
- break;
-
- case osl_Signal_ActAbortApp:
- ReportCrash( Signal );
- act.sa_handler = SIG_DFL;
- act.sa_flags = 0;
- sigemptyset(&(act.sa_mask));
- sigaction(SIGABRT, &act, NULL);
- PrintStack( Signal );
- abort();
- break;
-
- case osl_Signal_ActKillApp:
- /* prevent dumping core on exit() */
- _exit(255);
- break;
- default:
- break;
- }
-}
-
-/*****************************************************************************/
-/* osl_addSignalHandler */
-/*****************************************************************************/
-oslSignalHandler SAL_CALL osl_addSignalHandler(oslSignalHandlerFunction Handler, void* pData)
-{
- oslSignalHandlerImpl* pHandler;
-
- OSL_ASSERT(Handler != NULL);
- if ( Handler == 0 )
- {
- return 0;
- }
-
- if (! bInitSignal)
- bInitSignal = InitSignal();
-
- pHandler = (oslSignalHandlerImpl*) calloc(1, sizeof(oslSignalHandlerImpl));
-
- if (pHandler != NULL)
- {
- pHandler->Handler = Handler;
- pHandler->pData = pData;
-
- osl_acquireMutex(SignalListMutex);
-
- pHandler->pNext = SignalList;
- SignalList = pHandler;
-
- osl_releaseMutex(SignalListMutex);
-
- return (pHandler);
- }
-
- return (NULL);
-}
-
-/*****************************************************************************/
-/* osl_removeSignalHandler */
-/*****************************************************************************/
-sal_Bool SAL_CALL osl_removeSignalHandler(oslSignalHandler Handler)
-{
- oslSignalHandlerImpl *pHandler, *pPrevious = NULL;
-
- OSL_ASSERT(Handler != NULL);
-
- if (! bInitSignal)
- bInitSignal = InitSignal();
-
- osl_acquireMutex(SignalListMutex);
-
- pHandler = SignalList;
-
- while (pHandler != NULL)
- {
- if (pHandler == Handler)
- {
- if (pPrevious)
- pPrevious->pNext = pHandler->pNext;
- else
- SignalList = pHandler->pNext;
-
- osl_releaseMutex(SignalListMutex);
-
- if (SignalList == NULL)
- bInitSignal = DeInitSignal();
-
- free(pHandler);
-
- return (sal_True);
- }
-
- pPrevious = pHandler;
- pHandler = pHandler->pNext;
- }
-
- osl_releaseMutex(SignalListMutex);
-
- return (sal_False);
-}
-
-/*****************************************************************************/
-/* osl_raiseSignal */
-/*****************************************************************************/
-oslSignalAction SAL_CALL osl_raiseSignal(sal_Int32 UserSignal, void* UserData)
-{
- oslSignalInfo Info;
- oslSignalAction Action;
-
- if (! bInitSignal)
- bInitSignal = InitSignal();
-
- osl_acquireMutex(SignalListMutex);
-
- Info.Signal = osl_Signal_User;
- Info.UserSignal = UserSignal;
- Info.UserData = UserData;
-
- Action = CallSignalHandler(&Info);
-
- osl_releaseMutex(SignalListMutex);
-
- return (Action);
-}
-
-/*****************************************************************************/
-/* osl_setErrorReporting */
-/*****************************************************************************/
-sal_Bool SAL_CALL osl_setErrorReporting( sal_Bool bEnable )
-{
- sal_Bool bOld = bErrorReportingEnabled;
- bErrorReportingEnabled = bEnable;
-
- return bOld;
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */