mirror of
https://github.com/zeek/zeek.git
synced 2025-10-10 02:28:21 +00:00
Lift backtrace() code into Func.{h,cc}
This is to be re-used by the assertion facility.
This commit is contained in:
parent
857c15a293
commit
e8811a55ef
3 changed files with 77 additions and 43 deletions
53
src/Func.cc
53
src/Func.cc
|
@ -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)
|
static void emit_builtin_error_common(const char* msg, Obj* arg, bool unwind)
|
||||||
{
|
{
|
||||||
auto emit = [=](const CallExpr* ce)
|
auto emit = [=](const CallExpr* ce)
|
||||||
|
|
19
src/Func.h
19
src/Func.h
|
@ -364,6 +364,25 @@ private:
|
||||||
|
|
||||||
extern std::vector<CallInfo> call_stack;
|
extern std::vector<CallInfo> call_stack;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a single BacktraceElement record val.
|
||||||
|
*
|
||||||
|
* @param name the name of the function.
|
||||||
|
* @param args call argument vector created by MakeCallArgumentVector().
|
||||||
|
* @param loc optional location information of the caller.
|
||||||
|
*
|
||||||
|
* @return record value representing a BacktraceElement.
|
||||||
|
*/
|
||||||
|
zeek::RecordValPtr make_backtrace_element(std::string_view name, const VectorValPtr args,
|
||||||
|
const zeek::detail::Location* loc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a Zeek script Backtrace of the current script call_stack.
|
||||||
|
*
|
||||||
|
* @return VectorValPtr containing BacktraceElement entries.
|
||||||
|
*/
|
||||||
|
zeek::VectorValPtr get_current_script_backtrace();
|
||||||
|
|
||||||
// This is set to true after the built-in functions have been initialized.
|
// This is set to true after the built-in functions have been initialized.
|
||||||
extern bool did_builtin_init;
|
extern bool did_builtin_init;
|
||||||
extern std::vector<void (*)()> bif_initializers;
|
extern std::vector<void (*)()> bif_initializers;
|
||||||
|
|
48
src/zeek.bif
48
src/zeek.bif
|
@ -2368,6 +2368,10 @@ function is_v6_subnet%(s: subnet%): bool
|
||||||
return zeek::val_mgr->False();
|
return zeek::val_mgr->False();
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
%%{
|
||||||
|
#include "zeek/Func.h"
|
||||||
|
%%}
|
||||||
|
|
||||||
## Returns a representation of the call stack as a vector of call stack
|
## Returns a representation of the call stack as a vector of call stack
|
||||||
## elements, each containing call location information.
|
## elements, each containing call location information.
|
||||||
##
|
##
|
||||||
|
@ -2375,49 +2379,7 @@ function is_v6_subnet%(s: subnet%): bool
|
||||||
## location information.
|
## location information.
|
||||||
function backtrace%(%): Backtrace
|
function backtrace%(%): Backtrace
|
||||||
%{
|
%{
|
||||||
using zeek::detail::call_stack;
|
return zeek::detail::get_current_script_backtrace();
|
||||||
static auto backtrace_type = id::find_type<VectorType>("Backtrace");
|
|
||||||
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 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 = 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;
|
|
||||||
|
|
||||||
auto elem = make_intrusive<RecordVal>(elem_type);
|
|
||||||
|
|
||||||
const auto& params = ci.func->GetType()->Params();
|
|
||||||
auto args = MakeCallArgumentVector(ci.args, params);
|
|
||||||
|
|
||||||
elem->Assign(function_name_idx, ci.func->Name());
|
|
||||||
elem->Assign(function_args_idx, std::move(args));
|
|
||||||
|
|
||||||
if ( ci.call )
|
|
||||||
{
|
|
||||||
auto loc = ci.call->GetLocationInfo();
|
|
||||||
elem->Assign(file_location_idx, loc->filename);
|
|
||||||
elem->Assign(line_location_idx, loc->first_line);
|
|
||||||
}
|
|
||||||
|
|
||||||
rval->Assign(rval->Size(), std::move(elem));
|
|
||||||
}
|
|
||||||
|
|
||||||
return rval;
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
# ===========================================================================
|
# ===========================================================================
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue