Lift backtrace() code into Func.{h,cc}

This is to be re-used by the assertion facility.
This commit is contained in:
Arne Welzel 2023-06-05 18:56:32 +02:00
parent 857c15a293
commit e8811a55ef
3 changed files with 77 additions and 43 deletions

View file

@ -903,6 +903,59 @@ FunctionIngredients::FunctionIngredients(ScopePtr _scope, StmtPtr _body,
}
}
zeek::RecordValPtr make_backtrace_element(std::string_view name, const VectorValPtr args,
const zeek::detail::Location* loc)
{
static auto elem_type = id::find_type<RecordType>("BacktraceElement");
static auto function_name_idx = elem_type->FieldOffset("function_name");
static auto function_args_idx = elem_type->FieldOffset("function_args");
static auto file_location_idx = elem_type->FieldOffset("file_location");
static auto line_location_idx = elem_type->FieldOffset("line_location");
auto elem = make_intrusive<RecordVal>(elem_type);
elem->Assign(function_name_idx, name.data());
elem->Assign(function_args_idx, std::move(args));
if ( loc )
{
elem->Assign(file_location_idx, loc->filename);
elem->Assign(line_location_idx, loc->first_line);
}
return elem;
}
zeek::VectorValPtr get_current_script_backtrace()
{
static auto backtrace_type = id::find_type<VectorType>("Backtrace");
auto rval = make_intrusive<VectorVal>(backtrace_type);
// The body of the following loop can wind up adding items to
// the call stack (because MakeCallArgumentVector() evaluates
// default arguments, which can in turn involve calls to script
// functions), so we work from a copy of the current call stack
// to prevent problems with iterator invalidation.
auto cs_copy = zeek::detail::call_stack;
for ( auto it = cs_copy.rbegin(); it != cs_copy.rend(); ++it )
{
const auto& ci = *it;
if ( ! ci.func )
// This happens for compiled code.
continue;
const auto& params = ci.func->GetType()->Params();
auto args = MakeCallArgumentVector(ci.args, params);
auto elem = make_backtrace_element(ci.func->Name(), std::move(args),
ci.call ? ci.call->GetLocationInfo() : nullptr);
rval->Append(std::move(elem));
}
return rval;
}
static void emit_builtin_error_common(const char* msg, Obj* arg, bool unwind)
{
auto emit = [=](const CallExpr* ce)