15
15
#include <unistd.h>
16
16
#include <time.h>
17
17
#include <linux/perf_event.h>
18
+ #include <sys/stat.h>
18
19
#include <asm/unistd.h>
19
20
#include <bpf/libbpf.h>
20
21
#include <bpf/bpf.h>
@@ -38,12 +39,15 @@ static struct env
38
39
{
39
40
pid_t pid ;
40
41
pid_t tid ;
42
+ __u64 ns_dev ;
43
+ __u64 ns_ino ;
41
44
bool user_stacks_only ;
42
45
bool kernel_stacks_only ;
43
46
// control lua user space stack trace
44
47
bool disable_lua_user_trace ;
45
48
bool lua_user_stacks_only ;
46
49
int stack_storage_size ;
50
+ int stack_depth_limit ;
47
51
int perf_max_stack_depth ;
48
52
int duration ;
49
53
bool verbose ;
@@ -56,7 +60,10 @@ static struct env
56
60
} env = {
57
61
.pid = -1 ,
58
62
.tid = -1 ,
63
+ .ns_dev = 0 ,
64
+ .ns_ino = 0 ,
59
65
.stack_storage_size = 8192 ,
66
+ .stack_depth_limit = 15 ,
60
67
.perf_max_stack_depth = 127 ,
61
68
.duration = 3 ,
62
69
.freq = 1 ,
@@ -87,8 +94,9 @@ const char argp_program_doc[] =
87
94
88
95
#define OPT_PERF_MAX_STACK_DEPTH 1 /* --perf-max-stack-depth */
89
96
#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 */
92
100
#define PERF_BUFFER_PAGES 16
93
101
#define PERF_POLL_TIMEOUT_MS 100
94
102
@@ -109,6 +117,8 @@ static const struct argp_option opts[] = {
109
117
{"folded" , 'f' , NULL , 0 , "output folded format, one line per stack (for flame graphs)" },
110
118
{"stack-storage-size" , OPT_STACK_STORAGE_SIZE , "STACK-STORAGE-SIZE" , 0 ,
111
119
"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)" },
112
122
{"cpu" , 'C' , "CPU" , 0 , "cpu number to run profile on" },
113
123
{"perf-max-stack-depth" , OPT_PERF_MAX_STACK_DEPTH ,
114
124
"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[] = {
117
127
{},
118
128
};
119
129
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
+
120
146
static error_t parse_arg (int key , char * arg , struct argp_state * state )
121
147
{
122
148
static int pos_args ;
@@ -198,6 +224,15 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state)
198
224
argp_usage (state );
199
225
}
200
226
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 ;
201
236
case OPT_LUA_USER_STACK_ONLY :
202
237
env .lua_user_stacks_only = true;
203
238
break ;
@@ -774,9 +809,18 @@ int main(int argc, char **argv)
774
809
return 1 ;
775
810
}
776
811
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
+
777
818
/* initialize global data (filtering options) */
778
819
obj -> rodata -> targ_pid = env .pid ;
779
820
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 ;
780
824
obj -> rodata -> user_stacks_only = env .user_stacks_only ;
781
825
obj -> rodata -> kernel_stacks_only = env .kernel_stacks_only ;
782
826
obj -> rodata -> include_idle = env .include_idle ;
@@ -788,7 +832,9 @@ int main(int argc, char **argv)
788
832
err = profile_bpf__load (obj );
789
833
if (err )
790
834
{
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" );
792
838
goto cleanup ;
793
839
}
794
840
ksyms = ksyms__load ();
0 commit comments