1- // SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
2- // Copyright (c) 2021 Hengqi Chen
3- //
4- // Based on gethostlatency(8) from BCC by Brendan Gregg.
5- // 24-Mar-2021 Hengqi Chen Created this.
1+ /* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
2+
3+ /*
4+ * gethostlatency Show latency for getaddrinfo/gethostbyname[2] calls.
5+ *
6+ * Copyright (c) 2021 Hengqi Chen
7+ *
8+ * Based on gethostlatency(8) from BCC by Brendan Gregg.
9+ * 24-Mar-2021 Hengqi Chen Created this.
10+ */
611#include <argp.h>
712#include <errno.h>
813#include <signal.h>
1520#include "trace_helpers.h"
1621#include "uprobe_helpers.h"
1722
18- #define PERF_BUFFER_PAGES 16
19- #define PERF_POLL_TIMEOUT_MS 100
23+ #define PERF_BUFFER_PAGES 16
24+ #define PERF_POLL_TIMEOUT_MS 100
2025#define warn (...) fprintf(stderr, __VA_ARGS__)
2126
2227static volatile sig_atomic_t exiting = 0 ;
23- static pid_t traced_pid = 0 ;
28+ static pid_t target_pid = 0 ;
2429
2530const char * argp_program_version = "gethostlatency 0.1" ;
2631const char * argp_program_bug_address =
@@ -52,7 +57,7 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state)
5257 warn ("Invalid PID: %s\n" , arg );
5358 argp_usage (state );
5459 }
55- traced_pid = pid ;
60+ target_pid = pid ;
5661 break ;
5762 case 'h' :
5863 argp_state_help (state , stderr , ARGP_HELP_STD_HELP );
@@ -68,33 +73,18 @@ static void sig_int(int signo)
6873 exiting = 1 ;
6974}
7075
71- static const char * strftime_now ( char * s , size_t max , const char * format )
76+ static void handle_event ( void * ctx , int cpu , void * data , __u32 data_sz )
7277{
78+ const struct event * e = data ;
7379 struct tm * tm ;
80+ char ts [16 ];
7481 time_t t ;
7582
76- t = time (NULL );
83+ time (& t );
7784 tm = localtime (& t );
78- if (tm == NULL ) {
79- warn ("localtime: %s\n" , strerror (errno ));
80- return "<failed>" ;
81- }
82- if (strftime (s , max , format , tm ) == 0 ) {
83- warn ("strftime error\n" );
84- return "<failed>" ;
85- }
86- return s ;
87- }
88-
89- static void handle_event (void * ctx , int cpu , void * data , __u32 data_sz )
90- {
91- const struct val_t * e = data ;
92- char s [16 ] = {};
93- const char * now ;
94-
95- now = strftime_now (s , sizeof (s ), "%H:%M:%S" );
96- printf ("%-11s %-10d %-20s %-10.2f %-16s\n" ,
97- now , e -> pid , e -> comm , (double )e -> time /1000000 , e -> host );
85+ strftime (ts , sizeof (ts ), "%H:%M:%S" , tm );
86+ printf ("%-8s %-7d %-16s %-10.3f %-s\n" ,
87+ ts , e -> pid , e -> comm , (double )e -> time /1000000 , e -> host );
9888}
9989
10090static void handle_lost_events (void * ctx , int cpu , __u64 lost_cnt )
@@ -105,19 +95,17 @@ static void handle_lost_events(void *ctx, int cpu, __u64 lost_cnt)
10595static int get_libc_path (char * path )
10696{
10797 FILE * f ;
108- char buf [256 ] = {};
98+ char buf [PATH_MAX ] = {};
10999 char * filename ;
110100 float version ;
111101
112102 f = fopen ("/proc/self/maps" , "r" );
113- if (!f ) {
103+ if (!f )
114104 return - errno ;
115- }
116105
117106 while (fscanf (f , "%*x-%*x %*s %*s %*s %*s %[^\n]\n" , buf ) != EOF ) {
118- if (strchr (buf , '/' ) != buf ) {
107+ if (strchr (buf , '/' ) != buf )
119108 continue ;
120- }
121109 filename = strrchr (buf , '/' ) + 1 ;
122110 if (sscanf (filename , "libc-%f.so" , & version ) == 1 ) {
123111 memcpy (path , buf , strlen (buf ));
@@ -149,15 +137,15 @@ static int attach_uprobes(struct gethostlatency_bpf *obj)
149137 }
150138 obj -> links .handle_entry =
151139 bpf_program__attach_uprobe (obj -> progs .handle_entry , false,
152- traced_pid ?: -1 , libc_path , func_off );
140+ target_pid ?: -1 , libc_path , func_off );
153141 err = libbpf_get_error (obj -> links .handle_entry );
154142 if (err ) {
155143 warn ("failed to attach getaddrinfo: %d\n" , err );
156144 return -1 ;
157145 }
158146 obj -> links .handle_return =
159147 bpf_program__attach_uprobe (obj -> progs .handle_return , true,
160- traced_pid ?: -1 , libc_path , func_off );
148+ target_pid ?: -1 , libc_path , func_off );
161149 err = libbpf_get_error (obj -> links .handle_return );
162150 if (err ) {
163151 warn ("failed to attach getaddrinfo: %d\n" , err );
@@ -166,20 +154,20 @@ static int attach_uprobes(struct gethostlatency_bpf *obj)
166154
167155 func_off = get_elf_func_offset (libc_path , "gethostbyname" );
168156 if (func_off < 0 ) {
169- warn ("Could not find gethostbyname in %s\n" , libc_path );
157+ warn ("could not find gethostbyname in %s\n" , libc_path );
170158 return -1 ;
171159 }
172160 obj -> links .handle_entry =
173161 bpf_program__attach_uprobe (obj -> progs .handle_entry , false,
174- traced_pid ?: -1 , libc_path , func_off );
162+ target_pid ?: -1 , libc_path , func_off );
175163 err = libbpf_get_error (obj -> links .handle_entry );
176164 if (err ) {
177165 warn ("failed to attach gethostbyname: %d\n" , err );
178166 return -1 ;
179167 }
180168 obj -> links .handle_return =
181169 bpf_program__attach_uprobe (obj -> progs .handle_return , true,
182- traced_pid ?: -1 , libc_path , func_off );
170+ target_pid ?: -1 , libc_path , func_off );
183171 err = libbpf_get_error (obj -> links .handle_return );
184172 if (err ) {
185173 warn ("failed to attach gethostbyname: %d\n" , err );
@@ -188,20 +176,20 @@ static int attach_uprobes(struct gethostlatency_bpf *obj)
188176
189177 func_off = get_elf_func_offset (libc_path , "gethostbyname2" );
190178 if (func_off < 0 ) {
191- warn ("Could not find gethostbyname2 in %s\n" , libc_path );
179+ warn ("could not find gethostbyname2 in %s\n" , libc_path );
192180 return -1 ;
193181 }
194182 obj -> links .handle_entry =
195183 bpf_program__attach_uprobe (obj -> progs .handle_entry , false,
196- traced_pid ?: -1 , libc_path , func_off );
184+ target_pid ?: -1 , libc_path , func_off );
197185 err = libbpf_get_error (obj -> links .handle_entry );
198186 if (err ) {
199187 warn ("failed to attach gethostbyname2: %d\n" , err );
200188 return -1 ;
201189 }
202190 obj -> links .handle_return =
203191 bpf_program__attach_uprobe (obj -> progs .handle_return , true,
204- traced_pid ?: -1 , libc_path , func_off );
192+ target_pid ?: -1 , libc_path , func_off );
205193 err = libbpf_get_error (obj -> links .handle_return );
206194 if (err ) {
207195 warn ("failed to attach gethostbyname2: %d\n" , err );
@@ -239,7 +227,7 @@ int main(int argc, char **argv)
239227 return 1 ;
240228 }
241229
242- obj -> rodata -> targ_tgid = traced_pid ;
230+ obj -> rodata -> target_pid = target_pid ;
243231
244232 err = gethostlatency_bpf__load (obj );
245233 if (err ) {
@@ -248,9 +236,8 @@ int main(int argc, char **argv)
248236 }
249237
250238 err = attach_uprobes (obj );
251- if (err ) {
239+ if (err )
252240 goto cleanup ;
253- }
254241
255242 pb_opts .sample_cb = handle_event ;
256243 pb_opts .lost_cb = handle_lost_events ;
@@ -267,8 +254,8 @@ int main(int argc, char **argv)
267254 goto cleanup ;
268255 }
269256
270- printf ("%-11s %-10s %-20s %-10s %-16s \n" ,
271- "TIME" , "PID" , "COMM" , "LATms" , "HOST" );
257+ printf ("%-8s %-7s %-16s %-10s %-s \n" ,
258+ "TIME" , "PID" , "COMM" , "LATms" , "HOST" );
272259
273260 while (1 ) {
274261 if ((err = perf_buffer__poll (pb , PERF_POLL_TIMEOUT_MS )) < 0 )
@@ -279,6 +266,7 @@ int main(int argc, char **argv)
279266 warn ("error polling perf buffer: %d\n" , err );
280267
281268cleanup :
269+ perf_buffer__free (pb );
282270 gethostlatency_bpf__destroy (obj );
283271
284272 return err != 0 ;
0 commit comments