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