msvcrt: Partially implement _set_abort_behavior.
This commit is contained in:
parent
103ef913d1
commit
03ca06e791
|
@ -1068,7 +1068,7 @@
|
||||||
@ stub _seh_longjmp_unwind4
|
@ stub _seh_longjmp_unwind4
|
||||||
@ stdcall -i386 _seh_longjmp_unwind(ptr) msvcrt._seh_longjmp_unwind
|
@ stdcall -i386 _seh_longjmp_unwind(ptr) msvcrt._seh_longjmp_unwind
|
||||||
@ cdecl _set_SSE2_enable(long) msvcrt._set_SSE2_enable
|
@ cdecl _set_SSE2_enable(long) msvcrt._set_SSE2_enable
|
||||||
@ stub _set_abort_behavior
|
@ cdecl _set_abort_behavior(long long) msvcrt._set_abort_behavior
|
||||||
@ stub _set_controlfp
|
@ stub _set_controlfp
|
||||||
@ cdecl _set_doserrno(long) msvcrt._set_doserrno
|
@ cdecl _set_doserrno(long) msvcrt._set_doserrno
|
||||||
@ cdecl _set_errno(long) msvcrt._set_errno
|
@ cdecl _set_errno(long) msvcrt._set_errno
|
||||||
|
|
|
@ -920,7 +920,7 @@
|
||||||
@ stub _seh_longjmp_unwind4
|
@ stub _seh_longjmp_unwind4
|
||||||
@ stdcall -i386 _seh_longjmp_unwind(ptr) msvcrt._seh_longjmp_unwind
|
@ stdcall -i386 _seh_longjmp_unwind(ptr) msvcrt._seh_longjmp_unwind
|
||||||
@ cdecl _set_SSE2_enable(long) msvcrt._set_SSE2_enable
|
@ cdecl _set_SSE2_enable(long) msvcrt._set_SSE2_enable
|
||||||
@ stub _set_abort_behavior
|
@ cdecl _set_abort_behavior(long long) msvcrt._set_abort_behavior
|
||||||
@ stub _set_amblksiz
|
@ stub _set_amblksiz
|
||||||
@ stub _set_controlfp
|
@ stub _set_controlfp
|
||||||
@ cdecl _set_doserrno(long) msvcrt._set_doserrno
|
@ cdecl _set_doserrno(long) msvcrt._set_doserrno
|
||||||
|
|
|
@ -906,7 +906,7 @@
|
||||||
@ stub _seh_longjmp_unwind4
|
@ stub _seh_longjmp_unwind4
|
||||||
@ stdcall -i386 _seh_longjmp_unwind(ptr) msvcrt._seh_longjmp_unwind
|
@ stdcall -i386 _seh_longjmp_unwind(ptr) msvcrt._seh_longjmp_unwind
|
||||||
@ cdecl _set_SSE2_enable(long) msvcrt._set_SSE2_enable
|
@ cdecl _set_SSE2_enable(long) msvcrt._set_SSE2_enable
|
||||||
@ stub _set_abort_behavior
|
@ cdecl _set_abort_behavior(long long) msvcrt._set_abort_behavior
|
||||||
@ stub _set_amblksiz
|
@ stub _set_amblksiz
|
||||||
@ stub _set_controlfp
|
@ stub _set_controlfp
|
||||||
@ cdecl _set_doserrno(long) msvcrt._set_doserrno
|
@ cdecl _set_doserrno(long) msvcrt._set_doserrno
|
||||||
|
|
|
@ -69,6 +69,7 @@ static int (__cdecl *p_wcsncat_s)(wchar_t *dst, size_t elem, const wchar_t *src,
|
||||||
static void (__cdecl *p_qsort_s)(void *, size_t, size_t, int (__cdecl *)(void *, const void *, const void *), void *);
|
static void (__cdecl *p_qsort_s)(void *, size_t, size_t, int (__cdecl *)(void *, const void *, const void *), void *);
|
||||||
static int (__cdecl *p_controlfp_s)(unsigned int *, unsigned int, unsigned int);
|
static int (__cdecl *p_controlfp_s)(unsigned int *, unsigned int, unsigned int);
|
||||||
static int (__cdecl *p_atoflt)(_CRT_FLOAT *, char *);
|
static int (__cdecl *p_atoflt)(_CRT_FLOAT *, char *);
|
||||||
|
static unsigned int (__cdecl *p_set_abort_behavior)(unsigned int, unsigned int);
|
||||||
|
|
||||||
static void* (WINAPI *pEncodePointer)(void *);
|
static void* (WINAPI *pEncodePointer)(void *);
|
||||||
|
|
||||||
|
@ -680,6 +681,30 @@ if (0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test__set_abort_behavior(void)
|
||||||
|
{
|
||||||
|
unsigned int res;
|
||||||
|
|
||||||
|
if (!p_set_abort_behavior)
|
||||||
|
{
|
||||||
|
win_skip("_set_abort_behavior not found\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* default is _WRITE_ABORT_MSG | _CALL_REPORTFAULT */
|
||||||
|
res = p_set_abort_behavior(0, 0);
|
||||||
|
ok (res == (_WRITE_ABORT_MSG | _CALL_REPORTFAULT),
|
||||||
|
"got 0x%x (expected 0x%x)\n", res, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
|
||||||
|
|
||||||
|
/* no internal mask */
|
||||||
|
p_set_abort_behavior(0xffffffff, 0xffffffff);
|
||||||
|
res = p_set_abort_behavior(0, 0);
|
||||||
|
ok (res == 0xffffffff, "got 0x%x (expected 0x%x)\n", res, 0xffffffff);
|
||||||
|
|
||||||
|
/* set to default value */
|
||||||
|
p_set_abort_behavior(_WRITE_ABORT_MSG | _CALL_REPORTFAULT, 0xffffffff);
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(msvcr90)
|
START_TEST(msvcr90)
|
||||||
{
|
{
|
||||||
HMODULE hcrt;
|
HMODULE hcrt;
|
||||||
|
@ -712,6 +737,7 @@ START_TEST(msvcr90)
|
||||||
p_qsort_s = (void *) GetProcAddress(hcrt, "qsort_s");
|
p_qsort_s = (void *) GetProcAddress(hcrt, "qsort_s");
|
||||||
p_controlfp_s = (void *) GetProcAddress(hcrt, "_controlfp_s");
|
p_controlfp_s = (void *) GetProcAddress(hcrt, "_controlfp_s");
|
||||||
p_atoflt = (void* )GetProcAddress(hcrt, "_atoflt");
|
p_atoflt = (void* )GetProcAddress(hcrt, "_atoflt");
|
||||||
|
p_set_abort_behavior = (void *) GetProcAddress(hcrt, "_set_abort_behavior");
|
||||||
|
|
||||||
hkernel32 = GetModuleHandleA("kernel32.dll");
|
hkernel32 = GetModuleHandleA("kernel32.dll");
|
||||||
pEncodePointer = (void *) GetProcAddress(hkernel32, "EncodePointer");
|
pEncodePointer = (void *) GetProcAddress(hkernel32, "EncodePointer");
|
||||||
|
@ -725,4 +751,5 @@ START_TEST(msvcr90)
|
||||||
test_qsort_s();
|
test_qsort_s();
|
||||||
test_controlfp_s();
|
test_controlfp_s();
|
||||||
test__atoflt();
|
test__atoflt();
|
||||||
|
test__set_abort_behavior();
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,8 @@ static const char szMsgBoxTitle[] = "Wine C++ Runtime Library";
|
||||||
extern int MSVCRT_app_type;
|
extern int MSVCRT_app_type;
|
||||||
extern char *MSVCRT__pgmptr;
|
extern char *MSVCRT__pgmptr;
|
||||||
|
|
||||||
|
static unsigned int MSVCRT_abort_behavior = MSVCRT__WRITE_ABORT_MSG | MSVCRT__CALL_REPORTFAULT;
|
||||||
|
|
||||||
void (*CDECL _aexit_rtn)(int) = MSVCRT__exit;
|
void (*CDECL _aexit_rtn)(int) = MSVCRT__exit;
|
||||||
|
|
||||||
/* INTERNAL: call atexit functions */
|
/* INTERNAL: call atexit functions */
|
||||||
|
@ -150,17 +152,38 @@ void CDECL _amsg_exit(int errnum)
|
||||||
void CDECL MSVCRT_abort(void)
|
void CDECL MSVCRT_abort(void)
|
||||||
{
|
{
|
||||||
TRACE("()\n");
|
TRACE("()\n");
|
||||||
if (MSVCRT_app_type == 2)
|
|
||||||
|
if (MSVCRT_abort_behavior & MSVCRT__WRITE_ABORT_MSG)
|
||||||
{
|
{
|
||||||
DoMessageBox("Runtime error!", "abnormal program termination");
|
if (MSVCRT_app_type == 2)
|
||||||
|
{
|
||||||
|
DoMessageBox("Runtime error!", "abnormal program termination");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_cputs("\nabnormal program termination\n");
|
||||||
}
|
}
|
||||||
else
|
|
||||||
_cputs("\nabnormal program termination\n");
|
|
||||||
MSVCRT_raise(MSVCRT_SIGABRT);
|
MSVCRT_raise(MSVCRT_SIGABRT);
|
||||||
/* in case raise() returns */
|
/* in case raise() returns */
|
||||||
MSVCRT__exit(3);
|
MSVCRT__exit(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* _set_abort_behavior (MSVCRT.@)
|
||||||
|
*
|
||||||
|
* Not exported by native msvcrt, added in msvcr80
|
||||||
|
*/
|
||||||
|
unsigned int CDECL MSVCRT__set_abort_behavior(unsigned int flags, unsigned int mask)
|
||||||
|
{
|
||||||
|
unsigned int old = MSVCRT_abort_behavior;
|
||||||
|
|
||||||
|
TRACE("%x, %x\n", flags, mask);
|
||||||
|
if (mask & MSVCRT__CALL_REPORTFAULT)
|
||||||
|
FIXME("_WRITE_CALL_REPORTFAULT unhandled\n");
|
||||||
|
|
||||||
|
MSVCRT_abort_behavior = (MSVCRT_abort_behavior & ~mask) | (flags & mask);
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* _assert (MSVCRT.@)
|
* _assert (MSVCRT.@)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -732,6 +732,10 @@ typedef void (__cdecl *MSVCRT___sighandler_t)(int);
|
||||||
|
|
||||||
#define _MAX__TIME64_T (((MSVCRT___time64_t)0x00000007 << 32) | 0x93406FFF)
|
#define _MAX__TIME64_T (((MSVCRT___time64_t)0x00000007 << 32) | 0x93406FFF)
|
||||||
|
|
||||||
|
/* _set_abort_behavior codes */
|
||||||
|
#define MSVCRT__WRITE_ABORT_MSG 1
|
||||||
|
#define MSVCRT__CALL_REPORTFAULT 2
|
||||||
|
|
||||||
void __cdecl MSVCRT_free(void*);
|
void __cdecl MSVCRT_free(void*);
|
||||||
void* __cdecl MSVCRT_malloc(MSVCRT_size_t);
|
void* __cdecl MSVCRT_malloc(MSVCRT_size_t);
|
||||||
void* __cdecl MSVCRT_calloc(MSVCRT_size_t,MSVCRT_size_t);
|
void* __cdecl MSVCRT_calloc(MSVCRT_size_t,MSVCRT_size_t);
|
||||||
|
|
|
@ -1475,6 +1475,7 @@
|
||||||
@ varargs wscanf_s(wstr) MSVCRT_wscanf_s
|
@ varargs wscanf_s(wstr) MSVCRT_wscanf_s
|
||||||
|
|
||||||
# Functions not exported in native dll:
|
# Functions not exported in native dll:
|
||||||
|
@ cdecl _set_abort_behavior(long long) MSVCRT__set_abort_behavior
|
||||||
@ cdecl _get_invalid_parameter_handler()
|
@ cdecl _get_invalid_parameter_handler()
|
||||||
@ cdecl _set_invalid_parameter_handler(ptr)
|
@ cdecl _set_invalid_parameter_handler(ptr)
|
||||||
@ cdecl _create_locale(long str) MSVCRT__create_locale
|
@ cdecl _create_locale(long str) MSVCRT__create_locale
|
||||||
|
|
|
@ -453,6 +453,8 @@ static void test_defines(void)
|
||||||
CHECK_DEF(_EM_AMBIGUOUS);
|
CHECK_DEF(_EM_AMBIGUOUS);
|
||||||
CHECK_DEF(_OVERFLOW);
|
CHECK_DEF(_OVERFLOW);
|
||||||
CHECK_DEF(_UNDERFLOW);
|
CHECK_DEF(_UNDERFLOW);
|
||||||
|
CHECK_DEF(_WRITE_ABORT_MSG);
|
||||||
|
CHECK_DEF(_CALL_REPORTFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* __WINE_USE_MSVCRT */
|
#endif /* __WINE_USE_MSVCRT */
|
||||||
|
|
|
@ -73,6 +73,9 @@ typedef struct _ldiv_t {
|
||||||
#define _OUT_TO_MSGBOX 2
|
#define _OUT_TO_MSGBOX 2
|
||||||
#define _REPORT_ERRMODE 3
|
#define _REPORT_ERRMODE 3
|
||||||
|
|
||||||
|
/* _set_abort_behavior codes */
|
||||||
|
#define _WRITE_ABORT_MSG 1
|
||||||
|
#define _CALL_REPORTFAULT 2
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
Loading…
Reference in New Issue