Skip to content

Commit

Permalink
SystemTap: new parser
Browse files Browse the repository at this point in the history
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
  • Loading branch information
masatake committed Jan 8, 2019
1 parent b60a7b9 commit 6bc1a8a
Show file tree
Hide file tree
Showing 19 changed files with 1,587 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Units/parser-systemtap.r/functions.d/args.ctags
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
--sort=no
--fields=+ne
4 changes: 4 additions & 0 deletions Units/parser-systemtap.r/functions.d/expected.tags
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
matched_str input.stp /^function matched_str:string() { return matched(0) }$/;" f line:24 end:24
matched input.stp /^function matched:string(n:long)$/;" f line:39 end:82
ngroups input.stp /^function ngroups:long()$/;" f line:96 end:105
__asmlinkage_int_arg input.stp /^function __asmlinkage_int_arg:long(n:long)$/;" f line:116 end:120
120 changes: 120 additions & 0 deletions Units/parser-systemtap.r/functions.d/input.stp
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#
# Taken from /usr/share/systemtap/tapset/regex.stp and registers.stp
#
// Regular expression subexpression tapset
// Copyright (C) 2017 Serhei Makarov
// Copyright (C) 2013 Red Hat, Inc.
//
// This file is part of systemtap, and is free software. You can
// redistribute it and/or modify it under the terms of the GNU General
// Public License (GPL); either version 2, or (at your option) any
// later version.

%{
#define STAP_NEED_CONTEXT_SUBEXPRESSION 1
%}

/**
* sfunction matched_str - Return the last matched string.
*
* Description: returns the string matched by the last successful
* use of the =~ regexp matching operator. Returns an error if the
* last use of =~ led to a failed match.
*/
function matched_str:string() { return matched(0) }

/**
* sfunction matched - Return a given matched subexpression.
*
* @n: index to the subexpression to return. 0 corresponds to the
* entire regular expression.
*
* Description: returns the content of the n'th subexpression of the
* last successful use of the =~ regex matching operator. Returns an
* empty string if the n'th subexpression was not matched (e.g. due to
* alternation). Throws an error if the last use of =~ was a failed
* match, or if fewer than n subexpressions are present in the
* original regexp.
*/
function matched:string(n:long)
%{ /* pure */ /* unprivileged */ /* pragma:tagged_dfa */
int start_ix, end_ix; // indices into tag buffer
int start, end, length; // actual coordinate values

if (!CONTEXT->last_match.result) {
snprintf(CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer),
"Attempted to get subexpression %lld from failed match", (long long) STAP_ARG_n);
CONTEXT->last_error = CONTEXT->error_buffer;
}

start_ix = 2 * STAP_ARG_n, end_ix = start_ix + 1;

if (end_ix >= CONTEXT->last_match.num_final_tags) {
snprintf(CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer),
"Attempted to get nonexistent subexpression %lld", (long long) STAP_ARG_n);
CONTEXT->last_error = CONTEXT->error_buffer;
}

start = CONTEXT->last_match.tag_vals[start_ix];
end = CONTEXT->last_match.tag_vals[end_ix];
// _stp_printf ("**DEBUG** Extracted subexpression #%lld:(%d,%d) from %d to %d\n", STAP_ARG_n, start_ix, end_ix, start, end);

if (start < 0 || end < 0) {
// If indices are negative, the group was not matched. Return empty string:
start = end = 0;
// snprintf(CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer),
// "Unknown coordinates for subexpression %lld", STAP_ARG_n);
// CONTEXT->last_error = CONTEXT->error_buffer;
}

if (start > end) {
// This should not happen.
snprintf(CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer),
"BUG: inverted coordinates for subexpression %lld", (long long) STAP_ARG_n);
CONTEXT->last_error = CONTEXT->error_buffer;
}

length = end - start;

// TODOXXX assert (start <= strlen(matched_str)) ??
// XXX: Must add 1 to length to account for NUL byte in strlcpy().
strlcpy(STAP_RETVALUE, CONTEXT->last_match.matched_str + start, length + 1);
%}

/**
* sfunction ngroups - Number of subexpressions in the last match.
*
* Description: returns the number of subexpressions from the
* last successful use of the =~ regex matching operator.
*
* Note that this number includes subexpressions which are present in
* the regex but did not match any string; for example, given the
* regex "a|(b)", the subexpressions will count the group for (b)
* regardless of whether it matched a string or not. Throws an error
* if the last use of =~ was a failed match.
*/
function ngroups:long()
%{ /* pure */ /* unprivileged */ /* pragma:tagged_dfa */
if (!CONTEXT->last_match.result) {
snprintf(CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer),
"Attempted to get subexpression count from failed match");
CONTEXT->last_error = CONTEXT->error_buffer;
}

STAP_RETVALUE = CONTEXT->last_match.num_final_tags / 2;
%}

// XXX: perhaps implement matched_start, matched_end to get indices?
// XXX: some kind of find-replace functionality?
// XXX: some kind of splitting / multiple-match functionality?

/*
* In nd_syscall.return probes, we sometimes need @entry() values. To
* ensure we get the argument in the correct mode, we need a function
* that calls asmlinkage() first.
*/
function __asmlinkage_int_arg:long(n:long)
{
asmlinkage()
return int_arg(n)
}
2 changes: 2 additions & 0 deletions Units/parser-systemtap.r/macros.d/args.ctags
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
--sort=no
--fields=+ne
3 changes: 3 additions & 0 deletions Units/parser-systemtap.r/macros.d/expected.tags
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
m0 input.stpm /^@define m0$/;" m line:4 end:7
m1 input.stpm /^@define m1(a0) %($/;" m line:12 end:14
m2 input.stpm /^@define m2(a1,$/;" m line:19 end:22
22 changes: 22 additions & 0 deletions Units/parser-systemtap.r/macros.d/input.stpm
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#
# sharp Comment
#
@define m0
%(
0
%)

/*
* C comment
*/
@define m1(a0) %(
@a0
%)

//
// C++ comment
//
@define m2(a1,
a2) %(
%( @a1 + @a2 %)
%)
2 changes: 2 additions & 0 deletions Units/parser-systemtap.r/probes.d/args.ctags
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
--sort=no
--fields=+ne
38 changes: 38 additions & 0 deletions Units/parser-systemtap.r/probes.d/expected.tags
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
tcp_get_info_rto input.stp /^function tcp_get_info_rto:long(sock:long)$/;" f line:33 end:44
tcp_get_info_snd_cwnd input.stp /^function tcp_get_info_snd_cwnd:long(sock:long)$/;" f line:50 end:60
tcp_ts_get_info_state input.stp /^function tcp_ts_get_info_state:long(sock:long)$/;" f line:78 end:83
__tcp_sock_dport input.stp /^function __tcp_sock_dport:long (sock:long)$/;" f line:86 end:93
__get_skb_tcphdr_new input.stp /^@__private30 function __get_skb_tcphdr_new:long(skb:long)$/;" f line:96 end:107
__get_skb_tcphdr input.stp /^function __get_skb_tcphdr:long(skb:long)$/;" f line:110 end:118
__tcp_skb_urg input.stp /^function __tcp_skb_urg:long (tcphdr:long)$/;" f line:121 end:124
__tcp_skb_ack input.stp /^function __tcp_skb_ack:long (tcphdr:long)$/;" f line:127 end:130
__tcp_skb_psh input.stp /^function __tcp_skb_psh:long (tcphdr:long)$/;" f line:133 end:136
__tcp_skb_rst input.stp /^function __tcp_skb_rst:long (tcphdr:long)$/;" f line:139 end:142
__tcp_skb_syn input.stp /^function __tcp_skb_syn:long (tcphdr:long)$/;" f line:145 end:148
__tcp_skb_fin input.stp /^function __tcp_skb_fin:long (tcphdr:long)$/;" f line:151 end:154
__tcp_skb_sport input.stp /^function __tcp_skb_sport:long (tcphdr:long)$/;" f line:157 end:160
__tcp_skb_dport input.stp /^function __tcp_skb_dport:long (tcphdr:long){$/;" f line:163 end:165
__tcp_sock_sport input.stp /^function __tcp_sock_sport:long (sock:long)$/;" f line:168 end:174
sockstate input.stp /^@__private30 global sockstate[12]$/;" v line:176
tcp_sockstate_str input.stp /^function tcp_sockstate_str:string (state:long) {$/;" f line:192 end:194
tcp_ts_get_info_snd_ssthresh input.stp /^function tcp_ts_get_info_snd_ssthresh:long(sock:long)$/;" f line:199 end:209
tcp_ts_get_info_rcv_mss input.stp /^function tcp_ts_get_info_rcv_mss:long(sock:long)$/;" f line:213 end:224
__sockopt input.stp /^@__private30 global __sockopt[18]$/;" v line:248
tcp_sockopt_str input.stp /^function tcp_sockopt_str:string (optname:long)$/;" f line:281 end:285
__ipv6_sockopt input.stp /^@__private30 global __ipv6_sockopt[55]$/;" v line:349
tcp_ipv6_sockopt_str input.stp /^function tcp_ipv6_sockopt_str:string (optname:long)$/;" f line:467 end:471
tcp.sendmsg input.stp /^probe tcp.sendmsg = kernel.function("tcp_sendmsg") {$/;" p line:483 end:488
tcp.sendmsg.return input.stp /^probe tcp.sendmsg.return = kernel.function("tcp_sendmsg").return {$/;" p line:498 end:501
tcp.recvmsg input.stp /^probe tcp.recvmsg = kernel.function("tcp_recvmsg") {$/;" p line:516 end:525
tcp.recvmsg.return input.stp /^probe tcp.recvmsg.return = kernel.function("tcp_recvmsg").return {$/;" p line:540 end:548
tcp.disconnect input.stp /^probe tcp.disconnect = kernel.function("tcp_disconnect") {$/;" p line:564 end:573
tcp.disconnect.return input.stp /^probe tcp.disconnect.return = kernel.function("tcp_disconnect").return {$/;" p line:583 end:586
tcp.setsockopt input.stp /^probe tcp.setsockopt = tcp.ipv4.setsockopt, tcp.ipv6.setsockopt$/;" p line:601 end:603
tcp.ipv4.setsockopt input.stp /^probe tcp.ipv4.setsockopt = kernel.function("tcp_setsockopt")$/;" p line:604 end:613
tcp.ipv6.setsockopt input.stp /^probe tcp.ipv6.setsockopt = kernel.function("ipv6_setsockopt")!,$/;" p line:614 end:624
tcp.setsockopt.return input.stp /^probe tcp.setsockopt.return = tcp.ipv4.setsockopt.return,$/;" p line:634 end:637
tcp.ipv4.setsockopt.return input.stp /^probe tcp.ipv4.setsockopt.return = kernel.function("tcp_setsockopt").return$/;" p line:638 end:642
tcp.ipv6.setsockopt.return input.stp /^probe tcp.ipv6.setsockopt.return = kernel.function("ipv6_setsockopt").return!,$/;" p line:643 end:648
tcp.receive input.stp /^probe tcp.receive = tcp.ipv4.receive, tcp.ipv6.receive$/;" p line:667 end:669
tcp.ipv4.receive input.stp /^probe tcp.ipv4.receive = kernel.function("tcp_v4_rcv")$/;" p line:671 end:694
tcp.ipv6.receive input.stp /^probe tcp.ipv6.receive = kernel.function("tcp_v6_rcv")!,$/;" p line:696 end:730
Loading

0 comments on commit 6bc1a8a

Please sign in to comment.