Skip to content

Commit

Permalink
link: sanitizeSymbol: rewrite with no regexp use
Browse files Browse the repository at this point in the history
Instead of using a regular expression in sanitizeSymbol, write a small
for loop to replace any repetitions of unknown characters with a "_".

This removes the last use of regexp from this package.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
  • Loading branch information
kolyshkin committed Apr 27, 2022
1 parent 7f2a37f commit 68f654f
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 16 deletions.
4 changes: 2 additions & 2 deletions link/kprobe.go
Expand Up @@ -429,7 +429,7 @@ func createTraceFSProbeEvent(typ probeType, args probeArgs) error {
// the eBPF program itself.
// See Documentation/kprobes.txt for more details.
token = kprobeToken(args)
pe = fmt.Sprintf("%s:%s/%s %s", probePrefix(args.ret), args.group, sanitizedSymbol(args.symbol), token)
pe = fmt.Sprintf("%s:%s/%s %s", probePrefix(args.ret), args.group, sanitizeSymbol(args.symbol), token)
case uprobeType:
// The uprobe_events syntax is as follows:
// p[:[GRP/]EVENT] PATH:OFFSET [FETCHARGS] : Set a probe
Expand Down Expand Up @@ -481,7 +481,7 @@ func closeTraceFSProbeEvent(typ probeType, group, symbol string) error {

// See [k,u]probe_events syntax above. The probe type does not need to be specified
// for removals.
pe := fmt.Sprintf("-:%s/%s", group, sanitizedSymbol(symbol))
pe := fmt.Sprintf("-:%s/%s", group, sanitizeSymbol(symbol))
if _, err = f.WriteString(pe); err != nil {
return fmt.Errorf("writing '%s' to '%s': %w", pe, typ.EventsPath(), err)
}
Expand Down
2 changes: 1 addition & 1 deletion link/perf_event.go
Expand Up @@ -269,7 +269,7 @@ func unsafeStringPtr(str string) (unsafe.Pointer, error) {
// name automatically has its invalid symbols converted to underscores so the caller
// can pass a raw symbol name, e.g. a kernel symbol containing dots.
func getTraceEventID(group, name string) (uint64, error) {
name = sanitizedSymbol(name)
name = sanitizeSymbol(name)
tid, err := uint64FromFile(tracefsPath, "events", group, name, "id")
if errors.Is(err, os.ErrNotExist) {
return 0, fmt.Errorf("trace event %s/%s: %w", group, name, os.ErrNotExist)
Expand Down
34 changes: 25 additions & 9 deletions link/uprobe.go
Expand Up @@ -6,7 +6,7 @@ import (
"fmt"
"os"
"path/filepath"
"regexp"
"strings"
"sync"

"github.com/cilium/ebpf"
Expand All @@ -16,10 +16,6 @@ import (
var (
uprobeEventsPath = filepath.Join(tracefsPath, "uprobe_events")

// rgxEventSymbol is used to strip invalid characters from the [k,u]probe symbol
// as they are not allowed to be used as the EVENT token in tracefs.
rgxEventSymbol = regexp.MustCompile("[^a-zA-Z0-9]+")

uprobeRetprobeBit = struct {
once sync.Once
value uint64
Expand Down Expand Up @@ -296,7 +292,7 @@ func (ex *Executable) uprobe(symbol string, prog *ebpf.Program, opts *UprobeOpti
}

// Use tracefs if uprobe PMU is missing.
args.symbol = sanitizedSymbol(symbol)
args.symbol = sanitizeSymbol(symbol)
tp, err = tracefsUprobe(args)
if err != nil {
return nil, fmt.Errorf("creating trace event '%s:%s' in tracefs: %w", ex.path, symbol, err)
Expand All @@ -315,9 +311,29 @@ func tracefsUprobe(args probeArgs) (*perfEvent, error) {
return tracefsProbe(uprobeType, args)
}

// sanitizedSymbol replaces every invalid character for the tracefs api with an underscore.
func sanitizedSymbol(symbol string) string {
return rgxEventSymbol.ReplaceAllString(symbol, "_")
// sanitizeSymbol replaces every invalid character for the tracefs api with an underscore.
// It is equivalent to calling regexp.MustCompile("[^a-zA-Z0-9]+").ReplaceAllString("_").
func sanitizeSymbol(s string) string {
var b strings.Builder
b.Grow(len(s))
var skip bool
for _, c := range []byte(s) {
switch {
case c >= 'a' && c <= 'z',
c >= 'A' && c <= 'Z',
c >= '0' && c <= '9':
skip = false
b.WriteByte(c)

default:
if !skip {
b.WriteByte('_')
skip = true
}
}
}

return b.String()
}

// uprobeToken creates the PATH:OFFSET(REF_CTR_OFFSET) token for the tracefs api.
Expand Down
10 changes: 6 additions & 4 deletions link/uprobe_test.go
Expand Up @@ -179,7 +179,7 @@ func TestUprobeTraceFS(t *testing.T) {

// Prepare probe args.
args := probeArgs{
symbol: sanitizedSymbol(bashSym),
symbol: sanitizeSymbol(bashSym),
path: bashEx.path,
offset: off,
pid: perfAllThreads,
Expand Down Expand Up @@ -227,7 +227,7 @@ func TestUprobeCreateTraceFS(t *testing.T) {
c.Assert(err, qt.IsNil)

// Sanitize the symbol in order to be used in tracefs API.
ssym := sanitizedSymbol(bashSym)
ssym := sanitizeSymbol(bashSym)

pg, _ := randomGroup("ebpftest")
rg, _ := randomGroup("ebpftest")
Expand Down Expand Up @@ -280,14 +280,16 @@ func TestUprobeSanitizedSymbol(t *testing.T) {
expected string
}{
{"readline", "readline"},
{"main.Func", "main_Func"},
{"main.Func123", "main_Func123"},
{"a.....a", "a_a"},
{"./;'{}[]a", "_a"},
{"***xx**xx###", "_xx_xx_"},
{`@P#r$i%v^3*+t)i&k++--`, "_P_r_i_v_3_t_i_k_"},
}

for i, tt := range tests {
t.Run(fmt.Sprint(i), func(t *testing.T) {
sanitized := sanitizedSymbol(tt.symbol)
sanitized := sanitizeSymbol(tt.symbol)
if tt.expected != sanitized {
t.Errorf("Expected sanitized symbol to be '%s', got '%s'", tt.expected, sanitized)
}
Expand Down

0 comments on commit 68f654f

Please sign in to comment.