Skip to content

Commit a166f61

Browse files
committed
libbpf-tools/trace_helpers: Add a utility to split and convert string
Add a utility API to split and convert strings for argument parsing. Also, apply the API usage to offcputime and profile to remove duplicates.
1 parent 3dd4672 commit a166f61

File tree

4 files changed

+62
-46
lines changed

4 files changed

+62
-46
lines changed

libbpf-tools/offcputime.c

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -80,27 +80,6 @@ static const struct argp_option opts[] = {
8080
{},
8181
};
8282

83-
static int split_pidstr(char *s, char* delim, int max_split, pid_t *pids)
84-
{
85-
char *pid;
86-
int nr = 0;
87-
88-
errno = 0;
89-
pid = strtok(s, delim);
90-
while (pid) {
91-
if (nr >= max_split)
92-
return -ENOBUFS;
93-
94-
pids[nr++] = strtol(pid, NULL, 10);
95-
if (errno)
96-
return -errno;
97-
98-
pid = strtok(NULL, delim);
99-
}
100-
101-
return 0;
102-
}
103-
10483
static error_t parse_arg(int key, char *arg, struct argp_state *state)
10584
{
10685
static int pos_args;
@@ -114,7 +93,8 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state)
11493
env.verbose = true;
11594
break;
11695
case 'p':
117-
ret = split_pidstr(strdup(arg), ",", MAX_PID_NR, env.pids);
96+
ret = split_convert(strdup(arg), ",", env.pids, sizeof(env.pids),
97+
sizeof(pid_t), str_to_int);
11898
if (ret) {
11999
if (ret == -ENOBUFS)
120100
fprintf(stderr, "the number of pid is too big, please "
@@ -126,7 +106,8 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state)
126106
}
127107
break;
128108
case 't':
129-
ret = split_pidstr(strdup(arg), ",", MAX_TID_NR, env.tids);
109+
ret = split_convert(strdup(arg), ",", env.tids, sizeof(env.tids),
110+
sizeof(pid_t), str_to_int);
130111
if (ret) {
131112
if (ret == -ENOBUFS)
132113
fprintf(stderr, "the number of tid is too big, please "

libbpf-tools/profile.c

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -132,27 +132,6 @@ struct syms_cache *syms_cache;
132132
struct syms *syms;
133133
static char syminfo[SYM_INFO_LEN];
134134

135-
static int split_pidstr(char *s, char* sep, int max_split, pid_t *pids)
136-
{
137-
char *pid;
138-
int nr = 0;
139-
140-
errno = 0;
141-
pid = strtok(s, sep);
142-
while (pid) {
143-
if (nr >= max_split)
144-
return -ENOBUFS;
145-
146-
pids[nr++] = strtol(pid, NULL, 10);
147-
if (errno)
148-
return -errno;
149-
150-
pid = strtok(NULL, ",");
151-
}
152-
153-
return 0;
154-
}
155-
156135
static error_t parse_arg(int key, char *arg, struct argp_state *state)
157136
{
158137
static int pos_args;
@@ -166,7 +145,8 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state)
166145
env.verbose = true;
167146
break;
168147
case 'p':
169-
ret = split_pidstr(strdup(arg), ",", MAX_PID_NR, env.pids);
148+
ret = split_convert(strdup(arg), ",", env.pids, sizeof(env.pids),
149+
sizeof(pid_t), str_to_int);
170150
if (ret) {
171151
if (ret == -ENOBUFS)
172152
fprintf(stderr, "the number of pid is too big, please "
@@ -178,7 +158,8 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state)
178158
}
179159
break;
180160
case 'L':
181-
ret = split_pidstr(strdup(arg), ",", MAX_TID_NR, env.tids);
161+
ret = split_convert(strdup(arg), ",", env.tids, sizeof(env.tids),
162+
sizeof(pid_t), str_to_int);
182163
if (ret) {
183164
if (ret == -ENOBUFS)
184165
fprintf(stderr, "the number of tid is too big, please "

libbpf-tools/trace_helpers.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,3 +1247,45 @@ bool probe_ringbuf()
12471247
close(map_fd);
12481248
return true;
12491249
}
1250+
1251+
int split_convert(char *s, const char* delim, void *elems, size_t elems_size,
1252+
size_t elem_size, convert_fn_t convert)
1253+
{
1254+
char *token;
1255+
int ret;
1256+
char *pos = (char *)elems;
1257+
1258+
if (!s || !delim || !elems)
1259+
return -EINVAL;
1260+
1261+
token = strtok(s, delim);
1262+
while (token) {
1263+
if (pos + elem_size > (char*)elems + elems_size)
1264+
return -ENOBUFS;
1265+
1266+
ret = convert(token, pos);
1267+
if (ret)
1268+
return -ret;
1269+
1270+
pos += elem_size;
1271+
token = strtok(NULL, delim);
1272+
}
1273+
1274+
return 0;
1275+
}
1276+
1277+
int str_to_int(const char *src, void *dest)
1278+
{
1279+
errno = 0;
1280+
*(int*)dest = strtol(src, NULL, 10);
1281+
1282+
return errno;
1283+
}
1284+
1285+
int str_to_long(const char *src, void *dest)
1286+
{
1287+
errno = 0;
1288+
*(long*)dest = strtol(src, NULL, 10);
1289+
1290+
return errno;
1291+
}

libbpf-tools/trace_helpers.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,4 +108,16 @@ bool module_btf_exists(const char *mod);
108108
bool probe_tp_btf(const char *name);
109109
bool probe_ringbuf();
110110

111+
typedef int (*convert_fn_t)(const char *src, void *dest);
112+
int split_convert(char *s, const char* delim, void *elems, size_t elems_size,
113+
size_t elem_size, convert_fn_t convert);
114+
/*
115+
* Implementations of convert_fn_t.
116+
* This can be replaced with a user-defined callback function.
117+
*/
118+
/* converts a string to an integer */
119+
int str_to_int(const char *src, void *dest);
120+
/* converts a string to a long integer */
121+
int str_to_long(const char *src, void *dest);
122+
111123
#endif /* __TRACE_HELPERS_H */

0 commit comments

Comments
 (0)