Author: tkreuzer Date: Tue Jan 8 22:14:10 2013 New Revision: 58143
URL: http://svn.reactos.org/svn/reactos?rev=58143&view=rev Log: [CRT] - Use __debugbreak in _assert when user presses ignore in the message box - Implement __crt_MessageBoxA and use it from _assert and abort - Rewrite abort and _set_abort_behavior - Add function headers and set BSD license for my code - CORE-6594 #resolve
Added: trunk/reactos/lib/sdk/crt/include/internal/misc.h (with props) trunk/reactos/lib/sdk/crt/misc/__crt_MessageBoxA.c (with props) trunk/reactos/lib/sdk/crt/stdlib/_set_abort_behavior.c (with props) Modified: trunk/reactos/lib/sdk/crt/crt.cmake trunk/reactos/lib/sdk/crt/misc/assert.c trunk/reactos/lib/sdk/crt/precomp.h trunk/reactos/lib/sdk/crt/stdlib/abort.c
Modified: trunk/reactos/lib/sdk/crt/crt.cmake URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/crt.cmake?rev=5... ============================================================================== --- trunk/reactos/lib/sdk/crt/crt.cmake [iso-8859-1] (original) +++ trunk/reactos/lib/sdk/crt/crt.cmake [iso-8859-1] Tue Jan 8 22:14:10 2013 @@ -120,6 +120,7 @@ mem/memcmp.c mem/memccpy.c mem/memicmp.c + misc/__crt_MessageBoxA.c misc/amsg.c misc/assert.c misc/environ.c @@ -224,6 +225,7 @@ stdio/wstat.c stdio/wstat64.c stdlib/_exit.c + stdlib/_set_abort_behavior.c stdlib/abort.c stdlib/atexit.c stdlib/ecvt.c
Added: trunk/reactos/lib/sdk/crt/include/internal/misc.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/include/interna... ============================================================================== --- trunk/reactos/lib/sdk/crt/include/internal/misc.h (added) +++ trunk/reactos/lib/sdk/crt/include/internal/misc.h [iso-8859-1] Tue Jan 8 22:14:10 2013 @@ -1,0 +1,14 @@ + + +extern int msvcrt_error_mode; +extern int __app_type; +#define _UNKNOWN_APP 0 +#define _CONSOLE_APP 1 +#define _GUI_APP 2 + +int +__cdecl +__crt_MessageBoxA ( + _In_opt_ const char *pszText, + _In_ unsigned int uType); +
Propchange: trunk/reactos/lib/sdk/crt/include/internal/misc.h ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/reactos/lib/sdk/crt/misc/__crt_MessageBoxA.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/misc/__crt_Mess... ============================================================================== --- trunk/reactos/lib/sdk/crt/misc/__crt_MessageBoxA.c (added) +++ trunk/reactos/lib/sdk/crt/misc/__crt_MessageBoxA.c [iso-8859-1] Tue Jan 8 22:14:10 2013 @@ -1,0 +1,47 @@ +/* + * PROJECT: ReactOS C runtime library + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: lib/sdk/crt/__crt_MessageBoxA.c + * PURPOSE: __crt_MessageBoxA implementation + * PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org) + */ + +#include <precomp.h> + +/***************************************************************************** + * \brief Displays a message box. + * + * \param pszText - The message to be displayed. + * \param uType - The contents and behavior of the message box. + * \return Identifies the button that was pressed by the user. + * \see MessageBox + * + *****************************************************************************/ +int +__cdecl +__crt_MessageBoxA ( + _In_opt_ const char *pszText, + _In_ unsigned int uType) +{ + HMODULE hmodUser32; + int (WINAPI *pMessageBoxA)(HWND, LPCTSTR, LPCTSTR, UINT); + int iResult; + + /* Get MessageBoxA function pointer */ + hmodUser32 = LoadLibrary("user32.dll"); + pMessageBoxA = (PVOID)GetProcAddress(hmodUser32, "MessageBoxA"); + if (!pMessageBoxA) + { + abort(); + } + + /* Display a message box */ + iResult = pMessageBoxA(NULL, + pszText, + "ReactOS C Runtime Library", + uType); + + FreeLibrary(hmodUser32); + return iResult; +} +
Propchange: trunk/reactos/lib/sdk/crt/misc/__crt_MessageBoxA.c ------------------------------------------------------------------------------ svn:eol-style = native
Modified: trunk/reactos/lib/sdk/crt/misc/assert.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/misc/assert.c?r... ============================================================================== --- trunk/reactos/lib/sdk/crt/misc/assert.c [iso-8859-1] (original) +++ trunk/reactos/lib/sdk/crt/misc/assert.c [iso-8859-1] Tue Jan 8 22:14:10 2013 @@ -1,9 +1,12 @@ -/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ +/* + * PROJECT: ReactOS C runtime library + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: lib/sdk/crt/assert.c + * PURPOSE: _assert implementation + * PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org) + */ + #include <precomp.h> -#include <assert.h> -#include <stdio.h> -#include <stdlib.h> -#include <signal.h>
static const char formatstr[] = "Assertion failed!\n\n" @@ -11,35 +14,33 @@ "File: %s\n" "Line: %ld\n\n" "Expression: %s\n" - "Press Retry to debug the application\n"; + "Press Retry to debug the application\n\0";
- -/* - * @implemented - */ -void _assert(const char *exp, const char *file, unsigned line) +void +_assert ( + const char *exp, + const char *file, + unsigned line) { - int (WINAPI *pMessageBoxA)(HWND, LPCTSTR, LPCTSTR, UINT); - HMODULE hmodUser32; - char achProgram[40]; + char achProgram[MAX_PATH]; char *pszBuffer; size_t len; int iResult;
- /* Assertion failed at foo.c line 45: x<y */ - fprintf(stderr, "Assertion failed at %s line %d: %s\n", file, line, exp); - FIXME("Assertion failed at %s line %d: %s\n", file, line, exp); + /* First common debug message */ + FIXME("Assertion failed: %s, file %s, line %d\n", exp, file, line);
- /* Get MessageBoxA function pointer */ - hmodUser32 = LoadLibrary("user32.dll"); - pMessageBoxA = (PVOID)GetProcAddress(hmodUser32, "MessageBoxA"); - if (!pMessageBoxA) + /* Check if output should go to stderr */ + if (((msvcrt_error_mode == _OUT_TO_DEFAULT) && (__app_type == _CONSOLE_APP)) || + (msvcrt_error_mode == _OUT_TO_STDERR)) { + /* Print 'Assertion failed: x<y, file foo.c, line 45' to stderr */ + fprintf(stderr, "Assertion failed: %s, file %s, line %d\n", exp, file, line); abort(); }
/* Get the file name of the module */ - len = GetModuleFileNameA(NULL, achProgram, 40); + len = GetModuleFileNameA(NULL, achProgram, sizeof(achProgram));
/* Calculate full length of the message */ len += sizeof(formatstr) + len + strlen(exp) + strlen(file); @@ -51,22 +52,28 @@ _snprintf(pszBuffer, len, formatstr, achProgram, file, line, exp);
/* Display a message box */ - iResult = pMessageBoxA(NULL, - pszBuffer, - "ReactOS C Runtime Library", - MB_ABORTRETRYIGNORE | MB_ICONERROR); + iResult = __crt_MessageBoxA(pszBuffer, MB_ABORTRETRYIGNORE | MB_ICONERROR);
+ /* Free the buffer */ free(pszBuffer);
- /* Does the user want to abort? */ - if (iResult == IDABORT) + /* Does the user want to ignore? */ + if (iResult == IDIGNORE) { - abort(); + /* Just return to the caller */ + return; }
/* Does the user want to debug? */ if (iResult == IDRETRY) { - DbgRaiseAssertionFailure(); + /* Break and return to the caller */ + __debugbreak(); + return; } + + /* Reset all abort flags (we don*t want another message box) and abort */ + _set_abort_behavior(0, 0xffffffff); + abort(); } +
Modified: trunk/reactos/lib/sdk/crt/precomp.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/precomp.h?rev=5... ============================================================================== --- trunk/reactos/lib/sdk/crt/precomp.h [iso-8859-1] (original) +++ trunk/reactos/lib/sdk/crt/precomp.h [iso-8859-1] Tue Jan 8 22:14:10 2013 @@ -60,6 +60,7 @@ #include <internal/locale.h> #include <internal/math.h> #include <internal/mbstring.h> +#include <internal/misc.h> #include <internal/mtdll.h> #include <internal/rterror.h> #include <internal/safecrt.h>
Added: trunk/reactos/lib/sdk/crt/stdlib/_set_abort_behavior.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/stdlib/_set_abo... ============================================================================== --- trunk/reactos/lib/sdk/crt/stdlib/_set_abort_behavior.c (added) +++ trunk/reactos/lib/sdk/crt/stdlib/_set_abort_behavior.c [iso-8859-1] Tue Jan 8 22:14:10 2013 @@ -1,0 +1,39 @@ +/* + * PROJECT: ReactOS C runtime library + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: lib/sdk/crt/_set_abort_behavior.c + * PURPOSE: _set_abort_behavior implementation + * PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org) + */ + +extern unsigned int __abort_behavior; + +/*! + * \brief Specifies the behavior of the abort() function. + * + * \param flags - Value of the new flags. + * \param mask - Mask that specifies which flags to update. + * \return The old flags value. + */ +unsigned int +_cdecl +_set_abort_behavior( + unsigned int flags, + unsigned int mask) +{ + unsigned int old_flags; + + /* Save the old flags */ + old_flags = __abort_behavior; + + /* Reset all flags that are not in the mask */ + flags &= mask; + + /* Update the flags in the mask to the new flags value */ + __abort_behavior &= ~mask; + __abort_behavior |= flags; + + /* Return the old flags */ + return old_flags; +} +
Propchange: trunk/reactos/lib/sdk/crt/stdlib/_set_abort_behavior.c ------------------------------------------------------------------------------ svn:eol-style = native
Modified: trunk/reactos/lib/sdk/crt/stdlib/abort.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/stdlib/abort.c?... ============================================================================== --- trunk/reactos/lib/sdk/crt/stdlib/abort.c [iso-8859-1] (original) +++ trunk/reactos/lib/sdk/crt/stdlib/abort.c [iso-8859-1] Tue Jan 8 22:14:10 2013 @@ -1,114 +1,55 @@ /* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS system libraries - * FILE: lib/crt/stdlib/abort.c - * PURPOSE: Abnormal termination message - * PROGRAMER: Jon Griffiths - * Samuel Serapión + * PROJECT: ReactOS C runtime library + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: lib/sdk/crt/abort.c + * PURPOSE: abort implementation + * PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org) */
-/* based on wine exit.c */ +#include "precomp.h" +#include <signal.h>
-#include <precomp.h> -#include <signal.h> -#include <internal/wine/msvcrt.h> +unsigned int __abort_behavior = _WRITE_ABORT_MSG | _CALL_REPORTFAULT;
-extern int msvcrt_error_mode; -extern int __app_type; -unsigned int msvcrt_abort_behavior = MSVCRT__WRITE_ABORT_MSG | MSVCRT__CALL_REPORTFAULT; +static const char abort_msg[] = + "This application has requested the Runtime to terminate in an unusual way.\n" + "Please contact the applications's support team for more information.\0";
-/* avoid linking to user32 */ -typedef HWND (WINAPI *GetActiveWindowPtr)(void); -static GetActiveWindowPtr pGetActiveWindow = NULL; -typedef int (WINAPI *MessageBoxIndirectWPtr)(const MSGBOXPARAMSW*); -static MessageBoxIndirectWPtr pMessageBoxIndirectW = NULL; +/*! + * \brief Aborts the program. + * + * \note The function does not return. + */ +void +__cdecl +abort ( + void) +{ + /* Check if a message should be output */ + if (__abort_behavior & _WRITE_ABORT_MSG) + { + /* Check if we should display a message box */ + if (((msvcrt_error_mode == _OUT_TO_DEFAULT) && (__app_type == _GUI_APP)) || + (msvcrt_error_mode == _OUT_TO_MSGBOX)) + { + /* Output a message box */ + __crt_MessageBoxA(abort_msg, MB_OK); + } + else + { + /* Print message to stderr */ + fprintf(stderr, "%s\n", abort_msg); + } + }
-static void DoMessageBoxW(const wchar_t *lead, const wchar_t *message) -{ - const char szMsgBoxTitle[] = "ReactOS C++ Runtime Library"; - const wchar_t message_format[] = {'%','s','\n','\n','P','r','o','g','r','a','m',':',' ','%','s','\n', - '%','s','\n','\n','P','r','e','s','s',' ','O','K',' ','t','o',' ','e','x','i','t',' ','t','h','e',' ', - 'p','r','o','g','r','a','m',',',' ','o','r',' ','C','a','n','c','e','l',' ','t','o',' ','s','t','a','r','t',' ', - 't','h','e',' ','d','e','b','b','u','g','e','r','.','\n',0}; + /* Check if faultrep handler should be called */ + if (__abort_behavior & _CALL_REPORTFAULT) + { + /// \todo unimplemented + (void)0; + }
- MSGBOXPARAMSW msgbox; - wchar_t text[2048]; - INT ret; - - _snwprintf(text,sizeof(text),message_format, lead, _wpgmptr, message); - - msgbox.cbSize = sizeof(msgbox); - msgbox.hwndOwner = pGetActiveWindow(); - msgbox.hInstance = 0; - msgbox.lpszText = (LPCWSTR)text; - msgbox.lpszCaption = (LPCWSTR)szMsgBoxTitle; - msgbox.dwStyle = MB_OKCANCEL|MB_ICONERROR; - msgbox.lpszIcon = NULL; - msgbox.dwContextHelpId = 0; - msgbox.lpfnMsgBoxCallback = NULL; - msgbox.dwLanguageId = LANG_NEUTRAL; - - ret = pMessageBoxIndirectW(&msgbox); - if (ret == IDCANCEL) - DebugBreak(); + raise(SIGABRT); + _exit(3); }
-static void DoMessageBox(const char *lead, const char *message) -{ - wchar_t leadW[1024], messageW[1024]; - HMODULE huser32 = LoadLibrary("user32.dll"); - - if(huser32) { - pGetActiveWindow = (GetActiveWindowPtr)GetProcAddress(huser32, "GetActiveWindow"); - pMessageBoxIndirectW = (MessageBoxIndirectWPtr)GetProcAddress(huser32, "MessageBoxIndirectW"); - - if(!pGetActiveWindow || !pMessageBoxIndirectW) { - FreeLibrary(huser32); - ERR("GetProcAddress failed!\n"); - return; - } - } - else - { - ERR("Loading user32 failed!\n"); - return; - } - - mbstowcs(leadW, lead, 1024); - mbstowcs(messageW, message, 1024); - - DoMessageBoxW(leadW, messageW); - FreeLibrary(huser32); -} - -/* - * @implemented - */ -void abort() -{ - if (msvcrt_abort_behavior & MSVCRT__WRITE_ABORT_MSG) - { - if ((msvcrt_error_mode == MSVCRT__OUT_TO_MSGBOX) || - ((msvcrt_error_mode == MSVCRT__OUT_TO_DEFAULT) && (__app_type == 2))) - { - DoMessageBox("Runtime error!", "abnormal program termination"); - } - else - _cputs("\nabnormal program termination\n"); - } - raise(SIGABRT); - /* in case raise() returns */ - _exit(3); -} - -unsigned int CDECL _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; -}