diff --git a/CHANGES b/CHANGES index b2dcc13f2f..989ba30e5c 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,10 @@ +2.6-beta2-67 | 2018-11-02 17:41:46 -0500 + + * Add script-layer call stack to internal errors messages that abort (Jon Siwek, Corelight) + + * Improve error message of index assignment expression failures (Jon Siwek, Corelight) + 2.6-beta2-65 | 2018-11-02 09:36:30 -0500 * Improve Travis script to show multiple core dump stacks (Jon Siwek, Corelight) diff --git a/VERSION b/VERSION index 7ef7d0da78..b73b32485f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.6-beta2-65 +2.6-beta2-67 diff --git a/src/Func.cc b/src/Func.cc index 015829e2a1..9d624df1d1 100644 --- a/src/Func.cc +++ b/src/Func.cc @@ -56,6 +56,32 @@ bool did_builtin_init = false; vector Func::unique_ids; static const std::pair empty_hook_result(false, NULL); +std::string render_call_stack() + { + std::string rval; + int lvl = 0; + + if ( ! call_stack.empty() ) + rval += "| "; + + for ( auto it = call_stack.rbegin(); it != call_stack.rend(); ++it ) + { + if ( lvl > 0 ) + rval += " | "; + + auto& ci = *it; + auto loc = ci.call->GetLocationInfo(); + auto name = ci.func->Name(); + rval += fmt("#%d %s() at %s:%d", lvl, name, loc->filename, loc->first_line); + ++lvl; + } + + if ( ! call_stack.empty() ) + rval += " |"; + + return rval; + } + Func::Func() : scope(0), type(0) { unique_id = unique_ids.size(); diff --git a/src/Func.h b/src/Func.h index dc54087e06..f3f69f166b 100644 --- a/src/Func.h +++ b/src/Func.h @@ -147,6 +147,8 @@ struct CallInfo { extern vector call_stack; +extern std::string render_call_stack(); + // This is set to true after the built-in functions have been initialized. extern bool did_builtin_init; diff --git a/src/Obj.cc b/src/Obj.cc index 5553674598..023fa0d237 100644 --- a/src/Obj.cc +++ b/src/Obj.cc @@ -6,6 +6,7 @@ #include "Obj.h" #include "Serializer.h" +#include "Func.h" #include "File.h" #include "plugin/Manager.h" @@ -139,7 +140,13 @@ void BroObj::Internal(const char* msg) const { ODesc d; DoMsg(&d, msg); - reporter->InternalError("%s", d.Description()); + auto rcs = render_call_stack(); + + if ( rcs.empty() ) + reporter->InternalError("%s", d.Description()); + else + reporter->InternalError("%s, call stack: %s", d.Description(), rcs.data()); + reporter->PopLocation(); } diff --git a/testing/btest/Baseline/language.index-assignment-invalid/out b/testing/btest/Baseline/language.index-assignment-invalid/out index 879e1b8fb7..d2034bdc55 100644 --- a/testing/btest/Baseline/language.index-assignment-invalid/out +++ b/testing/btest/Baseline/language.index-assignment-invalid/out @@ -1 +1,5 @@ -internal error in /Users/jon/projects/bro/bro/scripts/base/utils/queue.bro, line 152: vector index assignment failed for invalid type 'myrec', value: [a=T, b=hi, c=] (Queue::ret[Queue::j]) +internal error in /Users/jon/projects/bro/bro/scripts/base/utils/queue.bro, line 152: vector index assignment failed for invalid type 'myrec', value: [a=T, b=hi, c=] (Queue::ret[Queue::j]), call stack: + #0 Queue::get_vector() at /Users/jon/projects/bro/bro/testing/btest/.tmp/language.index-assignment-invalid/index-assignment-invalid.bro:19 + #1 bar() at /Users/jon/projects/bro/bro/testing/btest/.tmp/language.index-assignment-invalid/index-assignment-invalid.bro:27 + #2 foo() at /Users/jon/projects/bro/bro/testing/btest/.tmp/language.index-assignment-invalid/index-assignment-invalid.bro:39 + diff --git a/testing/btest/language/index-assignment-invalid.bro b/testing/btest/language/index-assignment-invalid.bro index 6425ca5b1a..170183fb8a 100644 --- a/testing/btest/language/index-assignment-invalid.bro +++ b/testing/btest/language/index-assignment-invalid.bro @@ -1,4 +1,6 @@ -# @TEST-EXEC-FAIL: bro -b %INPUT >out 2>&1 +# @TEST-EXEC-FAIL: bro -b %INPUT >output 2>&1 +# @TEST-EXEC: grep "internal error" output >output2 +# @TEST-EXEC: for i in {1..5}; do cat output2 | cut -d'|' -f$i >>out; done # @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff out @load base/utils/queue @@ -11,11 +13,18 @@ type myrec: record { c: string &optional; }; -function foo(mr: myrec) +function bar() { - print mr$a; - print mr$c; - print mr$b; + local rval: vector of string = vector(); + Queue::get_vector(q, rval); + print rval; + Queue::get_vector(q, rval); + print rval; + } + +function foo() + { + bar(); } event bro_init() @@ -24,8 +33,8 @@ event bro_init() Queue::put(q, "goodbye"); Queue::put(q, "test"); Queue::put(q, myrec()); - - local rval: vector of string = vector(); - Queue::get_vector(q, rval); - print rval; + Queue::put(q, "asdf"); + Queue::put(q, 3); + Queue::put(q, "jkl;"); + foo(); }