Skip to content

Commit b0477fe

Browse files
authored
Merge pull request #7 from louxiu/master
FIX: Ensure that the type of vals matches counts's
2 parents 5263a71 + c4e3757 commit b0477fe

File tree

2 files changed

+86
-15
lines changed

2 files changed

+86
-15
lines changed

bpftools/profile_nginx_lua/profile.bpf.c

+36-11
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ const volatile bool disable_lua_user_trace = false;
1010
const volatile bool include_idle = false;
1111
const volatile pid_t targ_pid = -1;
1212
const volatile pid_t targ_tid = -1;
13+
const volatile __u64 targ_ns_dev = 0;
14+
const volatile __u64 targ_ns_ino = 0;
15+
const volatile __u64 stack_depth_limit = 0;
1316

1417
struct
1518
{
@@ -84,7 +87,7 @@ static inline int lua_get_funcdata(struct bpf_perf_event_data *ctx, cTValue *fra
8487
if (!src)
8588
return -1;
8689
bpf_probe_read_user_str(eventp->name, sizeof(eventp->name), src);
87-
bpf_printk("level= %d, fn_name=%s\n", level, eventp->name);
90+
//bpf_printk("level= %d, fn_name=%s\n", level, eventp->name);
8891
}
8992
else if (iscfunc(fn))
9093
{
@@ -127,7 +130,7 @@ static int fix_lua_stack(struct bpf_perf_event_data *ctx, __u32 tid, int stack_i
127130
frame = nextframe = BPF_PROBE_READ_USER(L, base) - 1;
128131
/* Traverse frames backwards. */
129132
// for the ebpf verifier insns (limit 1000000), we need to limit the max loop times to 13
130-
for (; i < 15 && frame > bot; i++)
133+
for (; i < stack_depth_limit && frame > bot; i++)
131134
{
132135
if (frame_gc(frame) == obj2gco(L))
133136
{
@@ -159,12 +162,33 @@ static int fix_lua_stack(struct bpf_perf_event_data *ctx, __u32 tid, int stack_i
159162
return 0;
160163
}
161164

165+
static long get_current_pid_tgid(__u32 *pid, __u32 *tid)
166+
{
167+
if (targ_ns_dev == 0 && targ_ns_ino == 0)
168+
{
169+
__u64 id = bpf_get_current_pid_tgid();
170+
*pid = id >> 32;
171+
*tid = id;
172+
return 0;
173+
}
174+
175+
struct bpf_pidns_info ns = {};
176+
long ret = bpf_get_ns_current_pid_tgid(targ_ns_dev, targ_ns_ino, &ns, sizeof(struct bpf_pidns_info));
177+
if (ret)
178+
return ret;
179+
180+
*pid = ns.pid;
181+
*tid = ns.tgid;
182+
return 0;
183+
}
184+
162185
SEC("perf_event")
163186
int do_perf_event(struct bpf_perf_event_data *ctx)
164187
{
165-
__u64 id = bpf_get_current_pid_tgid();
166-
__u32 pid = id >> 32;
167-
__u32 tid = id;
188+
__u32 pid = 0, tid = 0;
189+
if (get_current_pid_tgid(&pid, &tid))
190+
return 0;
191+
168192
__u64 *valp;
169193
static const __u64 zero;
170194
struct profile_key_t key = {};
@@ -220,9 +244,9 @@ static int probe_entry_lua_cancel(struct pt_regs *ctx)
220244
if (!PT_REGS_PARM4(ctx))
221245
return 0;
222246

223-
__u64 pid_tgid = bpf_get_current_pid_tgid();
224-
__u32 pid = pid_tgid >> 32;
225-
__u32 tid = (__u32)pid_tgid;
247+
__u32 pid = 0, tid = 0;
248+
if (get_current_pid_tgid(&pid, &tid))
249+
return 0;
226250

227251
if (targ_pid != -1 && targ_pid != pid)
228252
return 0;
@@ -241,9 +265,10 @@ static int probe_entry_lua(struct pt_regs *ctx)
241265
if (!PT_REGS_PARM1(ctx))
242266
return 0;
243267

244-
__u64 pid_tgid = bpf_get_current_pid_tgid();
245-
__u32 pid = pid_tgid >> 32;
246-
__u32 tid = (__u32)pid_tgid;
268+
__u32 pid = 0, tid = 0;
269+
if (get_current_pid_tgid(&pid, &tid))
270+
return 0;
271+
247272
struct lua_stack_event event = {};
248273

249274
if (targ_pid != -1 && targ_pid != pid)

bpftools/profile_nginx_lua/profile.c

+50-4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <unistd.h>
1616
#include <time.h>
1717
#include <linux/perf_event.h>
18+
#include <sys/stat.h>
1819
#include <asm/unistd.h>
1920
#include <bpf/libbpf.h>
2021
#include <bpf/bpf.h>
@@ -38,12 +39,15 @@ static struct env
3839
{
3940
pid_t pid;
4041
pid_t tid;
42+
__u64 ns_dev;
43+
__u64 ns_ino;
4144
bool user_stacks_only;
4245
bool kernel_stacks_only;
4346
// control lua user space stack trace
4447
bool disable_lua_user_trace;
4548
bool lua_user_stacks_only;
4649
int stack_storage_size;
50+
int stack_depth_limit;
4751
int perf_max_stack_depth;
4852
int duration;
4953
bool verbose;
@@ -56,7 +60,10 @@ static struct env
5660
} env = {
5761
.pid = -1,
5862
.tid = -1,
63+
.ns_dev = 0,
64+
.ns_ino = 0,
5965
.stack_storage_size = 8192,
66+
.stack_depth_limit = 15,
6067
.perf_max_stack_depth = 127,
6168
.duration = 3,
6269
.freq = 1,
@@ -87,8 +94,9 @@ const char argp_program_doc[] =
8794

8895
#define OPT_PERF_MAX_STACK_DEPTH 1 /* --perf-max-stack-depth */
8996
#define OPT_STACK_STORAGE_SIZE 2 /* --stack-storage-size */
90-
#define OPT_LUA_USER_STACK_ONLY 3 /* --lua-user-stacks-only */
91-
#define OPT_DISABLE_LUA_USER_TRACE 4 /* --disable-lua-user-trace */
97+
#define OPT_STACK_DEPTH_LIMIT 3 /* --stack-depth-limit */
98+
#define OPT_LUA_USER_STACK_ONLY 4 /* --lua-user-stacks-only */
99+
#define OPT_DISABLE_LUA_USER_TRACE 5 /* --disable-lua-user-trace */
92100
#define PERF_BUFFER_PAGES 16
93101
#define PERF_POLL_TIMEOUT_MS 100
94102

@@ -109,6 +117,8 @@ static const struct argp_option opts[] = {
109117
{"folded", 'f', NULL, 0, "output folded format, one line per stack (for flame graphs)"},
110118
{"stack-storage-size", OPT_STACK_STORAGE_SIZE, "STACK-STORAGE-SIZE", 0,
111119
"the number of unique stack traces that can be stored and displayed (default 1024)"},
120+
{"stack-depth-limit", OPT_STACK_DEPTH_LIMIT, "OPT_STACK_DEPTH_LIMIT", 0,
121+
"the limit depth of stack that be traversed (default 15)"},
112122
{"cpu", 'C', "CPU", 0, "cpu number to run profile on"},
113123
{"perf-max-stack-depth", OPT_PERF_MAX_STACK_DEPTH,
114124
"PERF-MAX-STACK-DEPTH", 0, "the limit for both kernel and user stack traces (default 127)"},
@@ -117,6 +127,22 @@ static const struct argp_option opts[] = {
117127
{},
118128
};
119129

130+
static int read_ns_dev_ino( __u64 *ns_dev, __u64 *ns_ino)
131+
{
132+
struct stat statbuf;
133+
const char *path = "/proc/self/ns/pid";
134+
135+
if (stat(path, &statbuf) == -1) {
136+
perror("stat");
137+
return 1;
138+
}
139+
140+
*ns_dev = statbuf.st_dev;
141+
*ns_ino = statbuf.st_ino;
142+
143+
return 0;
144+
}
145+
120146
static error_t parse_arg(int key, char *arg, struct argp_state *state)
121147
{
122148
static int pos_args;
@@ -198,6 +224,15 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state)
198224
argp_usage(state);
199225
}
200226
break;
227+
case OPT_STACK_DEPTH_LIMIT:
228+
errno = 0;
229+
env.stack_depth_limit = strtol(arg, NULL, 10);
230+
if (errno)
231+
{
232+
fprintf(stderr, "invalid stack depth limit: %s\n", arg);
233+
argp_usage(state);
234+
}
235+
break;
201236
case OPT_LUA_USER_STACK_ONLY:
202237
env.lua_user_stacks_only = true;
203238
break;
@@ -299,7 +334,7 @@ static bool read_batch_counts_map(int fd, struct key_ext_t *items, __u32 *count)
299334
void *in = NULL, *out;
300335
__u32 i, n, n_read = 0;
301336
int err = 0;
302-
__u32 vals[*count];
337+
__u64 vals[*count];
303338
struct profile_key_t keys[*count];
304339

305340
while (n_read < *count && !err)
@@ -774,9 +809,18 @@ int main(int argc, char **argv)
774809
return 1;
775810
}
776811

812+
if(read_ns_dev_ino(&env.ns_dev, &env.ns_ino))
813+
{
814+
fprintf(stderr, "failed to read ns_dev and ns_ino\n");
815+
return 1;
816+
}
817+
777818
/* initialize global data (filtering options) */
778819
obj->rodata->targ_pid = env.pid;
779820
obj->rodata->targ_tid = env.tid;
821+
obj->rodata->targ_ns_dev = env.ns_dev;
822+
obj->rodata->targ_ns_ino = env.ns_ino;
823+
obj->rodata->stack_depth_limit = env.stack_depth_limit;
780824
obj->rodata->user_stacks_only = env.user_stacks_only;
781825
obj->rodata->kernel_stacks_only = env.kernel_stacks_only;
782826
obj->rodata->include_idle = env.include_idle;
@@ -788,7 +832,9 @@ int main(int argc, char **argv)
788832
err = profile_bpf__load(obj);
789833
if (err)
790834
{
791-
fprintf(stderr, "failed to load BPF programs\n");
835+
fprintf(stderr, "failed to load BPF programs. "
836+
"if the error message indicates `BPF program is too large`, "
837+
"consider using the `--stack-depth-limit` option.\n");
792838
goto cleanup;
793839
}
794840
ksyms = ksyms__load();

0 commit comments

Comments
 (0)