static int fix_lua_stack()

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;
}