summaryrefslogtreecommitdiff
path: root/internal/generate
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-13 20:04:48 +0300
committerPaul Buetow <paul@buetow.org>2026-05-13 20:04:48 +0300
commit251894cf3375812564ecf28392179b395cdda9c7 (patch)
tree83c3609ab591702e29a375923670e7622a33b5c7 /internal/generate
parent78ea9e22e596255c5e23ce445d80641870674ca9 (diff)
refactor: break down functions exceeding 50 lines into smaller helpers
Split 22 production files across the codebase — event loop, TUI models, probe manager, dashboard, export, flag parsing, code generation, and ioworkload scenarios — so that no function body exceeds 50 lines. Each extracted helper carries its own comment explaining its role. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'internal/generate')
-rw-r--r--internal/generate/bpfhandler.go120
-rw-r--r--internal/generate/format.go84
2 files changed, 114 insertions, 90 deletions
diff --git a/internal/generate/bpfhandler.go b/internal/generate/bpfhandler.go
index cf9a0c9..549e80b 100644
--- a/internal/generate/bpfhandler.go
+++ b/internal/generate/bpfhandler.go
@@ -62,77 +62,93 @@ func renderHandler(name, ctxStruct, eventStruct, comment, eventTypeConst, extra
return b.String()
}
+// generateExtra returns the kind-specific C body lines for a tracepoint handler,
+// dispatching to a per-kind helper so that each case stays concise.
func generateExtra(tp GeneratedTracepoint, isEnter bool) string {
f := tp.Format
-
switch tp.Classification.Kind {
case KindFd:
- if f.Name == "sys_enter_pidfd_getfd" {
- return " ev->fd = (__s32)ctx->args[0];\n"
- }
- fdIdx := f.FieldNumber("fd")
- if fdIdx >= 0 {
- return fmt.Sprintf(" ev->fd = (__s32)ctx->args[%d];\n", fdIdx)
- }
- return " ev->fd = (__s32)ctx->args[0];\n"
-
+ return generateExtraFd(f)
case KindDup3:
return " ev->fd = (__s32)ctx->args[0];\n ev->flags = (__s32)ctx->args[2];\n"
-
case KindOpenByHandleAt:
return " ev->flags = (__s32)ctx->args[2];\n"
-
case KindOpen:
- filenameIdx := f.FieldNumber("filename")
- flagsIdx := f.FieldNumber("flags")
- var b strings.Builder
- b.WriteString(" __builtin_memset(&(ev->filename), 0, sizeof(ev->filename) + sizeof(ev->comm));\n")
- fmt.Fprintf(&b, " bpf_probe_read_user_str(ev->filename, sizeof(ev->filename), (void *)ctx->args[%d]);\n", filenameIdx)
- b.WriteString(" bpf_get_current_comm(&ev->comm, sizeof(ev->comm));\n")
- if flagsIdx > -1 {
- fmt.Fprintf(&b, " ev->flags = ctx->args[%d];\n", flagsIdx)
- } else {
- b.WriteString(" ev->flags = -1; // Probably OK\n")
- }
- return b.String()
-
+ return generateExtraOpen(f)
case KindPathname:
- fieldName := tp.Classification.PathnameField
- fieldIdx := f.FieldNumber(fieldName)
- var b strings.Builder
- b.WriteString(" __builtin_memset(&(ev->pathname), 0, sizeof(ev->pathname));\n")
- fmt.Fprintf(&b, " bpf_probe_read_user_str(ev->pathname, sizeof(ev->pathname), (void*)ctx->args[%d]);\n", fieldIdx)
- return b.String()
-
+ return generateExtraPathname(tp, f)
case KindName:
- oldIdx := f.FieldNumber("oldname")
- newIdx := f.FieldNumber("newname")
- var b strings.Builder
- b.WriteString(" __builtin_memset(&(ev->oldname), 0, sizeof(ev->oldname) + sizeof(ev->newname));\n")
- fmt.Fprintf(&b, " bpf_probe_read_user_str(ev->oldname, sizeof(ev->oldname), (void*)ctx->args[%d]);\n", oldIdx)
- fmt.Fprintf(&b, " bpf_probe_read_user_str(ev->newname, sizeof(ev->newname), (void*)ctx->args[%d]);\n", newIdx)
- return b.String()
-
+ return generateExtraName(f)
case KindFcntl:
- fdIdx := f.FieldNumber("fd")
- cmdIdx := f.FieldNumber("cmd")
- argIdx := f.FieldNumber("arg")
- return fmt.Sprintf(
- " ev->fd = ctx->args[%d];\n ev->cmd = ctx->args[%d];\n ev->arg = ctx->args[%d];\n",
- fdIdx, cmdIdx, argIdx,
- )
-
+ return generateExtraFcntl(f)
case KindRet:
- classification := ClassifyRet(f.Name)
- return fmt.Sprintf(" ev->ret = ctx->ret;\n ev->ret_type = %s;\n", classification)
-
+ return fmt.Sprintf(" ev->ret = ctx->ret;\n ev->ret_type = %s;\n", ClassifyRet(f.Name))
case KindNull:
return ""
}
-
return ""
}
+// generateExtraFd returns the fd-capture lines for fd-family events.
+func generateExtraFd(f *Format) string {
+ if f.Name == "sys_enter_pidfd_getfd" {
+ return " ev->fd = (__s32)ctx->args[0];\n"
+ }
+ fdIdx := f.FieldNumber("fd")
+ if fdIdx >= 0 {
+ return fmt.Sprintf(" ev->fd = (__s32)ctx->args[%d];\n", fdIdx)
+ }
+ return " ev->fd = (__s32)ctx->args[0];\n"
+}
+
+// generateExtraOpen returns the filename/comm/flags capture lines for open-family events.
+func generateExtraOpen(f *Format) string {
+ filenameIdx := f.FieldNumber("filename")
+ flagsIdx := f.FieldNumber("flags")
+ var b strings.Builder
+ b.WriteString(" __builtin_memset(&(ev->filename), 0, sizeof(ev->filename) + sizeof(ev->comm));\n")
+ fmt.Fprintf(&b, " bpf_probe_read_user_str(ev->filename, sizeof(ev->filename), (void *)ctx->args[%d]);\n", filenameIdx)
+ b.WriteString(" bpf_get_current_comm(&ev->comm, sizeof(ev->comm));\n")
+ if flagsIdx > -1 {
+ fmt.Fprintf(&b, " ev->flags = ctx->args[%d];\n", flagsIdx)
+ } else {
+ b.WriteString(" ev->flags = -1; // Probably OK\n")
+ }
+ return b.String()
+}
+
+// generateExtraPathname returns the pathname capture lines for path-family events.
+func generateExtraPathname(tp GeneratedTracepoint, f *Format) string {
+ fieldName := tp.Classification.PathnameField
+ fieldIdx := f.FieldNumber(fieldName)
+ var b strings.Builder
+ b.WriteString(" __builtin_memset(&(ev->pathname), 0, sizeof(ev->pathname));\n")
+ fmt.Fprintf(&b, " bpf_probe_read_user_str(ev->pathname, sizeof(ev->pathname), (void*)ctx->args[%d]);\n", fieldIdx)
+ return b.String()
+}
+
+// generateExtraName returns the oldname/newname capture lines for rename/link-family events.
+func generateExtraName(f *Format) string {
+ oldIdx := f.FieldNumber("oldname")
+ newIdx := f.FieldNumber("newname")
+ var b strings.Builder
+ b.WriteString(" __builtin_memset(&(ev->oldname), 0, sizeof(ev->oldname) + sizeof(ev->newname));\n")
+ fmt.Fprintf(&b, " bpf_probe_read_user_str(ev->oldname, sizeof(ev->oldname), (void*)ctx->args[%d]);\n", oldIdx)
+ fmt.Fprintf(&b, " bpf_probe_read_user_str(ev->newname, sizeof(ev->newname), (void*)ctx->args[%d]);\n", newIdx)
+ return b.String()
+}
+
+// generateExtraFcntl returns the fd/cmd/arg capture lines for fcntl events.
+func generateExtraFcntl(f *Format) string {
+ fdIdx := f.FieldNumber("fd")
+ cmdIdx := f.FieldNumber("cmd")
+ argIdx := f.FieldNumber("arg")
+ return fmt.Sprintf(
+ " ev->fd = ctx->args[%d];\n ev->cmd = ctx->args[%d];\n ev->arg = ctx->args[%d];\n",
+ fdIdx, cmdIdx, argIdx,
+ )
+}
+
// eventStructName returns the C struct name for a TracepointKind. The mapping
// is driven by kindRegistry so adding a new kind only requires a registry entry.
func eventStructName(kind TracepointKind) string {
diff --git a/internal/generate/format.go b/internal/generate/format.go
index ea579b6..ef51ba8 100644
--- a/internal/generate/format.go
+++ b/internal/generate/format.go
@@ -44,52 +44,60 @@ func ParseFormats(r io.Reader) ([]Format, error) {
isExternal := false
for scanner.Scan() {
- line := scanner.Text()
- trimmed := strings.TrimSpace(line)
-
- switch {
- case strings.HasPrefix(trimmed, "name:"):
- f := Format{}
- f.Name = strings.TrimSpace(strings.TrimPrefix(trimmed, "name:"))
- formats = append(formats, f)
- current = &formats[len(formats)-1]
- isExternal = false
-
- case strings.HasPrefix(trimmed, "ID:"):
- if current == nil {
- return nil, fmt.Errorf("ID without name")
- }
- id, err := strconv.Atoi(strings.TrimSpace(strings.TrimPrefix(trimmed, "ID:")))
- if err != nil {
- return nil, fmt.Errorf("parsing ID: %w", err)
- }
- current.ID = id
-
- case strings.HasPrefix(trimmed, "field:"):
- if current == nil {
- return nil, fmt.Errorf("field without name")
- }
- field, err := parseField(trimmed)
- if err != nil {
- return nil, fmt.Errorf("parsing field in %s: %w", current.Name, err)
- }
- if field.Name == "__syscall_nr" {
- isExternal = true
- }
- if isExternal {
- current.ExternalFields = append(current.ExternalFields, field)
- } else {
- current.InternalFields = append(current.InternalFields, field)
- }
+ var err error
+ current, isExternal, err = applyFormatLine(scanner.Text(), formats, current, isExternal, &formats)
+ if err != nil {
+ return nil, err
}
}
-
if err := scanner.Err(); err != nil {
return nil, fmt.Errorf("scanning input: %w", err)
}
return formats, nil
}
+// applyFormatLine processes one line from the format file, updating the
+// running parse state (current format, isExternal flag, and formats slice).
+func applyFormatLine(line string, _ []Format, current *Format, isExternal bool, formats *[]Format) (*Format, bool, error) {
+ trimmed := strings.TrimSpace(line)
+ switch {
+ case strings.HasPrefix(trimmed, "name:"):
+ f := Format{}
+ f.Name = strings.TrimSpace(strings.TrimPrefix(trimmed, "name:"))
+ *formats = append(*formats, f)
+ current = &(*formats)[len(*formats)-1]
+ isExternal = false
+
+ case strings.HasPrefix(trimmed, "ID:"):
+ if current == nil {
+ return nil, false, fmt.Errorf("ID without name")
+ }
+ id, err := strconv.Atoi(strings.TrimSpace(strings.TrimPrefix(trimmed, "ID:")))
+ if err != nil {
+ return nil, false, fmt.Errorf("parsing ID: %w", err)
+ }
+ current.ID = id
+
+ case strings.HasPrefix(trimmed, "field:"):
+ if current == nil {
+ return nil, false, fmt.Errorf("field without name")
+ }
+ field, err := parseField(trimmed)
+ if err != nil {
+ return nil, false, fmt.Errorf("parsing field in %s: %w", current.Name, err)
+ }
+ if field.Name == "__syscall_nr" {
+ isExternal = true
+ }
+ if isExternal {
+ current.ExternalFields = append(current.ExternalFields, field)
+ } else {
+ current.InternalFields = append(current.InternalFields, field)
+ }
+ }
+ return current, isExternal, nil
+}
+
func parseField(line string) (Field, error) {
// Format: "field:TYPE NAME; offset:N; size:N; signed:N;"
line = strings.TrimPrefix(line, "field:")