forked from namhyung/uftrace
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfstack.h
184 lines (157 loc) · 5.14 KB
/
fstack.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#ifndef UFTRACE_FSTACK_H
#define UFTRACE_FSTACK_H
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "uftrace.h"
#include "utils/filter.h"
struct uftrace_symbol;
enum uftrace_fstack_flag {
FSTACK_FL_FILTERED = (1U << 0),
FSTACK_FL_NOTRACE = (1U << 1),
FSTACK_FL_NORECORD = (1U << 2),
FSTACK_FL_EXEC = (1U << 3),
FSTACK_FL_LONGJMP = (1U << 4),
};
enum uftrace_fstack_context {
FSTACK_CTX_UNKNOWN = 0,
FSTACK_CTX_USER = 1,
FSTACK_CTX_KERNEL = 2,
};
struct uftrace_task_filter_stack {
struct uftrace_task_filter_stack *next;
uint64_t threshold;
int depth;
unsigned size;
enum uftrace_fstack_context context;
};
struct uftrace_task_reader {
int tid;
bool valid;
bool done;
bool lost_seen;
bool sched_out_seen;
bool fork_handled;
bool fstack_set;
bool display_depth_set;
bool fstack_warned;
FILE *fp;
struct uftrace_symbol *func;
struct uftrace_task *t;
struct uftrace_data *h;
struct uftrace_record ustack;
struct uftrace_record kstack;
struct uftrace_record estack;
struct uftrace_record xstack;
struct uftrace_record *rstack;
struct uftrace_rstack_list rstack_list;
struct uftrace_rstack_list event_list;
int stack_count;
int lost_count;
int user_stack_count;
int display_depth;
int user_display_depth;
int fork_display_depth;
int column_index;
int event_color;
int sched_cpu;
enum uftrace_fstack_context ctx;
uint64_t timestamp;
uint64_t timestamp_last;
uint64_t timestamp_next;
uint64_t timestamp_estimate;
struct {
int in_count;
int out_count;
int depth;
struct uftrace_task_filter_stack *stack;
} filter;
struct uftrace_fstack {
uint64_t addr;
bool valid;
int orig_depth;
unsigned long flags;
uint64_t total_time;
uint64_t child_time;
} * func_stack;
struct uftrace_fstack_args args;
bool sched_preempt_seen;
};
enum uftrace_argspec_string_bits {
/* bit index */
NEEDS_PAREN_BIT,
NEEDS_SEMI_COLON_BIT,
HAS_MORE_BIT,
IS_RETVAL_BIT,
NEEDS_ASSIGNMENT_BIT,
NEEDS_JSON_BIT,
/* bit mask */
NEEDS_PAREN = (1U << NEEDS_PAREN_BIT),
NEEDS_SEMI_COLON = (1U << NEEDS_SEMI_COLON_BIT),
HAS_MORE = (1U << HAS_MORE_BIT),
IS_RETVAL = (1U << IS_RETVAL_BIT),
NEEDS_ASSIGNMENT = (1U << NEEDS_ASSIGNMENT_BIT),
NEEDS_JSON = (1U << NEEDS_JSON_BIT),
};
extern bool fstack_enabled;
extern bool live_disabled;
struct uftrace_task_reader *get_task_handle(struct uftrace_data *handle, int tid);
void reset_task_handle(struct uftrace_data *handle);
void fstack_setup_task(char *tid_filter, struct uftrace_data *handle);
int read_rstack(struct uftrace_data *handle, struct uftrace_task_reader **task);
int peek_rstack(struct uftrace_data *handle, struct uftrace_task_reader **task);
void fstack_consume(struct uftrace_data *handle, struct uftrace_task_reader *task);
int read_task_ustack(struct uftrace_data *handle, struct uftrace_task_reader *task);
int read_task_args(struct uftrace_task_reader *task, struct uftrace_record *rstack, bool is_retval);
static inline bool is_user_record(struct uftrace_task_reader *task, struct uftrace_record *rec)
{
return rec == &task->ustack;
}
static inline bool is_kernel_record(struct uftrace_task_reader *task, struct uftrace_record *rec)
{
return rec == &task->kstack;
}
static inline bool is_event_record(struct uftrace_task_reader *task, struct uftrace_record *rec)
{
return rec == &task->estack;
}
static inline bool is_extern_record(struct uftrace_task_reader *task, struct uftrace_record *rec)
{
return rec == &task->xstack;
}
void setup_fstack_args(char *argspec, char *retspec, struct uftrace_data *handle,
struct uftrace_filter_setting *setting);
int fstack_setup_filters(struct uftrace_opts *opts, struct uftrace_data *handle);
struct uftrace_fstack *fstack_get(struct uftrace_task_reader *task, int idx);
int fstack_entry(struct uftrace_task_reader *task, struct uftrace_record *rstack,
struct uftrace_trigger *tr);
void fstack_exit(struct uftrace_task_reader *task);
int fstack_update(int type, struct uftrace_task_reader *task, struct uftrace_fstack *fstack);
struct uftrace_task_reader *fstack_skip(struct uftrace_data *handle,
struct uftrace_task_reader *task, int curr_depth,
struct uftrace_opts *opts);
bool fstack_check_filter(struct uftrace_task_reader *task);
bool fstack_check_opts(struct uftrace_task_reader *task, struct uftrace_opts *opts);
void fstack_check_filter_done(struct uftrace_task_reader *task);
bool is_sched_event(uint64_t addr);
bool is_sched_preempt_event(struct uftrace_task_reader *task, uint64_t addr);
void get_argspec_string(struct uftrace_task_reader *task, char *args, size_t len,
enum uftrace_argspec_string_bits str_mode);
#define EXTERN_DATA_MAX 1024
struct uftrace_extern_reader {
FILE *fp;
bool valid;
uint64_t time;
char msg[EXTERN_DATA_MAX];
struct uftrace_record rec;
};
int setup_extern_data(struct uftrace_data *handle, struct uftrace_opts *opts);
int read_extern_data(struct uftrace_data *handle, struct uftrace_extern_reader *extn);
struct uftrace_record *get_extern_record(struct uftrace_extern_reader *extn,
struct uftrace_record *rec);
int finish_extern_data(struct uftrace_data *handle);
static inline bool has_extern_data(struct uftrace_data *handle)
{
return handle->extn != NULL;
}
#endif /* UFTRACE_FSTACK_H */