diff --git a/jerry-core/api/jerryscript.c b/jerry-core/api/jerryscript.c index 60f8023fd0..5a874a3f32 100644 --- a/jerry-core/api/jerryscript.c +++ b/jerry-core/api/jerryscript.c @@ -172,6 +172,7 @@ jerry_return (const jerry_value_t value) /**< return value */ void jerry_init (jerry_init_flag_t flags) /**< combination of Jerry flags */ { + jerry_port_init (); #if JERRY_EXTERNAL_CONTEXT size_t total_size = jerry_port_context_alloc (sizeof (jerry_context_t)); JERRY_UNUSED (total_size); diff --git a/jerry-core/include/jerryscript-port.h b/jerry-core/include/jerryscript-port.h index 0d8b34e1d4..420ecd9bdf 100644 --- a/jerry-core/include/jerryscript-port.h +++ b/jerry-core/include/jerryscript-port.h @@ -49,6 +49,11 @@ typedef enum JERRY_FATAL_FAILED_ASSERTION = 120 /**< Assertion failed */ } jerry_fatal_code_t; +/** + * Init the program + */ +void jerry_port_init (void); + /** * Signal the port that the process experienced a fatal failure from which it cannot * recover. diff --git a/jerry-port/common/jerry-port-process.c b/jerry-port/common/jerry-port-process.c index 25c6f9027d..cbf943c03d 100644 --- a/jerry-port/common/jerry-port-process.c +++ b/jerry-port/common/jerry-port-process.c @@ -17,6 +17,18 @@ #include "jerryscript-port.h" +#if !defined(_WIN32) + +/** + * Default implementation of jerry_port_init. Do nothing. + */ +void JERRY_ATTR_WEAK +jerry_port_init (void) +{ +} /* jerry_port_init */ + +#endif /* !defined(_WIN32) */ + /** * Default implementation of jerry_port_fatal. Calls 'abort' if exit code is * non-zero, 'exit' otherwise. diff --git a/jerry-port/win/jerry-port-win-process.c b/jerry-port/win/jerry-port-win-process.c index c4949a2bf5..e6b2288fc0 100644 --- a/jerry-port/win/jerry-port-win-process.c +++ b/jerry-port/win/jerry-port-win-process.c @@ -18,6 +18,68 @@ #include +#include +#include + +void +jerry_port_init (void) +{ + if (!IsDebuggerPresent ()) + { + /* Make output streams unbuffered by default */ + setvbuf (stdout, NULL, _IONBF, 0); + setvbuf (stderr, NULL, _IONBF, 0); + + /* + * By default abort() only generates a crash-dump in *non* debug + * builds. As our Assert() / ExceptionalCondition() uses abort(), + * leaving the default in place would make debugging harder. + * + * MINGW's own C runtime doesn't have _set_abort_behavior(). When + * targeting Microsoft's UCRT with mingw, it never links to the debug + * version of the library and thus doesn't need the call to + * _set_abort_behavior() either. + */ +#if !defined(__MINGW32__) && !defined(__MINGW64__) + _set_abort_behavior (_CALL_REPORTFAULT | _WRITE_ABORT_MSG, _CALL_REPORTFAULT | _WRITE_ABORT_MSG); +#endif /* !defined(__MINGW32__) && !defined(__MINGW64__) */ + + /* + * SEM_FAILCRITICALERRORS causes more errors to be reported to + * callers. + * + * We used to also specify SEM_NOGPFAULTERRORBOX, but that prevents + * windows crash reporting from working. Which includes registered + * just-in-time debuggers, making it unnecessarily hard to debug + * problems on windows. Now we try to disable sources of popups + * separately below (note that SEM_NOGPFAULTERRORBOX did not actually + * prevent all sources of such popups). + */ + SetErrorMode (SEM_FAILCRITICALERRORS); + + /* + * Show errors on stderr instead of popup box (note this doesn't + * affect errors originating in the C runtime, see below). + */ + _set_error_mode (_OUT_TO_STDERR); + + /* + * In DEBUG builds, errors, including assertions, C runtime errors are + * reported via _CrtDbgReport. By default such errors are displayed + * with a popup (even with NOGPFAULTERRORBOX), preventing forward + * progress. Instead report such errors stderr (and the debugger). + * This is C runtime specific and thus the above incantations aren't + * sufficient to suppress these popups. + */ + _CrtSetReportMode (_CRT_ERROR, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); + _CrtSetReportFile (_CRT_ERROR, _CRTDBG_FILE_STDERR); + _CrtSetReportMode (_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); + _CrtSetReportFile (_CRT_ASSERT, _CRTDBG_FILE_STDERR); + _CrtSetReportMode (_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); + _CrtSetReportFile (_CRT_WARN, _CRTDBG_FILE_STDERR); + } +} /* jerry_port_init */ + /** * Default implementation of jerry_port_sleep, uses 'Sleep'. */