xref: /AOO41X/main/sal/osl/w32/signal.cxx (revision e1c63fd964ba130fb7c33234fe0d975ac26c34e8)
187d2adbcSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
387d2adbcSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
487d2adbcSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
587d2adbcSAndrew Rist  * distributed with this work for additional information
687d2adbcSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
787d2adbcSAndrew Rist  * to you under the Apache License, Version 2.0 (the
887d2adbcSAndrew Rist  * "License"); you may not use this file except in compliance
987d2adbcSAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
1187d2adbcSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
1387d2adbcSAndrew Rist  * Unless required by applicable law or agreed to in writing,
1487d2adbcSAndrew Rist  * software distributed under the License is distributed on an
1587d2adbcSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1687d2adbcSAndrew Rist  * KIND, either express or implied.  See the License for the
1787d2adbcSAndrew Rist  * specific language governing permissions and limitations
1887d2adbcSAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
2087d2adbcSAndrew Rist  *************************************************************/
2187d2adbcSAndrew Rist 
2287d2adbcSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir /* system headers */
25cdf0e10cSrcweir #include "system.h"
26cdf0e10cSrcweir #include <tchar.h>
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #include "file_url.h"
29cdf0e10cSrcweir #include "path_helper.hxx"
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #include <osl/diagnose.h>
32cdf0e10cSrcweir #include <osl/mutex.h>
33cdf0e10cSrcweir #include <osl/signal.h>
34cdf0e10cSrcweir #ifndef __MINGW32__
35cdf0e10cSrcweir #include <DbgHelp.h>
36cdf0e10cSrcweir #endif
37cdf0e10cSrcweir #include <ErrorRep.h>
38cdf0e10cSrcweir #include <systools/win32/uwinapi.h>
39747164b0SHerbert Dürr #include <eh.h>
40747164b0SHerbert Dürr #include <stdexcept>
41cdf0e10cSrcweir 
42cdf0e10cSrcweir typedef struct _oslSignalHandlerImpl
43cdf0e10cSrcweir {
44cdf0e10cSrcweir     oslSignalHandlerFunction      Handler;
45cdf0e10cSrcweir     void*                         pData;
46cdf0e10cSrcweir     struct _oslSignalHandlerImpl* pNext;
47cdf0e10cSrcweir } oslSignalHandlerImpl;
48cdf0e10cSrcweir 
49cdf0e10cSrcweir static sal_Bool               bErrorReportingEnabled = sal_True;
50cdf0e10cSrcweir static sal_Bool               bInitSignal = sal_False;
51cdf0e10cSrcweir static oslMutex               SignalListMutex;
52cdf0e10cSrcweir static oslSignalHandlerImpl*  SignalList;
53cdf0e10cSrcweir 
54cdf0e10cSrcweir static long WINAPI SignalHandlerFunction(LPEXCEPTION_POINTERS lpEP);
55cdf0e10cSrcweir 
56*e1c63fd9SArrigo Marchiori static _invalid_parameter_handler pPreviousInvalidParameterHandler = NULL;
57*e1c63fd9SArrigo Marchiori static void InvalidParameterHandlerFunction(
58*e1c63fd9SArrigo Marchiori     const wchar_t* expression,
59*e1c63fd9SArrigo Marchiori     const wchar_t* function,
60*e1c63fd9SArrigo Marchiori     const wchar_t* file,
61*e1c63fd9SArrigo Marchiori     unsigned int line,
62*e1c63fd9SArrigo Marchiori     uintptr_t pReserved );
63*e1c63fd9SArrigo Marchiori 
InitSignal(void)64cdf0e10cSrcweir static sal_Bool InitSignal(void)
65cdf0e10cSrcweir {
66cdf0e10cSrcweir     HMODULE hFaultRep;
67cdf0e10cSrcweir 
68cdf0e10cSrcweir     SignalListMutex = osl_createMutex();
69cdf0e10cSrcweir 
70cdf0e10cSrcweir     SetUnhandledExceptionFilter(SignalHandlerFunction);
71*e1c63fd9SArrigo Marchiori     if ( pPreviousInvalidParameterHandler == NULL )
72*e1c63fd9SArrigo Marchiori     {
73*e1c63fd9SArrigo Marchiori         pPreviousInvalidParameterHandler = _set_invalid_parameter_handler( InvalidParameterHandlerFunction );
74*e1c63fd9SArrigo Marchiori     }
75cdf0e10cSrcweir 
76cdf0e10cSrcweir     hFaultRep = LoadLibrary( "faultrep.dll" );
77cdf0e10cSrcweir     if ( hFaultRep )
78cdf0e10cSrcweir     {
79cdf0e10cSrcweir #ifdef __MINGW32__
80cdf0e10cSrcweir typedef BOOL (WINAPI *pfn_ADDEREXCLUDEDAPPLICATIONW)(LPCWSTR);
81cdf0e10cSrcweir #endif
82cdf0e10cSrcweir         pfn_ADDEREXCLUDEDAPPLICATIONW       pfn = (pfn_ADDEREXCLUDEDAPPLICATIONW)GetProcAddress( hFaultRep, "AddERExcludedApplicationW" );
83cdf0e10cSrcweir         if ( pfn )
84cdf0e10cSrcweir             pfn( L"SOFFICE.EXE" );
85cdf0e10cSrcweir         FreeLibrary( hFaultRep );
86cdf0e10cSrcweir     }
87cdf0e10cSrcweir 
88cdf0e10cSrcweir     return sal_True;
89cdf0e10cSrcweir }
90cdf0e10cSrcweir 
DeInitSignal(void)91cdf0e10cSrcweir static sal_Bool DeInitSignal(void)
92cdf0e10cSrcweir {
93cdf0e10cSrcweir     SetUnhandledExceptionFilter(NULL);
94cdf0e10cSrcweir 
95*e1c63fd9SArrigo Marchiori     if ( pPreviousInvalidParameterHandler )
96*e1c63fd9SArrigo Marchiori     {
97*e1c63fd9SArrigo Marchiori         _set_invalid_parameter_handler( pPreviousInvalidParameterHandler );
98*e1c63fd9SArrigo Marchiori         pPreviousInvalidParameterHandler = NULL;
99*e1c63fd9SArrigo Marchiori     }
100cdf0e10cSrcweir     osl_destroyMutex(SignalListMutex);
101cdf0e10cSrcweir 
102cdf0e10cSrcweir     return sal_False;
103cdf0e10cSrcweir }
104cdf0e10cSrcweir 
CallSignalHandler(oslSignalInfo * pInfo)105cdf0e10cSrcweir static oslSignalAction CallSignalHandler(oslSignalInfo *pInfo)
106cdf0e10cSrcweir {
107cdf0e10cSrcweir     oslSignalHandlerImpl* pHandler = SignalList;
108cdf0e10cSrcweir     oslSignalAction Action = osl_Signal_ActCallNextHdl;
109cdf0e10cSrcweir 
110cdf0e10cSrcweir     while (pHandler != NULL)
111cdf0e10cSrcweir     {
112cdf0e10cSrcweir         if ((Action = pHandler->Handler(pHandler->pData, pInfo)) != osl_Signal_ActCallNextHdl)
113cdf0e10cSrcweir             break;
114cdf0e10cSrcweir 
115cdf0e10cSrcweir         pHandler = pHandler->pNext;
116cdf0e10cSrcweir     }
117cdf0e10cSrcweir 
118cdf0e10cSrcweir     return Action;
119cdf0e10cSrcweir }
120cdf0e10cSrcweir 
121cdf0e10cSrcweir /*****************************************************************************/
122cdf0e10cSrcweir /* SignalHandlerFunction    */
123cdf0e10cSrcweir /*****************************************************************************/
124cdf0e10cSrcweir 
125cdf0e10cSrcweir #define REPORTENV_PARAM     "-crashreportenv:"
126cdf0e10cSrcweir #define REPORTENV_PARAM2    "/crashreportenv:"
127cdf0e10cSrcweir 
ReportCrash(LPEXCEPTION_POINTERS lpEP)128cdf0e10cSrcweir static BOOL ReportCrash( LPEXCEPTION_POINTERS lpEP )
129cdf0e10cSrcweir {
130cdf0e10cSrcweir     BOOL    fSuccess = FALSE;
131cdf0e10cSrcweir     BOOL    fAutoReport = FALSE;
132cdf0e10cSrcweir     TCHAR   szBuffer[1024];
133cdf0e10cSrcweir     ::osl::LongPathBuffer< sal_Char > aPath( MAX_LONG_PATH );
134cdf0e10cSrcweir     LPTSTR  lpFilePart;
135cdf0e10cSrcweir     PROCESS_INFORMATION ProcessInfo;
136cdf0e10cSrcweir     STARTUPINFO StartupInfo;
137cdf0e10cSrcweir     int     argi;
138cdf0e10cSrcweir 
139cdf0e10cSrcweir     if ( !bErrorReportingEnabled )
140cdf0e10cSrcweir         return FALSE;
141cdf0e10cSrcweir 
142cdf0e10cSrcweir     /* Check if crash reporter was disabled by command line */
143cdf0e10cSrcweir 
144cdf0e10cSrcweir     for ( argi = 1; argi < __argc; argi++ )
145cdf0e10cSrcweir     {
146cdf0e10cSrcweir         if (
147cdf0e10cSrcweir             0 == stricmp( __argv[argi], "-nocrashreport" ) ||
148cdf0e10cSrcweir             0 == stricmp( __argv[argi], "/nocrashreport" )
149cdf0e10cSrcweir             )
150cdf0e10cSrcweir             return FALSE;
151cdf0e10cSrcweir         else if (
152cdf0e10cSrcweir             0 == stricmp( __argv[argi], "-autocrashreport" ) ||
153cdf0e10cSrcweir             0 == stricmp( __argv[argi], "/autocrashreport" )
154cdf0e10cSrcweir             )
155cdf0e10cSrcweir             fAutoReport = TRUE;
156cdf0e10cSrcweir         else if (
157cdf0e10cSrcweir             0 == strnicmp( __argv[argi], REPORTENV_PARAM, strlen(REPORTENV_PARAM) ) ||
158cdf0e10cSrcweir             0 == strnicmp( __argv[argi], REPORTENV_PARAM2, strlen(REPORTENV_PARAM2) )
159cdf0e10cSrcweir             )
160cdf0e10cSrcweir         {
161cdf0e10cSrcweir             const char *envparam = __argv[argi] + strlen(REPORTENV_PARAM);
162cdf0e10cSrcweir             const char *delim = strchr(envparam, '=' );
163cdf0e10cSrcweir 
164cdf0e10cSrcweir             if ( delim )
165cdf0e10cSrcweir             {
166cdf0e10cSrcweir                 CHAR    *lpVariable;
167cdf0e10cSrcweir                 CHAR    *lpValue;
168cdf0e10cSrcweir                 const char *variable = envparam;
169cdf0e10cSrcweir                 size_t variable_len = delim - envparam;
170cdf0e10cSrcweir                 const char *value = delim + 1;
171cdf0e10cSrcweir                 size_t value_len = strlen(envparam) - variable_len - 1;
172cdf0e10cSrcweir 
173cdf0e10cSrcweir                 if ( '\"' == *value )
174cdf0e10cSrcweir                 {
175cdf0e10cSrcweir                     const char *quote;
176cdf0e10cSrcweir 
177cdf0e10cSrcweir                     value++;
178cdf0e10cSrcweir                     value_len--;
179cdf0e10cSrcweir 
180cdf0e10cSrcweir                     quote = strchr( value, '\"' );
181cdf0e10cSrcweir                     if ( quote )
182cdf0e10cSrcweir                         value_len = quote - value;
183cdf0e10cSrcweir                 }
184cdf0e10cSrcweir 
185cdf0e10cSrcweir                 lpVariable = reinterpret_cast< CHAR* >( _alloca( variable_len + 1 ) );
186cdf0e10cSrcweir                 memcpy( lpVariable, variable, variable_len );
187cdf0e10cSrcweir                 lpVariable[variable_len] = 0;
188cdf0e10cSrcweir 
189cdf0e10cSrcweir                 lpValue = reinterpret_cast< CHAR* >( _alloca( value_len + 1) );
190cdf0e10cSrcweir                 memcpy( lpValue, value, value_len );
191cdf0e10cSrcweir                 lpValue[value_len] = 0;
192cdf0e10cSrcweir 
193cdf0e10cSrcweir                 SetEnvironmentVariable( lpVariable, lpValue );
194cdf0e10cSrcweir             }
195cdf0e10cSrcweir         }
196cdf0e10cSrcweir     }
197cdf0e10cSrcweir 
198cdf0e10cSrcweir     if ( SearchPath( NULL, TEXT( "crashrep.exe" ), NULL, aPath.getBufSizeInSymbols(), aPath, &lpFilePart ) )
199cdf0e10cSrcweir     {
200cdf0e10cSrcweir         ZeroMemory( &StartupInfo, sizeof(StartupInfo) );
201cdf0e10cSrcweir         StartupInfo.cb = sizeof(StartupInfo.cb);
202cdf0e10cSrcweir 
203cdf0e10cSrcweir 
204cdf0e10cSrcweir         sntprintf( szBuffer, elementsof(szBuffer),
205cdf0e10cSrcweir             _T("%s -p %u -excp 0x%p -t %u%s"),
206cdf0e10cSrcweir             static_cast<sal_Char*>( aPath ),
207cdf0e10cSrcweir             GetCurrentProcessId(),
208cdf0e10cSrcweir             lpEP,
209cdf0e10cSrcweir             GetCurrentThreadId(),
210cdf0e10cSrcweir             fAutoReport ? _T(" -noui -send") : _T(" -noui") );
211cdf0e10cSrcweir 
212cdf0e10cSrcweir         if (
213cdf0e10cSrcweir             CreateProcess(
214cdf0e10cSrcweir                 NULL,
215cdf0e10cSrcweir                 szBuffer,
216cdf0e10cSrcweir                 NULL,
217cdf0e10cSrcweir                 NULL,
218cdf0e10cSrcweir                 FALSE,
219cdf0e10cSrcweir #ifdef UNICODE
220cdf0e10cSrcweir                 CREATE_UNICODE_ENVIRONMENT,
221cdf0e10cSrcweir #else
222cdf0e10cSrcweir                 0,
223cdf0e10cSrcweir #endif
224cdf0e10cSrcweir                 NULL, NULL, &StartupInfo, &ProcessInfo )
225cdf0e10cSrcweir             )
226cdf0e10cSrcweir         {
227cdf0e10cSrcweir             DWORD   dwExitCode;
228cdf0e10cSrcweir 
229cdf0e10cSrcweir             WaitForSingleObject( ProcessInfo.hProcess, INFINITE );
230cdf0e10cSrcweir             if ( GetExitCodeProcess( ProcessInfo.hProcess, &dwExitCode ) && 0 == dwExitCode )
231cdf0e10cSrcweir 
232cdf0e10cSrcweir             fSuccess = TRUE;
233cdf0e10cSrcweir 
234cdf0e10cSrcweir         }
235cdf0e10cSrcweir     }
236cdf0e10cSrcweir 
237cdf0e10cSrcweir     return fSuccess;
238cdf0e10cSrcweir }
239cdf0e10cSrcweir 
240cdf0e10cSrcweir /*****************************************************************************/
241cdf0e10cSrcweir /* SignalHandlerFunction    */
242cdf0e10cSrcweir /*****************************************************************************/
243cdf0e10cSrcweir 
IsWin95A(void)244cdf0e10cSrcweir static BOOL WINAPI IsWin95A(void)
245cdf0e10cSrcweir {
246cdf0e10cSrcweir     OSVERSIONINFO   ovi;
247cdf0e10cSrcweir 
248cdf0e10cSrcweir     ZeroMemory( &ovi, sizeof(ovi) );
249cdf0e10cSrcweir     ovi.dwOSVersionInfoSize = sizeof(ovi);
250cdf0e10cSrcweir 
251cdf0e10cSrcweir     if ( GetVersionEx( &ovi ) )
252cdf0e10cSrcweir         /* See MSDN January 2000 documentation of GetVersionEx */
253cdf0e10cSrcweir         return  (ovi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) &&
254cdf0e10cSrcweir                 (ovi.dwMajorVersion <= 4) &&
255cdf0e10cSrcweir                 (ovi.dwMinorVersion == 0) &&
256cdf0e10cSrcweir                 (ovi.dwBuildNumber == 0x040003B6);
257cdf0e10cSrcweir 
258cdf0e10cSrcweir     /* Something wrent wrong. So assume we have an older operating prior Win95 */
259cdf0e10cSrcweir 
260cdf0e10cSrcweir     return TRUE;
261cdf0e10cSrcweir }
262cdf0e10cSrcweir 
263cdf0e10cSrcweir /* magic Microsoft C++ compiler exception constant */
264cdf0e10cSrcweir #define EXCEPTION_MSC_CPP_EXCEPTION 0xe06d7363
265cdf0e10cSrcweir 
SignalHandlerFunction(LPEXCEPTION_POINTERS lpEP)266cdf0e10cSrcweir static long WINAPI SignalHandlerFunction(LPEXCEPTION_POINTERS lpEP)
267cdf0e10cSrcweir {
268cdf0e10cSrcweir     static sal_Bool     bNested = sal_False;
269cdf0e10cSrcweir     sal_Bool        bRaiseCrashReporter = sal_False;
270cdf0e10cSrcweir     oslSignalInfo   Info;
271cdf0e10cSrcweir     oslSignalAction Action;
272cdf0e10cSrcweir 
273cdf0e10cSrcweir     Info.UserSignal = lpEP->ExceptionRecord->ExceptionCode;
274cdf0e10cSrcweir     Info.UserData   = NULL;
275cdf0e10cSrcweir 
276cdf0e10cSrcweir     switch (lpEP->ExceptionRecord->ExceptionCode)
277cdf0e10cSrcweir     {
278cdf0e10cSrcweir         /* Transform unhandled exceptions into access violations.
279cdf0e10cSrcweir            Microsoft C++ compiler (add more for other compilers if necessary).
280cdf0e10cSrcweir          */
281cdf0e10cSrcweir         case EXCEPTION_MSC_CPP_EXCEPTION:
282cdf0e10cSrcweir         case EXCEPTION_ACCESS_VIOLATION:
283cdf0e10cSrcweir             Info.Signal = osl_Signal_AccessViolation;
284cdf0e10cSrcweir             bRaiseCrashReporter = sal_True;
285cdf0e10cSrcweir             break;
286cdf0e10cSrcweir 
287cdf0e10cSrcweir         case EXCEPTION_INT_DIVIDE_BY_ZERO:
288cdf0e10cSrcweir             Info.Signal = osl_Signal_IntegerDivideByZero;
289cdf0e10cSrcweir             bRaiseCrashReporter = sal_True;
290cdf0e10cSrcweir             break;
291cdf0e10cSrcweir 
292cdf0e10cSrcweir         case EXCEPTION_FLT_DIVIDE_BY_ZERO:
293cdf0e10cSrcweir             Info.Signal = osl_Signal_FloatDivideByZero;
294cdf0e10cSrcweir             bRaiseCrashReporter = sal_True;
295cdf0e10cSrcweir             break;
296cdf0e10cSrcweir 
297cdf0e10cSrcweir         case EXCEPTION_BREAKPOINT:
298cdf0e10cSrcweir             Info.Signal = osl_Signal_DebugBreak;
299cdf0e10cSrcweir             break;
300cdf0e10cSrcweir 
301cdf0e10cSrcweir         default:
302cdf0e10cSrcweir             Info.Signal = osl_Signal_System;
303cdf0e10cSrcweir             bRaiseCrashReporter = sal_True;
304cdf0e10cSrcweir             break;
305cdf0e10cSrcweir     }
306cdf0e10cSrcweir 
307cdf0e10cSrcweir     if ( !bNested )
308cdf0e10cSrcweir     {
309cdf0e10cSrcweir         bNested = sal_True;
310cdf0e10cSrcweir 
311cdf0e10cSrcweir         if ( bRaiseCrashReporter && ReportCrash( lpEP ) || IsWin95A() )
312cdf0e10cSrcweir         {
313cdf0e10cSrcweir             CallSignalHandler(&Info);
314cdf0e10cSrcweir             Action = osl_Signal_ActKillApp;
315cdf0e10cSrcweir         }
316cdf0e10cSrcweir         else
317cdf0e10cSrcweir             Action = CallSignalHandler(&Info);
318cdf0e10cSrcweir     }
319cdf0e10cSrcweir     else
320cdf0e10cSrcweir         Action = osl_Signal_ActKillApp;
321cdf0e10cSrcweir 
322cdf0e10cSrcweir 
323cdf0e10cSrcweir     switch ( Action )
324cdf0e10cSrcweir     {
325cdf0e10cSrcweir         case osl_Signal_ActCallNextHdl:
326cdf0e10cSrcweir             return (EXCEPTION_CONTINUE_SEARCH);
327cdf0e10cSrcweir 
328cdf0e10cSrcweir         case osl_Signal_ActAbortApp:
329cdf0e10cSrcweir             return (EXCEPTION_EXECUTE_HANDLER);
330cdf0e10cSrcweir 
331cdf0e10cSrcweir         case osl_Signal_ActKillApp:
332cdf0e10cSrcweir             SetErrorMode(SEM_NOGPFAULTERRORBOX);
333cdf0e10cSrcweir             exit(255);
334cdf0e10cSrcweir             break;
335cdf0e10cSrcweir         default:
336cdf0e10cSrcweir             break;
337cdf0e10cSrcweir     }
338cdf0e10cSrcweir 
339cdf0e10cSrcweir     return (EXCEPTION_CONTINUE_EXECUTION);
340cdf0e10cSrcweir }
341cdf0e10cSrcweir 
InvalidParameterHandlerFunction(const wchar_t * expression,const wchar_t * function,const wchar_t * file,unsigned int line,uintptr_t pReserved)342*e1c63fd9SArrigo Marchiori static void InvalidParameterHandlerFunction(
343*e1c63fd9SArrigo Marchiori     const wchar_t* expression,
344*e1c63fd9SArrigo Marchiori     const wchar_t* function,
345*e1c63fd9SArrigo Marchiori     const wchar_t* file,
346*e1c63fd9SArrigo Marchiori     unsigned int line,
347*e1c63fd9SArrigo Marchiori     uintptr_t pReserved )
348*e1c63fd9SArrigo Marchiori {
349*e1c63fd9SArrigo Marchiori     oslSignalInfo   Info;
350*e1c63fd9SArrigo Marchiori 
351*e1c63fd9SArrigo Marchiori     fwprintf(stderr, L"Invalid parameter detected in function %s.\n"
352*e1c63fd9SArrigo Marchiori              L"File: %s\n"
353*e1c63fd9SArrigo Marchiori              L"Line: %u\n"
354*e1c63fd9SArrigo Marchiori              L"Expression: %s\n"
355*e1c63fd9SArrigo Marchiori              L"pReserved: %p\n", function, file, line, expression, pReserved);
356*e1c63fd9SArrigo Marchiori 
357*e1c63fd9SArrigo Marchiori     Info.Signal = osl_Signal_AccessViolation;
358*e1c63fd9SArrigo Marchiori     Info.UserSignal = 0;
359*e1c63fd9SArrigo Marchiori     Info.UserData = NULL;
360*e1c63fd9SArrigo Marchiori     if ( ReportCrash( NULL ) || IsWin95A() )
361*e1c63fd9SArrigo Marchiori     {
362*e1c63fd9SArrigo Marchiori         CallSignalHandler(&Info);
363*e1c63fd9SArrigo Marchiori         abort(); // Equivalent of osl_Signal_ActAbortApp
364*e1c63fd9SArrigo Marchiori     } else {
365*e1c63fd9SArrigo Marchiori         // Equivalent of osl_Signal_ActKillApp
366*e1c63fd9SArrigo Marchiori         SetErrorMode(SEM_NOGPFAULTERRORBOX);
367*e1c63fd9SArrigo Marchiori         exit(255);
368*e1c63fd9SArrigo Marchiori     }
369*e1c63fd9SArrigo Marchiori     // We will never reach this point
370*e1c63fd9SArrigo Marchiori }
371*e1c63fd9SArrigo Marchiori 
372cdf0e10cSrcweir /*****************************************************************************/
373cdf0e10cSrcweir /* osl_addSignalHandler */
374cdf0e10cSrcweir /*****************************************************************************/
osl_addSignalHandler(oslSignalHandlerFunction Handler,void * pData)375cdf0e10cSrcweir oslSignalHandler SAL_CALL osl_addSignalHandler(oslSignalHandlerFunction Handler, void* pData)
376cdf0e10cSrcweir {
377cdf0e10cSrcweir     oslSignalHandlerImpl* pHandler;
378cdf0e10cSrcweir 
379cdf0e10cSrcweir     OSL_ASSERT(Handler != NULL);
380cdf0e10cSrcweir 
381cdf0e10cSrcweir     if (! bInitSignal)
382cdf0e10cSrcweir         bInitSignal = InitSignal();
383cdf0e10cSrcweir 
384cdf0e10cSrcweir     pHandler = reinterpret_cast< oslSignalHandlerImpl* >( calloc( 1, sizeof(oslSignalHandlerImpl) ) );
385cdf0e10cSrcweir 
386cdf0e10cSrcweir     if (pHandler != NULL)
387cdf0e10cSrcweir     {
388cdf0e10cSrcweir         pHandler->Handler = Handler;
389cdf0e10cSrcweir         pHandler->pData   = pData;
390cdf0e10cSrcweir 
391cdf0e10cSrcweir         osl_acquireMutex(SignalListMutex);
392cdf0e10cSrcweir 
393cdf0e10cSrcweir         pHandler->pNext = SignalList;
394cdf0e10cSrcweir         SignalList      = pHandler;
395cdf0e10cSrcweir 
396cdf0e10cSrcweir         osl_releaseMutex(SignalListMutex);
397cdf0e10cSrcweir 
398cdf0e10cSrcweir         return (pHandler);
399cdf0e10cSrcweir     }
400cdf0e10cSrcweir 
401cdf0e10cSrcweir     return (NULL);
402cdf0e10cSrcweir }
403cdf0e10cSrcweir 
404cdf0e10cSrcweir /*****************************************************************************/
405cdf0e10cSrcweir /* osl_removeSignalHandler */
406cdf0e10cSrcweir /*****************************************************************************/
osl_removeSignalHandler(oslSignalHandler Handler)407cdf0e10cSrcweir sal_Bool SAL_CALL osl_removeSignalHandler(oslSignalHandler Handler)
408cdf0e10cSrcweir {
409cdf0e10cSrcweir     oslSignalHandlerImpl *pHandler, *pPrevious = NULL;
410cdf0e10cSrcweir 
411cdf0e10cSrcweir     OSL_ASSERT(Handler != NULL);
412cdf0e10cSrcweir 
413cdf0e10cSrcweir     if (! bInitSignal)
414cdf0e10cSrcweir         bInitSignal = InitSignal();
415cdf0e10cSrcweir 
416cdf0e10cSrcweir     osl_acquireMutex(SignalListMutex);
417cdf0e10cSrcweir 
418cdf0e10cSrcweir     pHandler = SignalList;
419cdf0e10cSrcweir 
420cdf0e10cSrcweir     while (pHandler != NULL)
421cdf0e10cSrcweir     {
422cdf0e10cSrcweir         if (pHandler == Handler)
423cdf0e10cSrcweir         {
424cdf0e10cSrcweir             if (pPrevious)
425cdf0e10cSrcweir                 pPrevious->pNext = pHandler->pNext;
426cdf0e10cSrcweir             else
427cdf0e10cSrcweir                 SignalList = pHandler->pNext;
428cdf0e10cSrcweir 
429cdf0e10cSrcweir             osl_releaseMutex(SignalListMutex);
430cdf0e10cSrcweir 
431cdf0e10cSrcweir             if (SignalList == NULL)
432cdf0e10cSrcweir                 bInitSignal = DeInitSignal();
433cdf0e10cSrcweir 
434cdf0e10cSrcweir             free(pHandler);
435cdf0e10cSrcweir 
436cdf0e10cSrcweir             return (sal_True);
437cdf0e10cSrcweir         }
438cdf0e10cSrcweir 
439cdf0e10cSrcweir         pPrevious = pHandler;
440cdf0e10cSrcweir         pHandler  = pHandler->pNext;
441cdf0e10cSrcweir     }
442cdf0e10cSrcweir 
443cdf0e10cSrcweir     osl_releaseMutex(SignalListMutex);
444cdf0e10cSrcweir 
445cdf0e10cSrcweir     return (sal_False);
446cdf0e10cSrcweir }
447cdf0e10cSrcweir 
448cdf0e10cSrcweir /*****************************************************************************/
449cdf0e10cSrcweir /* osl_raiseSignal */
450cdf0e10cSrcweir /*****************************************************************************/
osl_raiseSignal(sal_Int32 UserSignal,void * UserData)451cdf0e10cSrcweir oslSignalAction SAL_CALL osl_raiseSignal(sal_Int32 UserSignal, void* UserData)
452cdf0e10cSrcweir {
453cdf0e10cSrcweir     oslSignalInfo   Info;
454cdf0e10cSrcweir     oslSignalAction Action;
455cdf0e10cSrcweir 
456cdf0e10cSrcweir     if (! bInitSignal)
457cdf0e10cSrcweir         bInitSignal = InitSignal();
458cdf0e10cSrcweir 
459cdf0e10cSrcweir     osl_acquireMutex(SignalListMutex);
460cdf0e10cSrcweir 
461cdf0e10cSrcweir     Info.Signal     = osl_Signal_User;
462cdf0e10cSrcweir     Info.UserSignal = UserSignal;
463cdf0e10cSrcweir     Info.UserData   = UserData;
464cdf0e10cSrcweir 
465cdf0e10cSrcweir     Action = CallSignalHandler(&Info);
466cdf0e10cSrcweir 
467cdf0e10cSrcweir     osl_releaseMutex(SignalListMutex);
468cdf0e10cSrcweir 
469cdf0e10cSrcweir     return (Action);
470cdf0e10cSrcweir }
471cdf0e10cSrcweir 
472cdf0e10cSrcweir /*****************************************************************************/
473cdf0e10cSrcweir /* osl_setErrorReporting */
474cdf0e10cSrcweir /*****************************************************************************/
475747164b0SHerbert Dürr 
win_seh_translator(unsigned nSEHCode,_EXCEPTION_POINTERS * pExcPtrs)476747164b0SHerbert Dürr void win_seh_translator( unsigned nSEHCode, _EXCEPTION_POINTERS* pExcPtrs)
477747164b0SHerbert Dürr {
4783752b850SHerbert Dürr     (void*)pExcPtrs; // currently unused, but useful inside a debugger
479747164b0SHerbert Dürr     const char* pSEHName = NULL;
4800b7f0425SHerbert Dürr     switch( nSEHCode)
4810b7f0425SHerbert Dürr     {
482747164b0SHerbert Dürr         case EXCEPTION_ACCESS_VIOLATION:         pSEHName = "SEH Exception: ACCESS VIOLATION"; break;
483747164b0SHerbert Dürr         case EXCEPTION_DATATYPE_MISALIGNMENT:    pSEHName = "SEH Exception: DATATYPE MISALIGNMENT"; break;
4840b7f0425SHerbert Dürr         case EXCEPTION_BREAKPOINT:               /*pSEHName = "SEH Exception: BREAKPOINT";*/ break;
4850b7f0425SHerbert Dürr         case EXCEPTION_SINGLE_STEP:              /*pSEHName = "SEH Exception: SINGLE STEP";*/ break;
486747164b0SHerbert Dürr         case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:    pSEHName = "SEH Exception: ARRAY BOUNDS EXCEEDED"; break;
487747164b0SHerbert Dürr         case EXCEPTION_FLT_DENORMAL_OPERAND:     pSEHName = "SEH Exception: DENORMAL FLOAT OPERAND"; break;
488747164b0SHerbert Dürr         case EXCEPTION_FLT_DIVIDE_BY_ZERO:       pSEHName = "SEH Exception: FLOAT DIVIDE_BY_ZERO"; break;
489747164b0SHerbert Dürr         case EXCEPTION_FLT_INEXACT_RESULT:       pSEHName = "SEH Exception: FLOAT INEXACT RESULT"; break;
490747164b0SHerbert Dürr         case EXCEPTION_FLT_INVALID_OPERATION:    pSEHName = "SEH Exception: INVALID FLOAT OPERATION"; break;
491747164b0SHerbert Dürr         case EXCEPTION_FLT_OVERFLOW:             pSEHName = "SEH Exception: FLOAT OVERFLOW"; break;
492747164b0SHerbert Dürr         case EXCEPTION_FLT_STACK_CHECK:          pSEHName = "SEH Exception: FLOAT STACK_CHECK"; break;
493747164b0SHerbert Dürr         case EXCEPTION_FLT_UNDERFLOW:            pSEHName = "SEH Exception: FLOAT UNDERFLOW"; break;
494747164b0SHerbert Dürr         case EXCEPTION_INT_DIVIDE_BY_ZERO:       pSEHName = "SEH Exception: INTEGER DIVIDE_BY_ZERO"; break;
495747164b0SHerbert Dürr         case EXCEPTION_INT_OVERFLOW:             pSEHName = "SEH Exception: INTEGER OVERFLOW"; break;
496747164b0SHerbert Dürr         case EXCEPTION_PRIV_INSTRUCTION:         pSEHName = "SEH Exception: PRIVILEDGED INSTRUCTION"; break;
497747164b0SHerbert Dürr         case EXCEPTION_IN_PAGE_ERROR:            pSEHName = "SEH Exception: IN_PAGE_ERROR"; break;
498747164b0SHerbert Dürr         case EXCEPTION_ILLEGAL_INSTRUCTION:      pSEHName = "SEH Exception: ILLEGAL INSTRUCTION"; break;
499747164b0SHerbert Dürr         case EXCEPTION_NONCONTINUABLE_EXCEPTION: pSEHName = "SEH Exception: NONCONTINUABLE EXCEPTION"; break;
500747164b0SHerbert Dürr         case EXCEPTION_STACK_OVERFLOW:           pSEHName = "SEH Exception: STACK OVERFLOW"; break;
501747164b0SHerbert Dürr         case EXCEPTION_INVALID_DISPOSITION:      pSEHName = "SEH Exception: INVALID DISPOSITION"; break;
502747164b0SHerbert Dürr         case EXCEPTION_GUARD_PAGE:               pSEHName = "SEH Exception: GUARD PAGE"; break;
503747164b0SHerbert Dürr         case EXCEPTION_INVALID_HANDLE:           pSEHName = "SEH Exception: INVALID HANDLE"; break;
504747164b0SHerbert Dürr //      case EXCEPTION_POSSIBLE_DEADLOCK:        pSEHName = "SEH Exception: POSSIBLE DEADLOCK"; break;
505747164b0SHerbert Dürr         default:                                 pSEHName = "Unknown SEH Exception"; break;
506747164b0SHerbert Dürr     }
5070b7f0425SHerbert Dürr 
5080b7f0425SHerbert Dürr     if( pSEHName)
509747164b0SHerbert Dürr         throw std::runtime_error( pSEHName);
510747164b0SHerbert Dürr }
511747164b0SHerbert Dürr 
osl_setErrorReporting(sal_Bool bEnable)512cdf0e10cSrcweir sal_Bool SAL_CALL osl_setErrorReporting( sal_Bool bEnable )
513cdf0e10cSrcweir {
514cdf0e10cSrcweir     sal_Bool bOld = bErrorReportingEnabled;
515cdf0e10cSrcweir     bErrorReportingEnabled = bEnable;
516cdf0e10cSrcweir 
517747164b0SHerbert Dürr     if( !bEnable) // if the crash reporter is disabled
518747164b0SHerbert Dürr     {
519747164b0SHerbert Dürr         // fall back to handle Window's SEH events as C++ exceptions
520747164b0SHerbert Dürr         _set_se_translator( win_seh_translator);
521747164b0SHerbert Dürr     }
522747164b0SHerbert Dürr 
523cdf0e10cSrcweir     return bOld;
524cdf0e10cSrcweir }
525