mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-15 10:24:44 +08:00
f3cf7fa963
That helps us not to lose new protocol families when they are introduced, replacing that hardcoded, dated family->string table. To recap what this allows us to do: # perf trace -e syscalls:sys_enter_socket/max-stack=10/ --filter=family==INET --max-events=1 0.000 fetchmail/41097 syscalls:sys_enter_socket(family: INET, type: DGRAM|CLOEXEC|NONBLOCK, protocol: IP) __GI___socket (inlined) reopen (/usr/lib64/libresolv-2.31.so) send_dg (/usr/lib64/libresolv-2.31.so) __res_context_send (/usr/lib64/libresolv-2.31.so) __GI___res_context_query (inlined) __GI___res_context_search (inlined) _nss_dns_gethostbyname4_r (/usr/lib64/libnss_dns-2.31.so) gaih_inet.constprop.0 (/usr/lib64/libc-2.31.so) __GI_getaddrinfo (inlined) [0x15cb2] (/usr/bin/fetchmail) # More work is still needed to allow for the more natura strace-like syscall name usage instead of the trace event name: # perf trace -e socket/max-stack=10,family==INET/ --max-events=1 I.e. to allow for modifiers to follow the syscall name and for logical expressions to be accepted as filters to use with that syscall, be it as trace event filters or BPF based ones. Using -v we can see how the trace event filter is built: # perf trace -v -e syscalls:sys_enter_socket/call-graph=dwarf/ --filter=family==INET --max-events=2 <SNIP> New filter for syscalls:sys_enter_socket: (family==0x2) && (common_pid != 41384 && common_pid != 2836) <SNIP> $ tools/perf/trace/beauty/socket.sh | grep -w 2 [2] = "INET", $ Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
70 lines
2.4 KiB
C
70 lines
2.4 KiB
C
// SPDX-License-Identifier: LGPL-2.1
|
|
// Copyright (C) 2018, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
|
|
#include "trace/beauty/beauty.h"
|
|
#include <sys/socket.h>
|
|
#include <sys/types.h>
|
|
#include <sys/un.h>
|
|
#include <arpa/inet.h>
|
|
|
|
#include "trace/beauty/generated/socket_arrays.c"
|
|
DEFINE_STRARRAY(socket_families, "PF_");
|
|
|
|
static size_t af_inet__scnprintf(struct sockaddr *sa, char *bf, size_t size)
|
|
{
|
|
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
|
|
char tmp[16];
|
|
return scnprintf(bf, size, ", port: %d, addr: %s", ntohs(sin->sin_port),
|
|
inet_ntop(sin->sin_family, &sin->sin_addr, tmp, sizeof(tmp)));
|
|
}
|
|
|
|
static size_t af_inet6__scnprintf(struct sockaddr *sa, char *bf, size_t size)
|
|
{
|
|
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
|
|
u32 flowinfo = ntohl(sin6->sin6_flowinfo);
|
|
char tmp[512];
|
|
size_t printed = scnprintf(bf, size, ", port: %d, addr: %s", ntohs(sin6->sin6_port),
|
|
inet_ntop(sin6->sin6_family, &sin6->sin6_addr, tmp, sizeof(tmp)));
|
|
if (flowinfo != 0)
|
|
printed += scnprintf(bf + printed, size - printed, ", flowinfo: %lu", flowinfo);
|
|
if (sin6->sin6_scope_id != 0)
|
|
printed += scnprintf(bf + printed, size - printed, ", scope_id: %lu", sin6->sin6_scope_id);
|
|
|
|
return printed;
|
|
}
|
|
|
|
static size_t af_local__scnprintf(struct sockaddr *sa, char *bf, size_t size)
|
|
{
|
|
struct sockaddr_un *sun = (struct sockaddr_un *)sa;
|
|
return scnprintf(bf, size, ", path: %s", sun->sun_path);
|
|
}
|
|
|
|
static size_t (*af_scnprintfs[])(struct sockaddr *sa, char *bf, size_t size) = {
|
|
[AF_LOCAL] = af_local__scnprintf,
|
|
[AF_INET] = af_inet__scnprintf,
|
|
[AF_INET6] = af_inet6__scnprintf,
|
|
};
|
|
|
|
static size_t syscall_arg__scnprintf_augmented_sockaddr(struct syscall_arg *arg, char *bf, size_t size)
|
|
{
|
|
struct sockaddr *sa = (struct sockaddr *)arg->augmented.args;
|
|
char family[32];
|
|
size_t printed;
|
|
|
|
strarray__scnprintf(&strarray__socket_families, family, sizeof(family), "%d", arg->show_string_prefix, sa->sa_family);
|
|
printed = scnprintf(bf, size, "{ .family: %s", family);
|
|
|
|
if (sa->sa_family < ARRAY_SIZE(af_scnprintfs) && af_scnprintfs[sa->sa_family])
|
|
printed += af_scnprintfs[sa->sa_family](sa, bf + printed, size - printed);
|
|
|
|
return printed + scnprintf(bf + printed, size - printed, " }");
|
|
}
|
|
|
|
size_t syscall_arg__scnprintf_sockaddr(char *bf, size_t size, struct syscall_arg *arg)
|
|
{
|
|
if (arg->augmented.args)
|
|
return syscall_arg__scnprintf_augmented_sockaddr(arg, bf, size);
|
|
|
|
return scnprintf(bf, size, "%#lx", arg->val);
|
|
}
|