Skip to content

Commit 74df5d2

Browse files
committed
Fix USDT argument parsing for ARM64 bracket syntax with spaces
The CUDA probe arguments on ARM64 use bracket syntax with spaces like '4@[sp, 44]' but our parser was using strings.Fields() which splits on all whitespace. This caused the arguments to be incorrectly split into '4@[sp,' and '44]'. Add a new splitUSDTArgs() function that preserves spaces inside brackets while still splitting arguments on whitespace outside brackets. This correctly handles both x86_64 syntax like '-4@-24(%rbp)' and ARM64 syntax like '4@[sp, 44]'. Also add a test case for ARM64 arguments with spaces in brackets.
1 parent 8f15ae6 commit 74df5d2

File tree

2 files changed

+46
-2
lines changed

2 files changed

+46
-2
lines changed

libpf/pfelf/usdt_args.go

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,17 +280,55 @@ func ParseUSDTArgSpec(argStr string) (*usdt.ArgSpec, error) {
280280
return nil, fmt.Errorf("unrecognized argument format: %s", argStr)
281281
}
282282

283+
// splitUSDTArgs splits a USDT argument string into individual argument specifications.
284+
// Unlike strings.Fields, this preserves spaces inside brackets for ARM64 syntax like "4@[sp, 44]".
285+
func splitUSDTArgs(argString string) []string {
286+
var args []string
287+
var current strings.Builder
288+
inBrackets := false
289+
290+
for _, ch := range argString {
291+
switch ch {
292+
case '[':
293+
inBrackets = true
294+
current.WriteRune(ch)
295+
case ']':
296+
inBrackets = false
297+
current.WriteRune(ch)
298+
case ' ', '\t', '\n', '\r':
299+
if inBrackets {
300+
// Preserve spaces inside brackets
301+
current.WriteRune(ch)
302+
} else if current.Len() > 0 {
303+
// End of argument outside brackets
304+
args = append(args, current.String())
305+
current.Reset()
306+
}
307+
default:
308+
current.WriteRune(ch)
309+
}
310+
}
311+
312+
// Add final argument if any
313+
if current.Len() > 0 {
314+
args = append(args, current.String())
315+
}
316+
317+
return args
318+
}
319+
283320
// ParseUSDTArguments parses a USDT argument specification string into a usdt.Spec.
284321
// The argument string is space-separated (e.g., "-4@%esi -4@-24(%rbp) -4@%ecx").
322+
// For ARM64, brackets can contain spaces (e.g., "4@[sp, 44] 8@[x0, -8]").
285323
func ParseUSDTArguments(argString string) (*usdt.Spec, error) {
286324
argString = strings.TrimSpace(argString)
287325
if argString == "" {
288326
// No arguments is valid
289327
return &usdt.Spec{Arg_cnt: 0}, nil
290328
}
291329

292-
// Split by whitespace
293-
argStrs := strings.Fields(argString)
330+
// Split by whitespace, but preserve spaces inside brackets
331+
argStrs := splitUSDTArgs(argString)
294332
if len(argStrs) > 12 {
295333
return nil, fmt.Errorf("too many arguments: %d (max 12)", len(argStrs))
296334
}

libpf/pfelf/usdt_args_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,12 @@ func TestParseUSDTArguments(t *testing.T) {
431431
expectError: false,
432432
expectedCnt: 4,
433433
},
434+
{
435+
name: "ARM64 brackets with spaces",
436+
argString: "4@[sp, 44] 4@[sp, 16] 8@[sp, 48]",
437+
expectError: false,
438+
expectedCnt: 3,
439+
},
434440
{
435441
name: "too many arguments",
436442
argString: "8@%rax 8@%rbx 8@%rcx 8@%rdx 8@%rsi 8@%rdi " +

0 commit comments

Comments
 (0)