Skip to content

Add backtrace print when the 'assert' js method fails #3051

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 5, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/10.EXT-REFERENCE-HANDLER.md
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,9 @@ For example usage see [jerryx_set_properties](#jerryx_set_properties).

Hard assert for scripts. The routine calls `jerry_port_fatal` on assertion failure.

If the `JERRY_FEATURE_LINE_INFO` runtime feature is enabled (build option: `JERRY_LINE_INFO`)
a backtrace is also printed out.

**Prototype**

```c
Expand Down
51 changes: 51 additions & 0 deletions jerry-ext/handler/handler-assert.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,15 @@
#include "jerryscript-ext/handler.h"
#include "jerryscript-port.h"

#include <inttypes.h>

/**
* Hard assert for scripts. The routine calls jerry_port_fatal on assertion failure.
*
* Notes:
* * If the `JERRY_FEATURE_LINE_INFO` runtime feature is enabled (build option: `JERRY_LINE_INFO`)
* a backtrace is also printed out.
*
* @return true - if only one argument was passed and that argument was a boolean true.
* Note that the function does not return otherwise.
*/
Expand All @@ -38,7 +44,52 @@ jerryx_handler_assert_fatal (const jerry_value_t func_obj_val, /**< function obj
return jerry_create_boolean (true);
}

/* Assert failed, print a bit of JS backtrace */
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Script Error: assertion failed\n");

if (jerry_is_feature_enabled (JERRY_FEATURE_LINE_INFO))
{
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Script backtrace (top 5):\n");

/* If the line info feature is disabled an empty array will be returned. */
jerry_value_t backtrace_array = jerry_get_backtrace (5);
uint32_t array_length = jerry_get_array_length (backtrace_array);

for (uint32_t idx = 0; idx < array_length; idx++)
{
jerry_value_t property = jerry_get_property_by_index (backtrace_array, idx);

jerry_length_t total_size = jerry_get_utf8_string_size (property);
jerry_length_t current_size = 0;
jerry_char_t string_buffer[64];
const jerry_length_t copy_size = (jerry_length_t) (sizeof (string_buffer) - 1);

/* On some systems the uint32_t values can't be printed with "%u" and
* on some systems it can be printed. To avoid differences in the uint32_t typdef
* The "PRIu32" macro is used to correctly add the formatter.
*/
jerry_port_log (JERRY_LOG_LEVEL_ERROR, " %"PRIu32": ", idx);
do
{
jerry_size_t copied_bytes = jerry_substring_to_utf8_char_buffer (property,
current_size,
current_size + copy_size,
string_buffer,
copy_size);
string_buffer[copied_bytes] = '\0';
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "%s", string_buffer);

current_size += copied_bytes;
}
while (total_size != current_size);
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "\n");

jerry_release_value (property);
}

jerry_release_value (backtrace_array);
}

jerry_port_fatal (ERR_FAILED_INTERNAL_ASSERTION);
} /* jerryx_handler_assert_fatal */

Expand Down