From: Dmitry Volyntsev Date: Thu, 22 Nov 2018 12:35:25 +0000 (+0300) Subject: Improved backtrace reporting for stack overflow. X-Git-Tag: 0.2.6~8 X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=7a4a3e6be0f3c59c92f6d6623a33dcc81e9b865d;p=njs.git Improved backtrace reporting for stack overflow. --- diff --git a/njs/njs_vm.c b/njs/njs_vm.c index cdf80a5d..819271d4 100644 --- a/njs/njs_vm.c +++ b/njs/njs_vm.c @@ -3202,12 +3202,12 @@ njs_vm_value_to_ext_string(njs_vm_t *vm, nxt_str_t *dst, const njs_value_t *src, 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 --git a/njs/test/njs_interactive_test.c b/njs/test/njs_interactive_test.c index e83c08c3..d4c2d13d 100644 --- a/njs/test/njs_interactive_test.c +++ b/njs/test/njs_interactive_test.c @@ -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