in profiler/profile.bpf.c [105:160]
static int fix_lua_stack(struct bpf_perf_event_data *ctx, __u32 tid, int stack_id)
{
if (stack_id == 0)
{
return 0;
}
struct lua_stack_event *eventp;
eventp = bpf_map_lookup_elem(&lua_events, &tid);
if (!eventp)
return 0;
eventp->user_stack_id = stack_id;
lua_State *L = eventp->L;
if (!L)
return 0;
// start from the top of the stack and trace back
// count the number of function calls founded
int level = 1, count = 0;
cTValue *frame, *nextframe, *bot = tvref(BPF_PROBE_READ_USER(L, stack)) + LJ_FR2;
int i = 0;
frame = nextframe = BPF_PROBE_READ_USER(L, base) - 1;
/* Traverse frames backwards. */
// for the ebpf verifier insns (limit 1000000), we need to limit the max loop times to 13
for (; i < frame_depth && frame > bot; i++)
{
if (frame_gc(frame) == obj2gco(L))
{
level++; /* Skip dummy frames. See lj_err_optype_call(). */
}
if (level-- == 0)
{
level++;
/* Level found. */
if (lua_get_funcdata(ctx, frame, eventp, count) != 0)
{
continue;
}
count++;
}
nextframe = frame;
if (frame_islua(frame))
{
frame = frame_prevl(frame);
}
else
{
if (frame_isvarg(frame))
level++; /* Skip vararg pseudo-frame. */
frame = frame_prevd(frame);
}
}
return 0;
}