[njs] Improved backtrace reporting for stack overflow.
Dmitry Volyntsev
xeioex at nginx.com
Thu Nov 22 12:54:42 UTC 2018
details: https://hg.nginx.org/njs/rev/987f7998a967
branches:
changeset: 663:987f7998a967
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Thu Nov 22 15:35:25 2018 +0300
description:
Improved backtrace reporting for stack overflow.
diffstat:
njs/njs_vm.c | 63 ++++++++++++++++++++++++++++++++--------
njs/test/njs_interactive_test.c | 6 +++
2 files changed, 56 insertions(+), 13 deletions(-)
diffs (117 lines):
diff -r 01f2cbf5acc4 -r 987f7998a967 njs/njs_vm.c
--- a/njs/njs_vm.c Thu Nov 22 15:02:19 2018 +0300
+++ b/njs/njs_vm.c Thu Nov 22 15:35:25 2018 +0300
@@ -3202,12 +3202,12 @@ njs_vm_value_to_ext_string(njs_vm_t *vm,
nxt_uint_t handle_exception)
{
u_char *p, *start;
- size_t len, size;
+ size_t len, size, count;
njs_ret_t ret;
nxt_uint_t i, exception;
nxt_array_t *backtrace;
njs_value_t value;
- njs_backtrace_entry_t *be;
+ njs_backtrace_entry_t *be, *prev;
exception = handle_exception;
@@ -3273,17 +3273,35 @@ again:
len = dst->length + 1;
+ count = 0;
+ prev = NULL;
+
be = backtrace->start;
for (i = 0; i < backtrace->items; i++) {
- if (be[i].line != 0) {
- len += sizeof(" at (:)\n") + 10
- + be[i].name.length;
+ if (i != 0 && prev->name.start == be[i].name.start
+ && prev->line == be[i].line)
+ {
+ count++;
} else {
- len += sizeof(" at (native)\n")
- + be[i].name.length;
+
+ if (count != 0) {
+ len += sizeof(" repeats times\n") + 10;
+ count = 0;
+ }
+
+ if (be[i].line != 0) {
+ len += sizeof(" at (:)\n") + 10
+ + be[i].name.length;
+
+ } else {
+ len += sizeof(" at (native)\n")
+ + be[i].name.length;
+ }
}
+
+ prev = &be[i];
}
p = nxt_mem_cache_alloc(vm->mem_cache_pool, len);
@@ -3297,16 +3315,35 @@ again:
p = nxt_cpymem(p, dst->start, dst->length);
*p++ = '\n';
+ count = 0;
+ prev = NULL;
+
for (i = 0; i < backtrace->items; i++) {
- if (be[i].line != 0) {
- p += sprintf((char *) p, " at %.*s (:%u)\n",
- (int) be[i].name.length, be[i].name.start,
- be[i].line);
+ if (i != 0 && prev->name.start == be[i].name.start
+ && prev->line == be[i].line)
+ {
+ count++;
} else {
- p += sprintf((char *) p, " at %.*s (native)\n",
- (int) be[i].name.length, be[i].name.start);
+ if (count != 0) {
+ p += sprintf((char *) p,
+ " repeats %zu times\n", count);
+ count =0;
+ }
+
+ if (be[i].line != 0) {
+ p += sprintf((char *) p, " at %.*s (:%u)\n",
+ (int) be[i].name.length,
+ be[i].name.start, be[i].line);
+
+ } else {
+ p += sprintf((char *) p, " at %.*s (native)\n",
+ (int) be[i].name.length,
+ be[i].name.start);
+ }
}
+
+ prev = &be[i];
}
dst->start = start;
diff -r 01f2cbf5acc4 -r 987f7998a967 njs/test/njs_interactive_test.c
--- a/njs/test/njs_interactive_test.c Thu Nov 22 15:02:19 2018 +0300
+++ b/njs/test/njs_interactive_test.c Thu Nov 22 15:35:25 2018 +0300
@@ -220,6 +220,12 @@ static njs_interactive_test_t njs_test[
" at parseInt (native)\n"
" at main (native)\n") },
+ { nxt_string("function f(n) { if (n == 0) { throw 'a'; } return f(n-1); }; f(2)" ENTER),
+ nxt_string("a\n"
+ " at f (:1)\n"
+ " repeats 2 times\n"
+ " at main (native)\n") },
+
/* Exception in njs_vm_retval_to_ext_string() */
{ nxt_string("var o = { toString: function() { return [1] } }" ENTER
More information about the nginx-devel
mailing list