LCOV - code coverage report
Current view: top level - sal/osl/unx - signal.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 97 185 52.4 %
Date: 2012-08-25 Functions: 7 13 53.8 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 45 99 45.5 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : 
      30                 :            : /* system headers */
      31                 :            : #include "system.h"
      32                 :            : 
      33                 :            : #define MAX_STACK_FRAMES 256
      34                 :            : 
      35                 :            : #if defined( MACOSX )
      36                 :            : 
      37                 :            : #if defined( INTEL )
      38                 :            : #include "backtrace.h"
      39                 :            : #define INCLUDE_BACKTRACE
      40                 :            : #define STACKTYPE "MacOsX_X86"
      41                 :            : #endif /* INTEL */
      42                 :            : 
      43                 :            : #endif /* MACOSX */
      44                 :            : 
      45                 :            : #ifdef LINUX
      46                 :            : #include <execinfo.h>
      47                 :            : #include <link.h>
      48                 :            : #define INCLUDE_BACKTRACE
      49                 :            : #define STACKTYPE "Linux"
      50                 :            : #endif
      51                 :            : 
      52                 :            : #ifdef SOLARIS
      53                 :            : 
      54                 :            : #include "backtrace.h"
      55                 :            : #define INCLUDE_BACKTRACE
      56                 :            : 
      57                 :            : #if defined( SPARC )
      58                 :            : #define STACKTYPE "Solaris_Sparc"
      59                 :            : #elif defined( INTEL )
      60                 :            : #define STACKTYPE "Solaris_X86"
      61                 :            : #else
      62                 :            : #define STACKTYPE "Solaris_Unknown"
      63                 :            : #endif
      64                 :            : 
      65                 :            : #endif /* defined SOLARIS */
      66                 :            : 
      67                 :            : #include <osl/diagnose.h>
      68                 :            : #include <osl/mutex.h>
      69                 :            : #include <osl/signal.h>
      70                 :            : #include <osl/process.h>
      71                 :            : #include <osl/thread.h>
      72                 :            : #include <sal/macros.h>
      73                 :            : #include <rtl/bootstrap.h>
      74                 :            : #include <rtl/digest.h>
      75                 :            : 
      76                 :            : #include "file_path_helper.h"
      77                 :            : 
      78                 :            : #define ACT_IGNORE  1
      79                 :            : #define ACT_EXIT    2
      80                 :            : #define ACT_SYSTEM  3
      81                 :            : #define ACT_HIDE    4
      82                 :            : #ifdef SAL_ENABLE_CRASH_REPORT
      83                 :            : #    define ACT_ABORT   5
      84                 :            : #else
      85                 :            : #    define ACT_ABORT   ACT_SYSTEM
      86                 :            : #endif
      87                 :            : 
      88                 :            : #if defined(HAVE_MEMCHECK_H)
      89                 :            : #include <memcheck.h>
      90                 :            : #endif
      91                 :            : 
      92                 :            : typedef struct _oslSignalHandlerImpl
      93                 :            : {
      94                 :            :     oslSignalHandlerFunction      Handler;
      95                 :            :     void*                         pData;
      96                 :            :     struct _oslSignalHandlerImpl* pNext;
      97                 :            : } oslSignalHandlerImpl;
      98                 :            : 
      99                 :            : static struct SignalAction
     100                 :            : {
     101                 :            :     int Signal;
     102                 :            :     int Action;
     103                 :            :     void (*Handler)(int);
     104                 :            : } Signals[] =
     105                 :            : {
     106                 :            :     { SIGHUP,    ACT_HIDE, NULL },    /* hangup */
     107                 :            :     { SIGINT,    ACT_EXIT,   NULL },    /* interrupt (rubout) */
     108                 :            :     { SIGQUIT,   ACT_EXIT,  NULL },    /* quit (ASCII FS) */
     109                 :            :     { SIGILL,    ACT_SYSTEM,  NULL },    /* illegal instruction (not reset when caught) */
     110                 :            : /* changed from ACT_ABOUT to ACT_SYSTEM to try and get collector to run*/
     111                 :            :     { SIGTRAP,   ACT_ABORT,  NULL },    /* trace trap (not reset when caught) */
     112                 :            : #if ( SIGIOT != SIGABRT )
     113                 :            :     { SIGIOT,    ACT_ABORT,  NULL },    /* IOT instruction */
     114                 :            : #endif
     115                 :            :     { SIGABRT,   ACT_ABORT,  NULL },    /* used by abort, replace SIGIOT in the future */
     116                 :            : #ifdef SIGEMT
     117                 :            :     { SIGEMT,    ACT_SYSTEM,  NULL },    /* EMT instruction */
     118                 :            : /* changed from ACT_ABORT to ACT_SYSTEM to remove handler*/
     119                 :            : /* SIGEMT may also be used by the profiler - so it is probably not a good
     120                 :            : plan to have the new handler use this signal*/
     121                 :            : #endif
     122                 :            :     { SIGFPE,    ACT_ABORT,  NULL },    /* floating point exception */
     123                 :            :     { SIGKILL,   ACT_SYSTEM, NULL },    /* kill (cannot be caught or ignored) */
     124                 :            :     { SIGBUS,    ACT_ABORT,  NULL },    /* bus error */
     125                 :            :     { SIGSEGV,   ACT_ABORT,  NULL },    /* segmentation violation */
     126                 :            : #ifdef SIGSYS
     127                 :            :     { SIGSYS,    ACT_ABORT,  NULL },    /* bad argument to system call */
     128                 :            : #endif
     129                 :            :     { SIGPIPE,   ACT_HIDE,   NULL },    /* write on a pipe with no one to read it */
     130                 :            :     { SIGALRM,   ACT_EXIT,   NULL },    /* alarm clock */
     131                 :            :     { SIGTERM,   ACT_EXIT,   NULL },    /* software termination signal from kill */
     132                 :            :     { SIGUSR1,   ACT_SYSTEM, NULL },    /* user defined signal 1 */
     133                 :            :     { SIGUSR2,   ACT_SYSTEM, NULL },    /* user defined signal 2 */
     134                 :            :     { SIGCHLD,   ACT_SYSTEM, NULL },    /* child status change */
     135                 :            : #ifdef SIGPWR
     136                 :            :     { SIGPWR,    ACT_IGNORE, NULL },    /* power-fail restart */
     137                 :            : #endif
     138                 :            :     { SIGWINCH,  ACT_IGNORE, NULL },    /* window size change */
     139                 :            :     { SIGURG,    ACT_EXIT,   NULL },    /* urgent socket condition */
     140                 :            : #ifdef SIGPOLL
     141                 :            :     { SIGPOLL,   ACT_EXIT,   NULL },    /* pollable event occurred */
     142                 :            : #endif
     143                 :            :     { SIGSTOP,   ACT_SYSTEM, NULL },    /* stop (cannot be caught or ignored) */
     144                 :            :     { SIGTSTP,   ACT_SYSTEM, NULL },    /* user stop requested from tty */
     145                 :            :     { SIGCONT,   ACT_SYSTEM, NULL },    /* stopped process has been continued */
     146                 :            :     { SIGTTIN,   ACT_SYSTEM, NULL },    /* background tty read attempted */
     147                 :            :     { SIGTTOU,   ACT_SYSTEM, NULL },    /* background tty write attempted */
     148                 :            :     { SIGVTALRM, ACT_EXIT,   NULL },    /* virtual timer expired */
     149                 :            :     { SIGPROF,   ACT_SYSTEM,   NULL },    /* profiling timer expired */
     150                 :            : /*Change from ACT_EXIT to ACT_SYSTEM for SIGPROF is so that profiling signals do
     151                 :            : not get taken by the new handler - the new handler does not pass on context
     152                 :            : information which causes 'collect' to crash. This is a way of avoiding
     153                 :            : what looks like a bug in the new handler*/
     154                 :            :     { SIGXCPU,   ACT_ABORT,  NULL },    /* exceeded cpu limit */
     155                 :            :     { SIGXFSZ,   ACT_ABORT,  NULL }     /* exceeded file size limit */
     156                 :            : };
     157                 :            : const int NoSignals = sizeof(Signals) / sizeof(struct SignalAction);
     158                 :            : 
     159                 :            : static sal_Bool               bErrorReportingEnabled = sal_True;
     160                 :            : static sal_Bool               bInitSignal = sal_False;
     161                 :            : static oslMutex               SignalListMutex;
     162                 :            : static oslSignalHandlerImpl*  SignalList;
     163                 :            : static sal_Bool               bDoHardKill = sal_False;
     164                 :            : static sal_Bool               bSetSEGVHandler = sal_False;
     165                 :            : static sal_Bool               bSetWINCHHandler = sal_False;
     166                 :            : static sal_Bool               bSetILLHandler = sal_False;
     167                 :            : 
     168                 :            : static void SignalHandlerFunction(int);
     169                 :            : 
     170                 :        322 : static void getExecutableName_Impl (rtl_String ** ppstrProgName)
     171                 :            : {
     172                 :        322 :     rtl_uString * ustrProgFile = 0;
     173                 :        322 :     osl_getExecutableFile (&ustrProgFile);
     174         [ +  - ]:        322 :     if (ustrProgFile)
     175                 :            :     {
     176                 :        322 :         rtl_uString * ustrProgName = 0;
     177                 :        322 :         osl_systemPathGetFileNameOrLastDirectoryPart (ustrProgFile, &ustrProgName);
     178         [ +  - ]:        322 :         if (ustrProgName != 0)
     179                 :            :         {
     180                 :        644 :             rtl_uString2String (
     181                 :            :                 ppstrProgName,
     182                 :        322 :                 rtl_uString_getStr (ustrProgName), rtl_uString_getLength (ustrProgName),
     183                 :        322 :                 osl_getThreadTextEncoding(),
     184                 :            :                 OUSTRING_TO_OSTRING_CVTFLAGS);
     185                 :        322 :             rtl_uString_release (ustrProgName);
     186                 :            :         }
     187                 :        322 :         rtl_uString_release (ustrProgFile);
     188                 :            :     }
     189                 :        322 : }
     190                 :            : 
     191                 :        322 : static sal_Bool is_soffice_Impl (void)
     192                 :            : {
     193                 :        322 :     sal_Int32    idx       = -1;
     194                 :        322 :     rtl_String * strProgName = 0;
     195                 :            : 
     196                 :        322 :     getExecutableName_Impl (&strProgName);
     197         [ +  - ]:        322 :     if (strProgName)
     198                 :            :     {
     199                 :        322 :         idx = rtl_str_indexOfStr (rtl_string_getStr (strProgName), "soffice");
     200                 :        322 :         rtl_string_release (strProgName);
     201                 :            :     }
     202                 :        322 :     return (idx != -1);
     203                 :            : }
     204                 :            : 
     205                 :        322 : static sal_Bool InitSignal()
     206                 :            : {
     207                 :            :     int i;
     208                 :            :     struct sigaction act;
     209                 :            :     struct sigaction oact;
     210                 :            :     sigset_t unset;
     211                 :            : 
     212         [ +  + ]:        322 :     if (is_soffice_Impl())
     213                 :            :     {
     214                 :            :         sal_uInt32  argi;
     215                 :            :         sal_uInt32  argc;
     216                 :        158 :         rtl_uString *ustrCommandArg = 0;
     217                 :            : 
     218                 :        158 :         argc = osl_getCommandArgCount();
     219         [ +  + ]:       1426 :         for ( argi = 0; argi < argc; argi++ )
     220                 :            :         {
     221         [ +  - ]:       1268 :             if (osl_Process_E_None == osl_getCommandArg (argi, &ustrCommandArg))
     222                 :            :             {
     223         [ -  + ]:       1268 :                 if (0 == rtl_ustr_ascii_compare (rtl_uString_getStr (ustrCommandArg), "-bean"))
     224                 :            :                 {
     225                 :          0 :                     bDoHardKill = sal_True;
     226                 :          0 :                     break;
     227                 :            :                 }
     228                 :            :             }
     229                 :            :         }
     230         [ +  - ]:        158 :         if (ustrCommandArg)
     231                 :            :         {
     232                 :        158 :             rtl_uString_release (ustrCommandArg);
     233                 :        158 :             ustrCommandArg = 0;
     234                 :            :         }
     235                 :            : 
     236                 :            :         // WORKAROUND FOR SEGV HANDLER CONFLICT
     237                 :            :         //
     238                 :            :         // the java jit needs SIGSEGV for proper work
     239                 :            :         // and we need SIGSEGV for the office crashguard
     240                 :            :         //
     241                 :            :         // TEMPORARY SOLUTION:
     242                 :            :         //   the office sets the signal handler during startup
     243                 :            :         //   java can than overwrite it, if needed
     244                 :        158 :         bSetSEGVHandler = sal_True;
     245                 :            : 
     246                 :            :         // WORKAROUND FOR WINCH HANDLER (SEE ABOVE)
     247                 :        158 :         bSetWINCHHandler = sal_True;
     248                 :            : 
     249                 :            :         // WORKAROUND FOR ILLEGAL INSTRUCTION HANDLER (SEE ABOVE)
     250                 :        158 :         bSetILLHandler = sal_True;
     251                 :            :     }
     252                 :            : 
     253                 :            : #ifdef DBG_UTIL
     254                 :            :     bSetSEGVHandler = bSetWINCHHandler = bSetILLHandler = bDoHardKill = sal_False;
     255                 :            : #endif
     256                 :            : 
     257                 :        322 :     SignalListMutex = osl_createMutex();
     258                 :            : 
     259                 :        322 :     act.sa_handler = SignalHandlerFunction;
     260                 :        322 :     act.sa_flags   = SA_RESTART;
     261                 :            : 
     262                 :        322 :     sigfillset(&(act.sa_mask));
     263                 :            : 
     264                 :            :     /* Initialize the rest of the signals */
     265         [ +  + ]:       9982 :     for (i = 0; i < NoSignals; ++i)
     266                 :            :     {
     267                 :            : #if defined(HAVE_MEMCHECK_H)
     268                 :            :         if (Signals[i].Signal == SIGUSR2 && RUNNING_ON_VALGRIND)
     269                 :            :             Signals[i].Action = ACT_IGNORE;
     270                 :            : #endif
     271                 :            : 
     272                 :            :         /* hack: stomcatd is attaching JavaVM wich dont work with an sigaction(SEGV) */
     273 [ +  + ][ +  + ]:       9660 :         if ((bSetSEGVHandler || Signals[i].Signal != SIGSEGV)
     274 [ +  + ][ +  + ]:       9496 :         && (bSetWINCHHandler || Signals[i].Signal != SIGWINCH)
     275 [ +  + ][ +  + ]:       9332 :         && (bSetILLHandler   || Signals[i].Signal != SIGILL))
     276                 :            :         {
     277         [ +  + ]:       9168 :             if (Signals[i].Action != ACT_SYSTEM)
     278                 :            :             {
     279         [ +  + ]:       3378 :                 if (Signals[i].Action == ACT_HIDE)
     280                 :            :                 {
     281                 :            :                     struct sigaction ign;
     282                 :            : 
     283                 :        644 :                     ign.sa_handler = SIG_IGN;
     284                 :        644 :                     ign.sa_flags   = 0;
     285                 :        644 :                     sigemptyset(&ign.sa_mask);
     286                 :            : 
     287         [ +  - ]:        644 :                     if (sigaction(Signals[i].Signal, &ign, &oact) == 0)
     288                 :        644 :                         Signals[i].Handler = oact.sa_handler;
     289                 :            :                     else
     290                 :        644 :                         Signals[i].Handler = SIG_DFL;
     291                 :            :                 }
     292                 :            :                 else
     293                 :            :                 {
     294         [ +  - ]:       2734 :                     if (sigaction(Signals[i].Signal, &act, &oact) == 0)
     295                 :       2734 :                         Signals[i].Handler = oact.sa_handler;
     296                 :            :                     else
     297                 :          0 :                         Signals[i].Handler = SIG_DFL;
     298                 :            :                 }
     299                 :            :             }
     300                 :            :         }
     301                 :            :     }
     302                 :            : 
     303                 :            :     /* Clear signal mask inherited from parent process (on Mac OS X, upon a
     304                 :            :        crash soffice re-execs itself from within the signal handler, so the
     305                 :            :        second soffice would have the guilty signal blocked and would freeze upon
     306                 :            :        encountering a similar crash again): */
     307         [ +  - ]:        322 :     if (sigemptyset(&unset) < 0 ||
     308                 :        322 :         pthread_sigmask(SIG_SETMASK, &unset, NULL) < 0)
     309                 :            :     {
     310                 :            :         OSL_TRACE("sigemptyset or pthread_sigmask failed");
     311                 :            :     }
     312                 :            : 
     313                 :        322 :     return sal_True;
     314                 :            : }
     315                 :            : 
     316                 :        158 : static sal_Bool DeInitSignal()
     317                 :            : {
     318                 :            :     int i;
     319                 :            :     struct sigaction act;
     320                 :            : 
     321                 :        158 :     act.sa_flags   = 0;
     322                 :        158 :     sigemptyset(&(act.sa_mask));
     323                 :            : 
     324                 :            :     /* Initialize the rest of the signals */
     325         [ +  + ]:       4898 :     for (i = NoSignals - 1; i >= 0; i--)
     326         [ +  + ]:       4740 :         if (Signals[i].Action != ACT_SYSTEM)
     327                 :            :         {
     328                 :       1738 :             act.sa_handler = Signals[i].Handler;
     329                 :            : 
     330                 :       1738 :             sigaction(Signals[i].Signal, &act, NULL);
     331                 :            :         }
     332                 :            : 
     333                 :        158 :     osl_destroyMutex(SignalListMutex);
     334                 :            : 
     335                 :        158 :     return sal_False;
     336                 :            : }
     337                 :            : 
     338                 :            : #if defined (SAL_ENABLE_CRASH_REPORT) && defined(INCLUDE_BACKTRACE)
     339                 :            : 
     340                 :            : /*****************************************************************************/
     341                 :            : /* Generate MD5 checksum    */
     342                 :            : /*****************************************************************************/
     343                 :            : 
     344                 :            : static sal_uInt32 calc_md5_checksum( const char *filename, sal_uInt8 *pChecksum, sal_uInt32 nChecksumLen )
     345                 :            : {
     346                 :            :     sal_uInt32  nBytesProcessed = 0;
     347                 :            : 
     348                 :            :     FILE *fp = fopen( filename, "r" );
     349                 :            : 
     350                 :            :     if ( fp )
     351                 :            :     {
     352                 :            :         rtlDigest digest = rtl_digest_createMD5();
     353                 :            : 
     354                 :            :         if ( digest )
     355                 :            :         {
     356                 :            :             size_t          nBytesRead;
     357                 :            :             sal_uInt8       buffer[4096];
     358                 :            :             rtlDigestError  error = rtl_Digest_E_None;
     359                 :            : 
     360                 :            :             while ( rtl_Digest_E_None == error &&
     361                 :            :                 0 != (nBytesRead = fread( buffer, 1, sizeof(buffer), fp )) )
     362                 :            :             {
     363                 :            :                 error = rtl_digest_updateMD5( digest, buffer, nBytesRead );
     364                 :            :                 nBytesProcessed += nBytesRead;
     365                 :            :             }
     366                 :            : 
     367                 :            :             if ( rtl_Digest_E_None == error )
     368                 :            :             {
     369                 :            :                 error = rtl_digest_getMD5( digest, pChecksum, nChecksumLen );
     370                 :            :             }
     371                 :            : 
     372                 :            :             if ( rtl_Digest_E_None != error )
     373                 :            :                 nBytesProcessed = 0;
     374                 :            : 
     375                 :            :             rtl_digest_destroyMD5( digest );
     376                 :            :         }
     377                 :            : 
     378                 :            :         fclose( fp );
     379                 :            :     }
     380                 :            : 
     381                 :            :     return nBytesProcessed;
     382                 :            : }
     383                 :            : 
     384                 :            : /*****************************************************************************/
     385                 :            : /* Call crash reporter  */
     386                 :            : /*****************************************************************************/
     387                 :            : 
     388                 :            : /* Helper function to encode and write a string to a stream */
     389                 :            : 
     390                 :            : static int fputs_xml( const char *string, FILE *stream )
     391                 :            : {
     392                 :            :     int result = 0;
     393                 :            : 
     394                 :            :     while ( result >= 0 && *string )
     395                 :            :     {
     396                 :            :         switch( *string )
     397                 :            :         {
     398                 :            :         case '&':
     399                 :            :             result = fputs( "&amp;", stream );
     400                 :            :             break;
     401                 :            :         case '<':
     402                 :            :             result = fputs( "&lt;", stream );
     403                 :            :             break;
     404                 :            :         case '>':
     405                 :            :             result = fputs( "&gt;", stream );
     406                 :            :             break;
     407                 :            :         default:
     408                 :            :             result = fputc( *string, stream );
     409                 :            :             break;
     410                 :            :         }
     411                 :            : 
     412                 :            :         string++;
     413                 :            :     }
     414                 :            : 
     415                 :            :     return result;
     416                 :            : }
     417                 :            : #endif
     418                 :            : 
     419                 :            : /* Create intermediate files and run crash reporter */
     420                 :            : 
     421                 :            : #define REPORTENV_PARAM     "-crashreportenv:"
     422                 :            : 
     423                 :            : #if defined SAL_ENABLE_CRASH_REPORT && defined INCLUDE_BACKTRACE && \
     424                 :            :     defined LINUX
     425                 :            : 
     426                 :            : typedef struct
     427                 :            : {
     428                 :            :     const char *name;
     429                 :            :     ElfW(Off) offset;
     430                 :            : } dynamic_entry;
     431                 :            : 
     432                 :            : static int
     433                 :            : callback(struct dl_phdr_info *info, size_t size, void *data)
     434                 :            : {
     435                 :            :     const ElfW(Phdr) *pDynamic = NULL;
     436                 :            : 
     437                 :            :     if (size == sizeof(struct dl_phdr_info))
     438                 :            :     {
     439                 :            :         int i;
     440                 :            :         for (i = 0; i < info->dlpi_phnum; ++i)
     441                 :            :         {
     442                 :            :             if (info->dlpi_phdr[i].p_type == PT_DYNAMIC)
     443                 :            :             {
     444                 :            :                 pDynamic = &(info->dlpi_phdr[i]);
     445                 :            :                 break;
     446                 :            :             }
     447                 :            :         }
     448                 :            :     }
     449                 :            : 
     450                 :            :     if (pDynamic)
     451                 :            :     {
     452                 :            :         char buffer[100];
     453                 :            :         int len;
     454                 :            :         char exe[PATH_MAX];
     455                 :            :         const char *dsoname = info->dlpi_name;
     456                 :            : 
     457                 :            :         dynamic_entry* entry = (dynamic_entry*)data;
     458                 :            : 
     459                 :            :         if (strcmp(dsoname, "") == 0)
     460                 :            :         {
     461                 :            :             snprintf(buffer, sizeof(buffer), "/proc/%d/exe", getpid());
     462                 :            :             if ((len = readlink(buffer, exe, PATH_MAX)) != -1)
     463                 :            :             {
     464                 :            :                 exe[len] = '\0';
     465                 :            :                 dsoname = exe;
     466                 :            :             }
     467                 :            :         }
     468                 :            : 
     469                 :            :         if (strcmp(dsoname, entry->name) == 0)
     470                 :            :         {
     471                 :            :             entry->offset = pDynamic->p_offset;
     472                 :            :             return 1;
     473                 :            :         }
     474                 :            :     }
     475                 :            :     return 0;
     476                 :            : }
     477                 :            : 
     478                 :            : /* Get the location of the .dynamic section offset for the given elf file.
     479                 :            :  * i.e. same as the "Offset" value shown for DYNAMIC from readelf -l foo
     480                 :            :  *
     481                 :            :  * We want to know this value so that if the binaries have been modifed
     482                 :            :  * by prelink then we can still process the call stack on server side
     483                 :            :  * by comparing this value to that of an "un-prelinked but known to be
     484                 :            :  * otherwise equivalent" version of those binaries and adjust the call
     485                 :            :  * stack addresses by the differences between .dynamic addresses so as
     486                 :            :  * to be able to map the prelinked addresses back to the unprelinked
     487                 :            :  * addresses
     488                 :            :  *
     489                 :            :  * cmc@openoffice.org
     490                 :            :  */
     491                 :            : static ElfW(Off)
     492                 :            : dynamic_section_offset(const char *name)
     493                 :            : {
     494                 :            :     dynamic_entry entry;
     495                 :            : 
     496                 :            :     entry.name = name;
     497                 :            :     entry.offset = 0;
     498                 :            : 
     499                 :            :     dl_iterate_phdr(callback, &entry);
     500                 :            : 
     501                 :            :     return entry.offset;
     502                 :            : }
     503                 :            : #endif
     504                 :            : 
     505                 :          0 : static int ReportCrash( int Signal )
     506                 :            : {
     507                 :            : #ifdef SAL_ENABLE_CRASH_REPORT
     508                 :            :     static sal_Bool bCrashReporterExecuted = sal_False;
     509                 :            :     sal_Bool        bAutoCrashReport = sal_False;
     510                 :            : 
     511                 :            :     sal_uInt32  argi;
     512                 :            :     sal_uInt32  argc;
     513                 :            :     rtl_uString *ustrCommandArg = NULL;
     514                 :            : 
     515                 :            :     if ( !bErrorReportingEnabled )
     516                 :            :         return -1;
     517                 :            : 
     518                 :            :     argc = osl_getCommandArgCount();
     519                 :            : 
     520                 :            :     for ( argi = 0; argi < argc; argi++ )
     521                 :            :     {
     522                 :            :         if ( osl_Process_E_None == osl_getCommandArg( argi, &ustrCommandArg ) )
     523                 :            :         {
     524                 :            :             if ( 0 == rtl_ustr_ascii_compare( rtl_uString_getStr( ustrCommandArg ), "--nocrashreport" ) )
     525                 :            :             {
     526                 :            :                 rtl_uString_release( ustrCommandArg );
     527                 :            :                 return -1;
     528                 :            :             }
     529                 :            :             else if ( 0 == rtl_ustr_ascii_compare( rtl_uString_getStr( ustrCommandArg ), "--autocrashreport" ) )
     530                 :            :             {
     531                 :            :                 bAutoCrashReport = sal_True;
     532                 :            :             }
     533                 :            :             else if ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength(
     534                 :            :                 rtl_uString_getStr( ustrCommandArg ), rtl_uString_getLength( ustrCommandArg ),
     535                 :            :                 REPORTENV_PARAM, strlen(REPORTENV_PARAM) )
     536                 :            :                 )
     537                 :            :             {
     538                 :            :                 rtl_uString *ustrEnvironment = NULL;
     539                 :            :                 rtl_String *strEnv = NULL;
     540                 :            : 
     541                 :            :                 rtl_uString_newFromStr( &ustrEnvironment, rtl_uString_getStr( ustrCommandArg ) + strlen(REPORTENV_PARAM) );
     542                 :            : 
     543                 :            :                 if ( ustrEnvironment )
     544                 :            :                 {
     545                 :            :                     rtl_uString2String(
     546                 :            :                         &strEnv,
     547                 :            :                         rtl_uString_getStr( ustrEnvironment ), rtl_uString_getLength( ustrEnvironment ),
     548                 :            :                         osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS
     549                 :            :                         );
     550                 :            : 
     551                 :            :                     if ( strEnv )
     552                 :            :                     {
     553                 :            :                         putenv( rtl_string_getStr( strEnv ) );
     554                 :            :                         rtl_string_release( strEnv );
     555                 :            :                     }
     556                 :            : 
     557                 :            :                     rtl_uString_release( ustrEnvironment );
     558                 :            :                 }
     559                 :            : 
     560                 :            :             }
     561                 :            : 
     562                 :            :         }
     563                 :            :     }
     564                 :            : 
     565                 :            :     if ( ustrCommandArg )
     566                 :            :         rtl_uString_release( ustrCommandArg );
     567                 :            : 
     568                 :            :     if ( !bCrashReporterExecuted )
     569                 :            :     {
     570                 :            :         int i;
     571                 :            :         /* struct sigaction act; */
     572                 :            : 
     573                 :            :         for (i = 0; i < NoSignals; i++)
     574                 :            :         {
     575                 :            :             if (Signals[i].Signal == Signal && Signals[i].Action == ACT_ABORT )
     576                 :            :             {
     577                 :            :                 int  ret;
     578                 :            :                 char szShellCmd[512] = { '\0' };
     579                 :            :                 char *pXMLTempName = NULL;
     580                 :            :                 char *pStackTempName = NULL;
     581                 :            :                 char *pChecksumTempName = NULL;
     582                 :            : 
     583                 :            : #ifdef INCLUDE_BACKTRACE
     584                 :            :                 char szXMLTempNameBuffer[L_tmpnam];
     585                 :            :                 char szChecksumTempNameBuffer[L_tmpnam];
     586                 :            :                 char szStackTempNameBuffer[L_tmpnam];
     587                 :            : 
     588                 :            :                 void *stackframes[MAX_STACK_FRAMES];
     589                 :            :                 int  iFrame;
     590                 :            :                 int  nFrames = backtrace( stackframes, SAL_N_ELEMENTS(stackframes) );
     591                 :            : 
     592                 :            :                 FILE *xmlout = NULL, *stackout = NULL, *checksumout = NULL;
     593                 :            :                 int fdxml, fdstk, fdchksum;
     594                 :            : 
     595                 :            :                 strncpy( szXMLTempNameBuffer, P_tmpdir, sizeof(szXMLTempNameBuffer) );
     596                 :            :                 strncat( szXMLTempNameBuffer, "/crxmlXXXXXX", sizeof(szXMLTempNameBuffer) - strlen(szXMLTempNameBuffer) - 1 );
     597                 :            : 
     598                 :            :                 strncpy( szStackTempNameBuffer, P_tmpdir, sizeof(szStackTempNameBuffer) );
     599                 :            :                 strncat( szStackTempNameBuffer, "/crstkXXXXXX", sizeof(szStackTempNameBuffer) - strlen(szStackTempNameBuffer) - 1 );
     600                 :            : 
     601                 :            :                 strncpy( szChecksumTempNameBuffer, P_tmpdir, sizeof(szChecksumTempNameBuffer) );
     602                 :            :                 strncat( szChecksumTempNameBuffer, "/crchkXXXXXX", sizeof(szChecksumTempNameBuffer) - strlen(szChecksumTempNameBuffer) - 1 );
     603                 :            : 
     604                 :            :                 fdxml = mkstemp(szXMLTempNameBuffer);
     605                 :            :                 fdstk = mkstemp(szStackTempNameBuffer);
     606                 :            :                 fdchksum = mkstemp(szChecksumTempNameBuffer);
     607                 :            : 
     608                 :            :                 xmlout = fdopen( fdxml , "w" );
     609                 :            :                 stackout = fdopen( fdstk , "w" );
     610                 :            :                 checksumout = fdopen( fdchksum, "w" );
     611                 :            : 
     612                 :            :                 pXMLTempName = szXMLTempNameBuffer;
     613                 :            :                 pStackTempName = szStackTempNameBuffer;
     614                 :            :                 pChecksumTempName = szChecksumTempNameBuffer;
     615                 :            : 
     616                 :            : 
     617                 :            :                 if ( xmlout && stackout && checksumout )
     618                 :            :                 {
     619                 :            :                     fprintf( xmlout, "<errormail:Stack type=\"%s\">\n", STACKTYPE );
     620                 :            : 
     621                 :            :                     fprintf( checksumout, "<errormail:Checksums type=\"MD5\">\n" );
     622                 :            : 
     623                 :            :                     for ( iFrame = 0; iFrame < nFrames; iFrame++ )
     624                 :            :                     {
     625                 :            :                         Dl_info dl_info;
     626                 :            : 
     627                 :            :                         fprintf( stackout, "0x%" SAL_PRIxUINTPTR ":",
     628                 :            :                             SAL_INT_CAST(sal_uIntPtr, stackframes[iFrame]) );
     629                 :            : 
     630                 :            :                         fprintf( xmlout, "<errormail:StackInfo pos=\"%d\" ip=\"0x%" SAL_PRIxUINTPTR "\"",
     631                 :            :                             iFrame,
     632                 :            :                             SAL_INT_CAST(sal_uIntPtr, stackframes[iFrame])
     633                 :            :                             );
     634                 :            : 
     635                 :            :                         memset( &dl_info, 0, sizeof(dl_info) );
     636                 :            : 
     637                 :            :                         /* dladdr may fail */
     638                 :            :                         if ( dladdr( stackframes[iFrame], &dl_info) )
     639                 :            :                         {
     640                 :            :                             const char *dli_fname = NULL;
     641                 :            :                             char *dli_fdir = NULL;
     642                 :            :                             char szDirectory[PATH_MAX];
     643                 :            :                             char szCanonicDirectory[PATH_MAX];
     644                 :            : 
     645                 :            :                             /* Don't expect that dladdr filled all members of dl_info */
     646                 :            : 
     647                 :            :                             dli_fname = dl_info.dli_fname ? strrchr(  dl_info.dli_fname, '/' ) : NULL;
     648                 :            :                             if ( dli_fname )
     649                 :            :                             {
     650                 :            :                                 ++dli_fname;
     651                 :            :                                 memcpy( szDirectory, dl_info.dli_fname, dli_fname - dl_info.dli_fname );
     652                 :            :                                 szDirectory[dli_fname - dl_info.dli_fname] = 0;
     653                 :            : 
     654                 :            :                                 dli_fdir = realpath( szDirectory, szCanonicDirectory ) ? szCanonicDirectory : szDirectory;
     655                 :            : 
     656                 :            :                                 if ( *dli_fdir && dli_fdir[ strlen(dli_fdir) - 1 ] != '/' )
     657                 :            :                                     strcat( dli_fdir, "/" );
     658                 :            :                             }
     659                 :            :                             else
     660                 :            :                                 dli_fname = dl_info.dli_fname;
     661                 :            : 
     662                 :            :                             /* create checksum of library on stack */
     663                 :            :                             if ( dli_fname )
     664                 :            :                             {
     665                 :            :                                 sal_uInt8   checksum[RTL_DIGEST_LENGTH_MD5];
     666                 :            : 
     667                 :            :                                 sal_uInt32 nBytesProcessed = calc_md5_checksum(
     668                 :            :                                     dl_info.dli_fname, checksum, sizeof(checksum) );
     669                 :            :                                 if ( nBytesProcessed )
     670                 :            :                                 {
     671                 :            :                                     int j;
     672                 :            : 
     673                 :            :                                     fprintf( checksumout, "<errormail:Checksum sum=\"0x" );
     674                 :            :                                     for ( j = 0; j < 16; fprintf( checksumout, "%02X", checksum[j++] ) );
     675                 :            :                                     fprintf( checksumout,
     676                 :            :                                         "\" bytes=\"%lu\" file=\"%s\"/>\n",
     677                 :            :                                         SAL_INT_CAST(
     678                 :            :                                             unsigned long, nBytesProcessed),
     679                 :            :                                         dli_fname );
     680                 :            :                                 }
     681                 :            :                             }
     682                 :            : 
     683                 :            :                             if ( dl_info.dli_fbase && dl_info.dli_fname )
     684                 :            :                             {
     685                 :            : #ifdef LINUX
     686                 :            :                                 ElfW(Off) dynamic_offset = dynamic_section_offset(dl_info.dli_fname);
     687                 :            :                                 fprintf( stackout, " 0x%" SAL_PRI_SIZET "x:", dynamic_offset);
     688                 :            : #endif
     689                 :            : 
     690                 :            :                                 fprintf( stackout, " %s + 0x%" SAL_PRI_PTRDIFFT "x",
     691                 :            :                                     dl_info.dli_fname,
     692                 :            :                                     (char*)stackframes[iFrame] - (char*)dl_info.dli_fbase
     693                 :            :                                     );
     694                 :            : 
     695                 :            :                                 fprintf( xmlout, " rel=\"0x%" SAL_PRI_PTRDIFFT "x\"", (char *)stackframes[iFrame] - (char *)dl_info.dli_fbase );
     696                 :            :                                 if ( dli_fname )
     697                 :            :                                     fprintf( xmlout, " name=\"%s\"", dli_fname );
     698                 :            : 
     699                 :            :                                 if ( dli_fdir )
     700                 :            :                                     fprintf( xmlout, " path=\"%s\"", dli_fdir );
     701                 :            : 
     702                 :            : #ifdef LINUX
     703                 :            :                                 fprintf( xmlout, " dynamicoffset=\"0x%" SAL_PRI_SIZET "x\"", dynamic_offset );
     704                 :            : #endif
     705                 :            :                             }
     706                 :            :                             else
     707                 :            :                                 fprintf( stackout, " ????????" );
     708                 :            : 
     709                 :            :                             if ( dl_info.dli_sname && dl_info.dli_saddr )
     710                 :            :                             {
     711                 :            :                                 fputs( " (", stackout );
     712                 :            :                                 fputs_xml( dl_info.dli_sname, stackout );
     713                 :            :                                 fprintf( stackout, " + 0x%" SAL_PRI_PTRDIFFT "x)",
     714                 :            :                                     (char*)stackframes[iFrame] - (char*)dl_info.dli_saddr );
     715                 :            : 
     716                 :            :                                 fputs( " ordinal=\"", xmlout );
     717                 :            :                                 fputs_xml( dl_info.dli_sname, xmlout );
     718                 :            :                                 fprintf( xmlout, "+0x%" SAL_PRI_PTRDIFFT "x\"",
     719                 :            :                                     (char *)stackframes[iFrame] - (char *)dl_info.dli_saddr );
     720                 :            :                             }
     721                 :            : 
     722                 :            :                         }
     723                 :            :                         else /* dladdr failed */
     724                 :            :                         {
     725                 :            :                             fprintf( stackout, " ????????" );
     726                 :            :                         }
     727                 :            : 
     728                 :            :                         fprintf( stackout, "\n" );
     729                 :            :                         fprintf( xmlout, "/>\n" );
     730                 :            : 
     731                 :            :                     }
     732                 :            : 
     733                 :            :                     fprintf( xmlout, "</errormail:Stack>\n" );
     734                 :            :                     fprintf( checksumout, "</errormail:Checksums>\n" );
     735                 :            :                 }
     736                 :            :                 else
     737                 :            :                 {
     738                 :            :                     pXMLTempName = NULL;
     739                 :            :                     pStackTempName = NULL;
     740                 :            :                     pChecksumTempName = NULL;
     741                 :            :                 }
     742                 :            : 
     743                 :            :                 if ( stackout )
     744                 :            :                     fclose( stackout );
     745                 :            :                 if ( xmlout )
     746                 :            :                     fclose( xmlout );
     747                 :            :                 if ( checksumout )
     748                 :            :                     fclose( checksumout );
     749                 :            : 
     750                 :            :                 if ( pXMLTempName && pChecksumTempName && pStackTempName )
     751                 :            : #endif /* INCLUDE_BACKTRACE */
     752                 :            :                 {
     753                 :            :                     rtl_uString * crashrep_url = NULL;
     754                 :            :                     rtl_uString * crashrep_path = NULL;
     755                 :            :                     rtl_String  * crashrep_path_system = NULL;
     756                 :            :                     rtl_string2UString(
     757                 :            :                         &crashrep_url,
     758                 :            :                         RTL_CONSTASCII_USTRINGPARAM(
     759                 :            :                             "$BRAND_BASE_DIR/program/crashrep"),
     760                 :            :                         OSTRING_TO_OUSTRING_CVTFLAGS);
     761                 :            :                     rtl_bootstrap_expandMacros(&crashrep_url);
     762                 :            :                     osl_getSystemPathFromFileURL(crashrep_url, &crashrep_path);
     763                 :            :                     rtl_uString2String(
     764                 :            :                         &crashrep_path_system,
     765                 :            :                         rtl_uString_getStr(crashrep_path),
     766                 :            :                         rtl_uString_getLength(crashrep_path),
     767                 :            :                         osl_getThreadTextEncoding(),
     768                 :            :                         (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
     769                 :            :                          | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR));
     770                 :            :                     rtl_uString_release(crashrep_url);
     771                 :            :                     rtl_uString_release(crashrep_path);
     772                 :            : #if defined INCLUDE_BACKTRACE && (defined LINUX || defined MACOSX)
     773                 :            :                     snprintf( szShellCmd, SAL_N_ELEMENTS(szShellCmd),
     774                 :            :                         "%s -p %d -s %d -xml %s -chksum %s -stack %s -noui%s",
     775                 :            :                         rtl_string_getStr(crashrep_path_system),
     776                 :            :                         getpid(),
     777                 :            :                         Signal,
     778                 :            :                         pXMLTempName,
     779                 :            :                         pChecksumTempName,
     780                 :            :                         pStackTempName,
     781                 :            :                         bAutoCrashReport ? " -send" : "" );
     782                 :            : #elif defined INCLUDE_BACKTRACE && defined SOLARIS
     783                 :            :                     snprintf( szShellCmd, SAL_N_ELEMENTS(szShellCmd),
     784                 :            :                         "%s -p %d -s %d -xml %s -chksum %s -noui%s",
     785                 :            :                         rtl_string_getStr(crashrep_path_system),
     786                 :            :                         getpid(),
     787                 :            :                         Signal,
     788                 :            :                         pXMLTempName,
     789                 :            :                         pChecksumTempName,
     790                 :            :                         bAutoCrashReport ? " -send" : "" );
     791                 :            : #else
     792                 :            :                     snprintf( szShellCmd, SAL_N_ELEMENTS(szShellCmd),
     793                 :            :                         "%s -p %d -s %d -noui%s",
     794                 :            :                         rtl_string_getStr(crashrep_path_system),
     795                 :            :                         getpid(), Signal, bAutoCrashReport ? " -send" : "" );
     796                 :            : #endif
     797                 :            :                     rtl_string_release(crashrep_path_system);
     798                 :            :                 }
     799                 :            : 
     800                 :            :                 ret = szShellCmd[0] == '\0' ? -1 : system( szShellCmd );
     801                 :            : 
     802                 :            :                 if ( pXMLTempName )
     803                 :            :                     unlink( pXMLTempName );
     804                 :            : 
     805                 :            :                 if ( pStackTempName )
     806                 :            :                     unlink( pStackTempName );
     807                 :            : 
     808                 :            :                 if ( pChecksumTempName )
     809                 :            :                     unlink( pChecksumTempName );
     810                 :            : 
     811                 :            :                 if ( -1 != ret )
     812                 :            :                 {
     813                 :            :                     bCrashReporterExecuted = sal_True;
     814                 :            :                     return 1;
     815                 :            :                 }
     816                 :            :                 else
     817                 :            :                     return -1;
     818                 :            : 
     819                 :            :             }
     820                 :            :         }
     821                 :            : 
     822                 :            :         return 0;
     823                 :            :     }
     824                 :            : 
     825                 :            :     return 1;
     826                 :            : #else /* defined SAL_ENABLE_CRASH_REPORT */
     827                 :            :     /* the utility crash_report is not build, so do the same as when
     828                 :            :        the option -nocrashreport is used */
     829                 :            :     (void) Signal; // avoid warnings
     830                 :          0 :     return -1;
     831                 :            : #endif /* defined SAL_ENABLE_CRASH_REPORT */
     832                 :            : }
     833                 :            : 
     834                 :          0 : static void PrintStack( int sig )
     835                 :            : {
     836                 :            : #ifdef INCLUDE_BACKTRACE
     837                 :            :     void *buffer[MAX_STACK_FRAMES];
     838                 :          0 :     int size = backtrace( buffer, SAL_N_ELEMENTS(buffer) );
     839                 :            : #endif
     840                 :            : 
     841                 :          0 :     fprintf( stderr, "\n\nFatal exception: Signal %d\n", sig );
     842                 :            : 
     843                 :            : #if defined( MACOSX ) && !defined( INCLUDE_BACKTRACE )
     844                 :            :     fprintf( stderr, "Please turn on Enable Crash Reporting and\nAutomatic Display of Crashlogs in the Console application\n" );
     845                 :            : #else
     846                 :            : #ifdef INCLUDE_BACKTRACE
     847         [ #  # ]:          0 :     if ( size > 0 )
     848                 :            :     {
     849                 :          0 :         fputs( "Stack:\n", stderr );
     850                 :          0 :         backtrace_symbols_fd( buffer, size, fileno(stderr) );
     851                 :            :     }
     852                 :            : #endif
     853                 :            : #endif
     854                 :          0 : }
     855                 :            : 
     856                 :          0 : static oslSignalAction CallSignalHandler(oslSignalInfo *pInfo)
     857                 :            : {
     858                 :          0 :     oslSignalHandlerImpl* pHandler = SignalList;
     859                 :          0 :     oslSignalAction Action = osl_Signal_ActCallNextHdl;
     860                 :            : 
     861         [ #  # ]:          0 :     while (pHandler != NULL)
     862                 :            :     {
     863         [ #  # ]:          0 :         if ((Action = pHandler->Handler(pHandler->pData, pInfo))
     864                 :            :             != osl_Signal_ActCallNextHdl)
     865                 :          0 :             break;
     866                 :            : 
     867                 :          0 :         pHandler = pHandler->pNext;
     868                 :            :     }
     869                 :            : 
     870                 :          0 :     return Action;
     871                 :            : }
     872                 :            : 
     873                 :          0 : void CallSystemHandler(int Signal)
     874                 :            : {
     875                 :            :     int i;
     876                 :            :     struct sigaction act;
     877                 :            : 
     878         [ #  # ]:          0 :     for (i = 0; i < NoSignals; i++)
     879                 :            :     {
     880         [ #  # ]:          0 :         if (Signals[i].Signal == Signal)
     881                 :          0 :             break;
     882                 :            :     }
     883                 :            : 
     884         [ #  # ]:          0 :     if (i < NoSignals)
     885                 :            :     {
     886 [ #  # ][ #  # ]:          0 :         if ((Signals[i].Handler == NULL)    ||
     887         [ #  # ]:          0 :             (Signals[i].Handler == SIG_DFL) ||
     888         [ #  # ]:          0 :             (Signals[i].Handler == SIG_IGN) ||
     889                 :          0 :              (Signals[i].Handler == SIG_ERR))
     890                 :            :         {
     891   [ #  #  #  # ]:          0 :             switch (Signals[i].Action)
     892                 :            :             {
     893                 :            :                 case ACT_EXIT:      /* terminate */
     894                 :            :                     /* prevent dumping core on exit() */
     895                 :          0 :                     _exit(255);
     896                 :            :                     break;
     897                 :            : 
     898                 :            :                 case ACT_ABORT:     /* terminate witch core dump */
     899                 :          0 :                     ReportCrash( Signal );
     900                 :          0 :                     act.sa_handler = SIG_DFL;
     901                 :          0 :                     act.sa_flags   = 0;
     902                 :          0 :                     sigemptyset(&(act.sa_mask));
     903                 :          0 :                     sigaction(SIGABRT, &act, NULL);
     904                 :          0 :                     PrintStack( Signal );
     905                 :          0 :                     abort();
     906                 :            :                     break;
     907                 :            : 
     908                 :            :                 case ACT_IGNORE:    /* ignore */
     909                 :          0 :                     break;
     910                 :            : 
     911                 :            :                 default:            /* should never happen */
     912                 :            :                     OSL_ASSERT(0);
     913                 :            :             }
     914                 :          0 :         }
     915                 :            :         else
     916                 :          0 :             (*Signals[i].Handler)(Signal);
     917                 :            :     }
     918                 :          0 : }
     919                 :            : 
     920                 :            : #if defined(HAVE_MEMCHECK_H)
     921                 :            : static void DUMPCURRENTALLOCS()
     922                 :            : {
     923                 :            :     VALGRIND_PRINTF( "=== start memcheck dump of active allocations ===\n" );
     924                 :            : 
     925                 :            : #if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
     926                 :            : #   pragma GCC diagnostic push
     927                 :            : #   pragma GCC diagnostic ignored "-Wunused-but-set-variable"
     928                 :            : #endif
     929                 :            : 
     930                 :            :     VALGRIND_DO_LEAK_CHECK;
     931                 :            : 
     932                 :            : #if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
     933                 :            : #   pragma GCC diagnostic pop
     934                 :            : #endif
     935                 :            : 
     936                 :            :     VALGRIND_PRINTF( "=== end memcheck dump of active allocations ===\n" );
     937                 :            : }
     938                 :            : #endif
     939                 :            : 
     940                 :            : /*****************************************************************************/
     941                 :            : /* SignalHandlerFunction    */
     942                 :            : /*****************************************************************************/
     943                 :          0 : void SignalHandlerFunction(int Signal)
     944                 :            : {
     945                 :            :     oslSignalInfo    Info;
     946                 :            :     struct sigaction act;
     947                 :            : 
     948                 :          0 :     Info.UserSignal = Signal;
     949                 :          0 :     Info.UserData   = NULL;
     950                 :            : 
     951   [ #  #  #  #  :          0 :     switch (Signal)
                      # ]
     952                 :            :     {
     953                 :            :         case SIGBUS:
     954                 :            :         case SIGILL:
     955                 :            :         case SIGSEGV:
     956                 :            :         case SIGIOT:
     957                 :            : #if ( SIGIOT != SIGABRT )
     958                 :            :         case SIGABRT:
     959                 :            : #endif
     960                 :          0 :             Info.Signal = osl_Signal_AccessViolation;
     961                 :          0 :             break;
     962                 :            : 
     963                 :            :         case -1:
     964                 :          0 :             Info.Signal = osl_Signal_IntegerDivideByZero;
     965                 :          0 :             break;
     966                 :            : 
     967                 :            :         case SIGFPE:
     968                 :          0 :             Info.Signal = osl_Signal_FloatDivideByZero;
     969                 :          0 :             break;
     970                 :            : 
     971                 :            :         case SIGINT:
     972                 :            :         case SIGTERM:
     973                 :            :         case SIGQUIT:
     974                 :          0 :             Info.Signal = osl_Signal_Terminate;
     975                 :          0 :             break;
     976                 :            : 
     977                 :            : #if defined(HAVE_MEMCHECK_H)
     978                 :            :         case SIGUSR2:
     979                 :            :             if (RUNNING_ON_VALGRIND)
     980                 :            :                 DUMPCURRENTALLOCS();
     981                 :            :             Info.Signal = osl_Signal_System;
     982                 :            :             break;
     983                 :            : #endif
     984                 :            : 
     985                 :            :         default:
     986                 :          0 :             Info.Signal = osl_Signal_System;
     987                 :          0 :             break;
     988                 :            :     }
     989                 :            : 
     990                 :          0 :     ReportCrash( Signal );
     991                 :            : 
     992                 :            :     /* Portal Demo HACK !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
     993 [ #  # ][ #  # ]:          0 :     if (bDoHardKill && (Info.Signal == osl_Signal_AccessViolation))
     994                 :          0 :         _exit(255);
     995                 :            :     /* Portal Demo HACK !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
     996                 :            : 
     997                 :            : 
     998   [ #  #  #  # ]:          0 :     switch (CallSignalHandler(&Info))
     999                 :            :     {
    1000                 :            :     case osl_Signal_ActCallNextHdl:
    1001                 :          0 :         CallSystemHandler(Signal);
    1002                 :          0 :         break;
    1003                 :            : 
    1004                 :            :     case osl_Signal_ActAbortApp:
    1005                 :          0 :         ReportCrash( Signal );
    1006                 :          0 :         act.sa_handler = SIG_DFL;
    1007                 :          0 :         act.sa_flags   = 0;
    1008                 :          0 :         sigemptyset(&(act.sa_mask));
    1009                 :          0 :         sigaction(SIGABRT, &act, NULL);
    1010                 :          0 :         PrintStack( Signal );
    1011                 :          0 :         abort();
    1012                 :            :         break;
    1013                 :            : 
    1014                 :            :     case osl_Signal_ActKillApp:
    1015                 :            :         /* prevent dumping core on exit() */
    1016                 :          0 :         _exit(255);
    1017                 :            :         break;
    1018                 :            :     default:
    1019                 :          0 :         break;
    1020                 :            :     }
    1021                 :          0 : }
    1022                 :            : 
    1023                 :            : /*****************************************************************************/
    1024                 :            : /* osl_addSignalHandler */
    1025                 :            : /*****************************************************************************/
    1026                 :        480 : oslSignalHandler SAL_CALL osl_addSignalHandler(oslSignalHandlerFunction Handler, void* pData)
    1027                 :            : {
    1028                 :            :     oslSignalHandlerImpl* pHandler;
    1029                 :            : 
    1030                 :            :     OSL_ASSERT(Handler != NULL);
    1031         [ -  + ]:        480 :     if ( Handler == 0 )
    1032                 :            :     {
    1033                 :          0 :         return 0;
    1034                 :            :     }
    1035                 :            : 
    1036         [ +  + ]:        480 :     if (! bInitSignal)
    1037                 :        322 :         bInitSignal = InitSignal();
    1038                 :            : 
    1039                 :        480 :     pHandler = (oslSignalHandlerImpl*) calloc(1, sizeof(oslSignalHandlerImpl));
    1040                 :            : 
    1041         [ +  - ]:        480 :     if (pHandler != NULL)
    1042                 :            :     {
    1043                 :        480 :         pHandler->Handler = Handler;
    1044                 :        480 :         pHandler->pData   = pData;
    1045                 :            : 
    1046                 :        480 :         osl_acquireMutex(SignalListMutex);
    1047                 :            : 
    1048                 :        480 :         pHandler->pNext = SignalList;
    1049                 :        480 :         SignalList      = pHandler;
    1050                 :            : 
    1051                 :        480 :         osl_releaseMutex(SignalListMutex);
    1052                 :            : 
    1053                 :        480 :         return (pHandler);
    1054                 :            :     }
    1055                 :            : 
    1056                 :        480 :     return (NULL);
    1057                 :            : }
    1058                 :            : 
    1059                 :            : /*****************************************************************************/
    1060                 :            : /* osl_removeSignalHandler */
    1061                 :            : /*****************************************************************************/
    1062                 :        316 : sal_Bool SAL_CALL osl_removeSignalHandler(oslSignalHandler Handler)
    1063                 :            : {
    1064                 :        316 :     oslSignalHandlerImpl *pHandler, *pPrevious = NULL;
    1065                 :            : 
    1066                 :            :     OSL_ASSERT(Handler != NULL);
    1067                 :            : 
    1068         [ -  + ]:        316 :     if (! bInitSignal)
    1069                 :          0 :         bInitSignal = InitSignal();
    1070                 :            : 
    1071                 :        316 :     osl_acquireMutex(SignalListMutex);
    1072                 :            : 
    1073                 :        316 :     pHandler = SignalList;
    1074                 :            : 
    1075         [ +  - ]:        316 :     while (pHandler != NULL)
    1076                 :            :     {
    1077         [ +  - ]:        316 :         if (pHandler == Handler)
    1078                 :            :         {
    1079         [ -  + ]:        316 :             if (pPrevious)
    1080                 :          0 :                 pPrevious->pNext = pHandler->pNext;
    1081                 :            :             else
    1082                 :        316 :                 SignalList = pHandler->pNext;
    1083                 :            : 
    1084                 :        316 :             osl_releaseMutex(SignalListMutex);
    1085                 :            : 
    1086         [ +  + ]:        316 :             if (SignalList == NULL)
    1087                 :        158 :                 bInitSignal = DeInitSignal();
    1088                 :            : 
    1089                 :        316 :             free(pHandler);
    1090                 :            : 
    1091                 :        316 :             return (sal_True);
    1092                 :            :         }
    1093                 :            : 
    1094                 :          0 :         pPrevious = pHandler;
    1095                 :          0 :         pHandler  = pHandler->pNext;
    1096                 :            :     }
    1097                 :            : 
    1098                 :          0 :     osl_releaseMutex(SignalListMutex);
    1099                 :            : 
    1100                 :        316 :     return (sal_False);
    1101                 :            : }
    1102                 :            : 
    1103                 :            : /*****************************************************************************/
    1104                 :            : /* osl_raiseSignal */
    1105                 :            : /*****************************************************************************/
    1106                 :          0 : oslSignalAction SAL_CALL osl_raiseSignal(sal_Int32 UserSignal, void* UserData)
    1107                 :            : {
    1108                 :            :     oslSignalInfo   Info;
    1109                 :            :     oslSignalAction Action;
    1110                 :            : 
    1111         [ #  # ]:          0 :     if (! bInitSignal)
    1112                 :          0 :         bInitSignal = InitSignal();
    1113                 :            : 
    1114                 :          0 :     osl_acquireMutex(SignalListMutex);
    1115                 :            : 
    1116                 :          0 :     Info.Signal     = osl_Signal_User;
    1117                 :          0 :     Info.UserSignal = UserSignal;
    1118                 :          0 :     Info.UserData   = UserData;
    1119                 :            : 
    1120                 :          0 :     Action = CallSignalHandler(&Info);
    1121                 :            : 
    1122                 :          0 :     osl_releaseMutex(SignalListMutex);
    1123                 :            : 
    1124                 :          0 :     return (Action);
    1125                 :            : }
    1126                 :            : 
    1127                 :            : /*****************************************************************************/
    1128                 :            : /* osl_setErrorReporting */
    1129                 :            : /*****************************************************************************/
    1130                 :        158 : sal_Bool SAL_CALL osl_setErrorReporting( sal_Bool bEnable )
    1131                 :            : {
    1132                 :        158 :     sal_Bool bOld = bErrorReportingEnabled;
    1133                 :        158 :     bErrorReportingEnabled = bEnable;
    1134                 :            : 
    1135                 :        158 :     return bOld;
    1136                 :            : }
    1137                 :            : 
    1138                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10