[PATCH 2/2] Partially implement _set_abort_behavior

Nikolay Sivov nsivov at codeweavers.com
Wed Jan 19 16:21:11 CST 2011


---
 dlls/msvcr100/msvcr100.spec  |    2 +-
 dlls/msvcr80/msvcr80.spec    |    2 +-
 dlls/msvcr90/msvcr90.spec    |    2 +-
 dlls/msvcr90/tests/msvcr90.c |   27 +++++++++++++++++++++++++++
 dlls/msvcrt/exit.c           |   31 +++++++++++++++++++++++++++----
 dlls/msvcrt/msvcrt.h         |    4 ++++
 dlls/msvcrt/msvcrt.spec      |    1 +
 dlls/msvcrt/tests/headers.c  |    2 ++
 include/msvcrt/stdlib.h      |    3 +++
 9 files changed, 67 insertions(+), 7 deletions(-)

diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec
index a07400e..c103916 100644
--- a/dlls/msvcr100/msvcr100.spec
+++ b/dlls/msvcr100/msvcr100.spec
@@ -1068,7 +1068,7 @@
 @ stub _seh_longjmp_unwind4
 @ stdcall -i386 _seh_longjmp_unwind(ptr) msvcrt._seh_longjmp_unwind
 @ 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
 @ cdecl _set_doserrno(long) msvcrt._set_doserrno
 @ cdecl _set_errno(long) msvcrt._set_errno
diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec
index f983944..4879e13 100644
--- a/dlls/msvcr80/msvcr80.spec
+++ b/dlls/msvcr80/msvcr80.spec
@@ -920,7 +920,7 @@
 @ stub _seh_longjmp_unwind4
 @ stdcall -i386 _seh_longjmp_unwind(ptr) msvcrt._seh_longjmp_unwind
 @ 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_controlfp
 @ cdecl _set_doserrno(long) msvcrt._set_doserrno
diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec
index fb9073d..aa0f981 100644
--- a/dlls/msvcr90/msvcr90.spec
+++ b/dlls/msvcr90/msvcr90.spec
@@ -906,7 +906,7 @@
 @ stub _seh_longjmp_unwind4
 @ stdcall -i386 _seh_longjmp_unwind(ptr) msvcrt._seh_longjmp_unwind
 @ 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_controlfp
 @ cdecl _set_doserrno(long) msvcrt._set_doserrno
diff --git a/dlls/msvcr90/tests/msvcr90.c b/dlls/msvcr90/tests/msvcr90.c
index 40caa05..dcf893d 100644
--- a/dlls/msvcr90/tests/msvcr90.c
+++ b/dlls/msvcr90/tests/msvcr90.c
@@ -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 int (__cdecl *p_controlfp_s)(unsigned int *, unsigned int, unsigned int);
 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 *);
 
@@ -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)
 {
     HMODULE hcrt;
@@ -712,6 +737,7 @@ START_TEST(msvcr90)
     p_qsort_s = (void *) GetProcAddress(hcrt, "qsort_s");
     p_controlfp_s = (void *) GetProcAddress(hcrt, "_controlfp_s");
     p_atoflt = (void* )GetProcAddress(hcrt, "_atoflt");
+    p_set_abort_behavior = (void *) GetProcAddress(hcrt, "_set_abort_behavior");
 
     hkernel32 = GetModuleHandleA("kernel32.dll");
     pEncodePointer = (void *) GetProcAddress(hkernel32, "EncodePointer");
@@ -725,4 +751,5 @@ START_TEST(msvcr90)
     test_qsort_s();
     test_controlfp_s();
     test__atoflt();
+    test__set_abort_behavior();
 }
diff --git a/dlls/msvcrt/exit.c b/dlls/msvcrt/exit.c
index 80749fc..ac7e9b3 100644
--- a/dlls/msvcrt/exit.c
+++ b/dlls/msvcrt/exit.c
@@ -39,6 +39,8 @@ static const char szMsgBoxTitle[] = "Wine C++ Runtime Library";
 extern int MSVCRT_app_type;
 extern char *MSVCRT__pgmptr;
 
+static unsigned int MSVCRT_abort_behavior =  MSVCRT__WRITE_ABORT_MSG | MSVCRT__CALL_REPORTFAULT;
+
 void (*CDECL _aexit_rtn)(int) = MSVCRT__exit;
 
 /* INTERNAL: call atexit functions */
@@ -150,18 +152,39 @@ void CDECL _amsg_exit(int errnum)
 void CDECL MSVCRT_abort(void)
 {
   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);
   /* in case raise() returns */
   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.@)
  */
 void CDECL MSVCRT__assert(const char* str, const char* file, unsigned int line)
diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h
index 9e29d31..d2292e4 100644
--- a/dlls/msvcrt/msvcrt.h
+++ b/dlls/msvcrt/msvcrt.h
@@ -732,6 +732,10 @@ typedef void (__cdecl *MSVCRT___sighandler_t)(int);
 
 #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_malloc(MSVCRT_size_t);
 void* __cdecl    MSVCRT_calloc(MSVCRT_size_t,MSVCRT_size_t);
diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec
index a6160a4..53c0126 100644
--- a/dlls/msvcrt/msvcrt.spec
+++ b/dlls/msvcrt/msvcrt.spec
@@ -850,6 +850,7 @@
 @ cdecl _searchenv_s(str str ptr long)
 # stub _seh_longjmp_unwind4
 @ stdcall -i386 _seh_longjmp_unwind(ptr)
+@ cdecl _set_abort_behavior(long long) MSVCRT__set_abort_behavior
 @ cdecl _set_SSE2_enable(long) MSVCRT__set_SSE2_enable
 # stub _set_controlfp
 @ cdecl _set_doserrno(long)
diff --git a/dlls/msvcrt/tests/headers.c b/dlls/msvcrt/tests/headers.c
index 829fe47..f02b61f 100644
--- a/dlls/msvcrt/tests/headers.c
+++ b/dlls/msvcrt/tests/headers.c
@@ -453,6 +453,8 @@ static void test_defines(void)
     CHECK_DEF(_EM_AMBIGUOUS);
     CHECK_DEF(_OVERFLOW);
     CHECK_DEF(_UNDERFLOW);
+    CHECK_DEF(_WRITE_ABORT_MSG);
+    CHECK_DEF(_CALL_REPORTFAULT);
 }
 
 #endif /* __WINE_USE_MSVCRT */
diff --git a/include/msvcrt/stdlib.h b/include/msvcrt/stdlib.h
index d30e483..6a6398d 100644
--- a/include/msvcrt/stdlib.h
+++ b/include/msvcrt/stdlib.h
@@ -73,6 +73,9 @@ typedef struct _ldiv_t {
 #define _OUT_TO_MSGBOX       2
 #define _REPORT_ERRMODE      3
 
+/* _set_abort_behavior codes */
+#define _WRITE_ABORT_MSG     1
+#define _CALL_REPORTFAULT    2
 
 #ifdef __cplusplus
 extern "C" {
-- 
1.5.6.5


--------------070600050104040304030700--



More information about the wine-patches mailing list