LCOV - code coverage report
Current view: top level - sal/osl/unx - signal.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 87 178 48.9 %
Date: 2015-06-13 12:38:46 Functions: 7 13 53.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <sal/config.h>
      21             : 
      22             : #include <config_features.h>
      23             : 
      24             : /* system headers */
      25             : #include "system.hxx"
      26             : 
      27             : #if defined( MACOSX )
      28             : 
      29             : #if defined( INTEL )
      30             : #include "backtrace.h"
      31             : #define INCLUDE_BACKTRACE
      32             : #endif /* INTEL */
      33             : 
      34             : #endif /* MACOSX */
      35             : 
      36             : #ifdef LINUX
      37             : #include <execinfo.h>
      38             : #include <link.h>
      39             : #define INCLUDE_BACKTRACE
      40             : #endif
      41             : 
      42             : #ifdef SOLARIS
      43             : 
      44             : #include "backtrace.h"
      45             : #define INCLUDE_BACKTRACE
      46             : 
      47             : #endif /* defined SOLARIS */
      48             : 
      49             : #if defined INCLUDE_BACKTRACE
      50             : #define MAX_STACK_FRAMES 256
      51             : #endif
      52             : 
      53             : #include <osl/diagnose.h>
      54             : #include <osl/mutex.h>
      55             : #include <osl/signal.h>
      56             : #include <osl/process.h>
      57             : #include <osl/thread.h>
      58             : #include <sal/macros.h>
      59             : #include <rtl/bootstrap.h>
      60             : #include <rtl/digest.h>
      61             : 
      62             : #include "file_path_helper.hxx"
      63             : 
      64             : #define ACT_IGNORE  1
      65             : #define ACT_EXIT    2
      66             : #define ACT_SYSTEM  3
      67             : #define ACT_HIDE    4
      68             : #define ACT_ABORT   ACT_SYSTEM
      69             : 
      70             : #if defined HAVE_VALGRIND_HEADERS
      71             : #include <valgrind/memcheck.h>
      72             : #endif
      73             : 
      74             : typedef struct _oslSignalHandlerImpl
      75             : {
      76             :     oslSignalHandlerFunction      Handler;
      77             :     void*                         pData;
      78             :     struct _oslSignalHandlerImpl* pNext;
      79             : } oslSignalHandlerImpl;
      80             : 
      81             : static struct SignalAction
      82             : {
      83             :     int Signal;
      84             :     int Action;
      85             :     void (*Handler)(int);
      86             : } Signals[] =
      87             : {
      88             :     { SIGHUP,    ACT_HIDE, NULL },    /* hangup */
      89             :     { SIGINT,    ACT_EXIT,   NULL },    /* interrupt (rubout) */
      90             :     { SIGQUIT,   ACT_EXIT,  NULL },    /* quit (ASCII FS) */
      91             :     { SIGILL,    ACT_SYSTEM,  NULL },    /* illegal instruction (not reset when caught) */
      92             : /* changed from ACT_ABOUT to ACT_SYSTEM to try and get collector to run*/
      93             :     { SIGTRAP,   ACT_ABORT,  NULL },    /* trace trap (not reset when caught) */
      94             : #if ( SIGIOT != SIGABRT )
      95             :     { SIGIOT,    ACT_ABORT,  NULL },    /* IOT instruction */
      96             : #endif
      97             :     { SIGABRT,   ACT_ABORT,  NULL },    /* used by abort, replace SIGIOT in the future */
      98             : #ifdef SIGEMT
      99             :     { SIGEMT,    ACT_SYSTEM,  NULL },    /* EMT instruction */
     100             : /* changed from ACT_ABORT to ACT_SYSTEM to remove handler*/
     101             : /* SIGEMT may also be used by the profiler - so it is probably not a good
     102             : plan to have the new handler use this signal*/
     103             : #endif
     104             :     { SIGFPE,    ACT_ABORT,  NULL },    /* floating point exception */
     105             :     { SIGKILL,   ACT_SYSTEM, NULL },    /* kill (cannot be caught or ignored) */
     106             :     { SIGBUS,    ACT_ABORT,  NULL },    /* bus error */
     107             :     { SIGSEGV,   ACT_ABORT,  NULL },    /* segmentation violation */
     108             : #ifdef SIGSYS
     109             :     { SIGSYS,    ACT_ABORT,  NULL },    /* bad argument to system call */
     110             : #endif
     111             :     { SIGPIPE,   ACT_HIDE,   NULL },    /* write on a pipe with no one to read it */
     112             :     { SIGALRM,   ACT_EXIT,   NULL },    /* alarm clock */
     113             :     { SIGTERM,   ACT_EXIT,   NULL },    /* software termination signal from kill */
     114             :     { SIGUSR1,   ACT_SYSTEM, NULL },    /* user defined signal 1 */
     115             :     { SIGUSR2,   ACT_SYSTEM, NULL },    /* user defined signal 2 */
     116             :     { SIGCHLD,   ACT_SYSTEM, NULL },    /* child status change */
     117             : #ifdef SIGPWR
     118             :     { SIGPWR,    ACT_IGNORE, NULL },    /* power-fail restart */
     119             : #endif
     120             :     { SIGWINCH,  ACT_IGNORE, NULL },    /* window size change */
     121             :     { SIGURG,    ACT_EXIT,   NULL },    /* urgent socket condition */
     122             : #ifdef SIGPOLL
     123             :     { SIGPOLL,   ACT_EXIT,   NULL },    /* pollable event occurred */
     124             : #endif
     125             :     { SIGSTOP,   ACT_SYSTEM, NULL },    /* stop (cannot be caught or ignored) */
     126             :     { SIGTSTP,   ACT_SYSTEM, NULL },    /* user stop requested from tty */
     127             :     { SIGCONT,   ACT_SYSTEM, NULL },    /* stopped process has been continued */
     128             :     { SIGTTIN,   ACT_SYSTEM, NULL },    /* background tty read attempted */
     129             :     { SIGTTOU,   ACT_SYSTEM, NULL },    /* background tty write attempted */
     130             :     { SIGVTALRM, ACT_EXIT,   NULL },    /* virtual timer expired */
     131             :     { SIGPROF,   ACT_SYSTEM,   NULL },    /* profiling timer expired */
     132             : /*Change from ACT_EXIT to ACT_SYSTEM for SIGPROF is so that profiling signals do
     133             : not get taken by the new handler - the new handler does not pass on context
     134             : information which causes 'collect' to crash. This is a way of avoiding
     135             : what looks like a bug in the new handler*/
     136             :     { SIGXCPU,   ACT_ABORT,  NULL },    /* exceeded cpu limit */
     137             :     { SIGXFSZ,   ACT_ABORT,  NULL }     /* exceeded file size limit */
     138             : };
     139             : const int NoSignals = sizeof(Signals) / sizeof(struct SignalAction);
     140             : 
     141             : static bool               bErrorReportingEnabled = true;
     142             : static bool               bInitSignal = false;
     143             : static oslMutex               SignalListMutex;
     144             : static oslSignalHandlerImpl*  SignalList;
     145             : static bool               bSetSEGVHandler = false;
     146             : static bool               bSetWINCHHandler = false;
     147             : static bool               bSetILLHandler = false;
     148             : 
     149             : static void SignalHandlerFunction(int);
     150             : 
     151         245 : static void getExecutableName_Impl (rtl_String ** ppstrProgName)
     152             : {
     153         245 :     rtl_uString * ustrProgFile = 0;
     154         245 :     osl_getExecutableFile (&ustrProgFile);
     155         245 :     if (ustrProgFile)
     156             :     {
     157         245 :         rtl_uString * ustrProgName = 0;
     158         245 :         osl_systemPathGetFileNameOrLastDirectoryPart (ustrProgFile, &ustrProgName);
     159         245 :         if (ustrProgName != 0)
     160             :         {
     161             :             rtl_uString2String (
     162             :                 ppstrProgName,
     163         245 :                 rtl_uString_getStr (ustrProgName), rtl_uString_getLength (ustrProgName),
     164         245 :                 osl_getThreadTextEncoding(),
     165         490 :                 OUSTRING_TO_OSTRING_CVTFLAGS);
     166         245 :             rtl_uString_release (ustrProgName);
     167             :         }
     168         245 :         rtl_uString_release (ustrProgFile);
     169             :     }
     170         245 : }
     171             : 
     172         245 : static bool is_soffice_Impl()
     173             : {
     174         245 :     sal_Int32    idx       = -1;
     175         245 :     rtl_String * strProgName = 0;
     176             : 
     177         245 :     getExecutableName_Impl (&strProgName);
     178         245 :     if (strProgName)
     179             :     {
     180         245 :         idx = rtl_str_indexOfStr (rtl_string_getStr (strProgName), "soffice");
     181         245 :         rtl_string_release (strProgName);
     182             :     }
     183         245 :     return (idx != -1);
     184             : }
     185             : 
     186         245 : static bool InitSignal()
     187             : {
     188             :     int i;
     189             :     struct sigaction act;
     190             :     struct sigaction oact;
     191             :     sigset_t unset;
     192             : 
     193         245 :     if (is_soffice_Impl())
     194             :     {
     195             :         // WORKAROUND FOR SEGV HANDLER CONFLICT
     196             :         //
     197             :         // the java jit needs SIGSEGV for proper work
     198             :         // and we need SIGSEGV for the office crashguard
     199             :         //
     200             :         // TEMPORARY SOLUTION:
     201             :         //   the office sets the signal handler during startup
     202             :         //   java can than overwrite it, if needed
     203         115 :         bSetSEGVHandler = true;
     204             : 
     205             :         // WORKAROUND FOR WINCH HANDLER (SEE ABOVE)
     206         115 :         bSetWINCHHandler = true;
     207             : 
     208             :         // WORKAROUND FOR ILLEGAL INSTRUCTION HANDLER (SEE ABOVE)
     209         115 :         bSetILLHandler = true;
     210             :     }
     211             : 
     212             : #ifdef DBG_UTIL
     213             :     bSetSEGVHandler = bSetWINCHHandler = bSetILLHandler = false;
     214             : #endif
     215             : 
     216         245 :     SignalListMutex = osl_createMutex();
     217             : 
     218         245 :     act.sa_handler = SignalHandlerFunction;
     219         245 :     act.sa_flags   = SA_RESTART;
     220             : 
     221         245 :     sigfillset(&(act.sa_mask));
     222             : 
     223             :     /* Initialize the rest of the signals */
     224        7595 :     for (i = 0; i < NoSignals; ++i)
     225             :     {
     226             : #if defined HAVE_VALGRIND_HEADERS
     227        7350 :         if (Signals[i].Signal == SIGUSR2 && RUNNING_ON_VALGRIND)
     228           0 :             Signals[i].Action = ACT_IGNORE;
     229             : #endif
     230             : 
     231             :         /* hack: stomcatd is attaching JavaVM which does not work with an sigaction(SEGV) */
     232        7350 :         if ((bSetSEGVHandler || Signals[i].Signal != SIGSEGV)
     233        7220 :         && (bSetWINCHHandler || Signals[i].Signal != SIGWINCH)
     234        7090 :         && (bSetILLHandler   || Signals[i].Signal != SIGILL))
     235             :         {
     236        6960 :             if (Signals[i].Action != ACT_SYSTEM)
     237             :             {
     238        2565 :                 if (Signals[i].Action == ACT_HIDE)
     239             :                 {
     240             :                     struct sigaction ign;
     241             : 
     242         490 :                     ign.sa_handler = SIG_IGN;
     243         490 :                     ign.sa_flags   = 0;
     244         490 :                     sigemptyset(&ign.sa_mask);
     245             : 
     246         490 :                     if (sigaction(Signals[i].Signal, &ign, &oact) == 0)
     247         490 :                         Signals[i].Handler = oact.sa_handler;
     248             :                     else
     249           0 :                         Signals[i].Handler = SIG_DFL;
     250             :                 }
     251             :                 else
     252             :                 {
     253        2075 :                     if (sigaction(Signals[i].Signal, &act, &oact) == 0)
     254        2075 :                         Signals[i].Handler = oact.sa_handler;
     255             :                     else
     256           0 :                         Signals[i].Handler = SIG_DFL;
     257             :                 }
     258             :             }
     259             :         }
     260             :     }
     261             : 
     262             :     /* Clear signal mask inherited from parent process (on Mac OS X, upon a
     263             :        crash soffice re-execs itself from within the signal handler, so the
     264             :        second soffice would have the guilty signal blocked and would freeze upon
     265             :        encountering a similar crash again): */
     266         490 :     if (sigemptyset(&unset) < 0 ||
     267         245 :         pthread_sigmask(SIG_SETMASK, &unset, NULL) < 0)
     268             :     {
     269             :         OSL_TRACE("sigemptyset or pthread_sigmask failed");
     270             :     }
     271             : 
     272         245 :     return true;
     273             : }
     274             : 
     275         242 : static bool DeInitSignal()
     276             : {
     277             :     int i;
     278             :     struct sigaction act;
     279             : 
     280         242 :     act.sa_flags   = 0;
     281         242 :     sigemptyset(&(act.sa_mask));
     282             : 
     283             :     /* Initialize the rest of the signals */
     284        7502 :     for (i = NoSignals - 1; i >= 0; i--)
     285        7260 :         if (Signals[i].Action != ACT_SYSTEM)
     286             :         {
     287        2662 :             act.sa_handler = Signals[i].Handler;
     288             : 
     289        2662 :             sigaction(Signals[i].Signal, &act, NULL);
     290             :         }
     291             : 
     292         242 :     osl_destroyMutex(SignalListMutex);
     293             : 
     294         242 :     return false;
     295             : }
     296             : 
     297           0 : static void PrintStack( int sig )
     298             : {
     299             : #ifdef INCLUDE_BACKTRACE
     300             :     void *buffer[MAX_STACK_FRAMES];
     301           0 :     int size = backtrace( buffer, SAL_N_ELEMENTS(buffer) );
     302             : #endif
     303             : 
     304           0 :     fprintf( stderr, "\n\nFatal exception: Signal %d\n", sig );
     305             : 
     306             : #if defined( MACOSX ) && !defined( INCLUDE_BACKTRACE )
     307             :     fprintf( stderr, "Please turn on Enable Crash Reporting and\nAutomatic Display of Crashlogs in the Console application\n" );
     308             : #else
     309             : #ifdef INCLUDE_BACKTRACE
     310           0 :     if ( size > 0 )
     311             :     {
     312           0 :         fputs( "Stack:\n", stderr );
     313           0 :         backtrace_symbols_fd( buffer, size, fileno(stderr) );
     314             :     }
     315             : #endif
     316             : #endif
     317           0 : }
     318             : 
     319           0 : static oslSignalAction CallSignalHandler(oslSignalInfo *pInfo)
     320             : {
     321           0 :     oslSignalHandlerImpl* pHandler = SignalList;
     322           0 :     oslSignalAction Action = osl_Signal_ActCallNextHdl;
     323             : 
     324           0 :     while (pHandler != NULL)
     325             :     {
     326           0 :         if ((Action = pHandler->Handler(pHandler->pData, pInfo))
     327             :             != osl_Signal_ActCallNextHdl)
     328           0 :             break;
     329             : 
     330           0 :         pHandler = pHandler->pNext;
     331             :     }
     332             : 
     333           0 :     return Action;
     334             : }
     335             : 
     336           0 : void CallSystemHandler(int Signal)
     337             : {
     338             :     int i;
     339             :     struct sigaction act;
     340             : 
     341           0 :     for (i = 0; i < NoSignals; i++)
     342             :     {
     343           0 :         if (Signals[i].Signal == Signal)
     344           0 :             break;
     345             :     }
     346             : 
     347           0 :     if (i < NoSignals)
     348             :     {
     349           0 :         if ((Signals[i].Handler == NULL)    ||
     350           0 :             (Signals[i].Handler == SIG_DFL) ||
     351           0 :             (Signals[i].Handler == SIG_IGN) ||
     352           0 :              (Signals[i].Handler == SIG_ERR))
     353             :         {
     354           0 :             switch (Signals[i].Action)
     355             :             {
     356             :                 case ACT_EXIT:      /* terminate */
     357             :                     /* prevent dumping core on exit() */
     358           0 :                     _exit(255);
     359             :                     break;
     360             : 
     361             :                 case ACT_ABORT:     /* terminate witch core dump */
     362           0 :                     act.sa_handler = SIG_DFL;
     363           0 :                     act.sa_flags   = 0;
     364           0 :                     sigemptyset(&(act.sa_mask));
     365           0 :                     sigaction(SIGABRT, &act, NULL);
     366           0 :                     PrintStack( Signal );
     367           0 :                     abort();
     368             :                     break;
     369             : 
     370             :                 case ACT_IGNORE:    /* ignore */
     371           0 :                     break;
     372             : 
     373             :                 default:            /* should never happen */
     374             :                     OSL_ASSERT(false);
     375             :             }
     376             :         }
     377             :         else
     378           0 :             (*Signals[i].Handler)(Signal);
     379             :     }
     380           0 : }
     381             : 
     382             : #if defined HAVE_VALGRIND_HEADERS
     383           0 : static void DUMPCURRENTALLOCS()
     384             : {
     385           0 :     VALGRIND_PRINTF( "=== start memcheck dump of active allocations ===\n" );
     386             : 
     387             : #if __GNUC__ && !defined(__clang__)
     388             : #   pragma GCC diagnostic push
     389             : #   pragma GCC diagnostic ignored "-Wunused-but-set-variable"
     390             : #endif
     391             : 
     392           0 :     VALGRIND_DO_LEAK_CHECK;
     393             : 
     394             : #if __GNUC__ && !defined(__clang__)
     395             : #   pragma GCC diagnostic pop
     396             : #endif
     397             : 
     398           0 :     VALGRIND_PRINTF( "=== end memcheck dump of active allocations ===\n" );
     399           0 : }
     400             : #endif
     401             : 
     402           0 : void SignalHandlerFunction(int Signal)
     403             : {
     404             :     oslSignalInfo    Info;
     405             :     struct sigaction act;
     406             : 
     407           0 :     Info.UserSignal = Signal;
     408           0 :     Info.UserData   = NULL;
     409             : 
     410           0 :     switch (Signal)
     411             :     {
     412             :         case SIGBUS:
     413             :         case SIGILL:
     414             :         case SIGSEGV:
     415             :         case SIGIOT:
     416             : #if ( SIGIOT != SIGABRT )
     417             :         case SIGABRT:
     418             : #endif
     419           0 :             Info.Signal = osl_Signal_AccessViolation;
     420           0 :             break;
     421             : 
     422             :         case -1:
     423           0 :             Info.Signal = osl_Signal_IntegerDivideByZero;
     424           0 :             break;
     425             : 
     426             :         case SIGFPE:
     427           0 :             Info.Signal = osl_Signal_FloatDivideByZero;
     428           0 :             break;
     429             : 
     430             :         case SIGINT:
     431             :         case SIGTERM:
     432             :         case SIGQUIT:
     433           0 :             Info.Signal = osl_Signal_Terminate;
     434           0 :             break;
     435             : 
     436             : #if defined HAVE_VALGRIND_HEADERS
     437             :         case SIGUSR2:
     438           0 :             if (RUNNING_ON_VALGRIND)
     439           0 :                 DUMPCURRENTALLOCS();
     440           0 :             Info.Signal = osl_Signal_System;
     441           0 :             break;
     442             : #endif
     443             : 
     444             :         default:
     445           0 :             Info.Signal = osl_Signal_System;
     446           0 :             break;
     447             :     }
     448             : 
     449           0 :     switch (CallSignalHandler(&Info))
     450             :     {
     451             :     case osl_Signal_ActCallNextHdl:
     452           0 :         CallSystemHandler(Signal);
     453           0 :         break;
     454             : 
     455             :     case osl_Signal_ActAbortApp:
     456           0 :         act.sa_handler = SIG_DFL;
     457           0 :         act.sa_flags   = 0;
     458           0 :         sigemptyset(&(act.sa_mask));
     459           0 :         sigaction(SIGABRT, &act, NULL);
     460           0 :         PrintStack( Signal );
     461           0 :         abort();
     462             :         break;
     463             : 
     464             :     case osl_Signal_ActKillApp:
     465             :         /* prevent dumping core on exit() */
     466           0 :         _exit(255);
     467             :         break;
     468             :     default:
     469           0 :         break;
     470             :     }
     471           0 : }
     472             : 
     473         361 : oslSignalHandler SAL_CALL osl_addSignalHandler(oslSignalHandlerFunction Handler, void* pData)
     474             : {
     475             :     oslSignalHandlerImpl* pHandler;
     476             : 
     477             :     OSL_ASSERT(Handler != NULL);
     478         361 :     if ( Handler == 0 )
     479             :     {
     480           0 :         return 0;
     481             :     }
     482             : 
     483         361 :     if (! bInitSignal)
     484         245 :         bInitSignal = InitSignal();
     485             : 
     486         361 :     pHandler = static_cast<oslSignalHandlerImpl*>(calloc(1, sizeof(oslSignalHandlerImpl)));
     487             : 
     488         361 :     if (pHandler != NULL)
     489             :     {
     490         361 :         pHandler->Handler = Handler;
     491         361 :         pHandler->pData   = pData;
     492             : 
     493         361 :         osl_acquireMutex(SignalListMutex);
     494             : 
     495         361 :         pHandler->pNext = SignalList;
     496         361 :         SignalList      = pHandler;
     497             : 
     498         361 :         osl_releaseMutex(SignalListMutex);
     499             : 
     500         361 :         return (pHandler);
     501             :     }
     502             : 
     503           0 :     return NULL;
     504             : }
     505             : 
     506         358 : sal_Bool SAL_CALL osl_removeSignalHandler(oslSignalHandler Handler)
     507             : {
     508         358 :     oslSignalHandlerImpl *pHandler, *pPrevious = NULL;
     509             : 
     510             :     OSL_ASSERT(Handler != NULL);
     511             : 
     512         358 :     if (! bInitSignal)
     513           0 :         bInitSignal = InitSignal();
     514             : 
     515         358 :     osl_acquireMutex(SignalListMutex);
     516             : 
     517         358 :     pHandler = SignalList;
     518             : 
     519         716 :     while (pHandler != NULL)
     520             :     {
     521         358 :         if (pHandler == Handler)
     522             :         {
     523         358 :             if (pPrevious)
     524           0 :                 pPrevious->pNext = pHandler->pNext;
     525             :             else
     526         358 :                 SignalList = pHandler->pNext;
     527             : 
     528         358 :             osl_releaseMutex(SignalListMutex);
     529             : 
     530         358 :             if (SignalList == NULL)
     531         242 :                 bInitSignal = DeInitSignal();
     532             : 
     533         358 :             free(pHandler);
     534             : 
     535         358 :             return sal_True;
     536             :         }
     537             : 
     538           0 :         pPrevious = pHandler;
     539           0 :         pHandler  = pHandler->pNext;
     540             :     }
     541             : 
     542           0 :     osl_releaseMutex(SignalListMutex);
     543             : 
     544           0 :     return sal_False;
     545             : }
     546             : 
     547           0 : oslSignalAction SAL_CALL osl_raiseSignal(sal_Int32 UserSignal, void* UserData)
     548             : {
     549             :     oslSignalInfo   Info;
     550             :     oslSignalAction Action;
     551             : 
     552           0 :     if (! bInitSignal)
     553           0 :         bInitSignal = InitSignal();
     554             : 
     555           0 :     osl_acquireMutex(SignalListMutex);
     556             : 
     557           0 :     Info.Signal     = osl_Signal_User;
     558           0 :     Info.UserSignal = UserSignal;
     559           0 :     Info.UserData   = UserData;
     560             : 
     561           0 :     Action = CallSignalHandler(&Info);
     562             : 
     563           0 :     osl_releaseMutex(SignalListMutex);
     564             : 
     565           0 :     return (Action);
     566             : }
     567             : 
     568         116 : sal_Bool SAL_CALL osl_setErrorReporting( sal_Bool bEnable )
     569             : {
     570         116 :     bool bOld = bErrorReportingEnabled;
     571         116 :     bErrorReportingEnabled = bEnable;
     572             : 
     573         116 :     return bOld;
     574             : }
     575             : 
     576             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11