Skip to content

Commit

Permalink
internal: recognize register based errors from the verifier
Browse files Browse the repository at this point in the history
The verifier has a bunch of places where it bails out due to register state
not being what it expects:

    λ  linux master ✓ grep -E "verbose\(env, \"R" kernel/bpf/verifier.c | wc -l
    60

These errors are difficult to understand without additional context. Include the
previous line of log output if we encounter one of these.
  • Loading branch information
lmb committed Jun 14, 2022
1 parent f0c26fd commit c722347
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 6 deletions.
30 changes: 24 additions & 6 deletions internal/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,8 @@ func (le *VerifierError) Error() string {
}

lines := log[n-1:]
if n >= 2 && (strings.HasPrefix(log[n-1], "\t") || le.Truncated) {
// Add one more line of context if the last line starts with a tab,
// or if it has been truncated.
// For example:
// [13] STRUCT drm_rect size=16 vlen=4
// \tx1 type_id=2
if n >= 2 && (includePreviousLine(log[n-1]) || le.Truncated) {
// Add one more line of context if it aids understanding the error.
lines = log[n-2:]
}

Expand Down Expand Up @@ -113,6 +109,28 @@ func (le *VerifierError) Error() string {
return b.String()
}

// includePreviousLine returns true if the given line likely is better
// understood with additional context from the preceding line.
func includePreviousLine(line string) bool {
// We need to find a good trade off between understandable error messages
// and too much complexity here. Checking the string prefix is ok, requiring
// regular expressions to do it is probably overkill.

if strings.HasPrefix(line, "\t") {
// [13] STRUCT drm_rect size=16 vlen=4
// \tx1 type_id=2
return true
}

if len(line) >= 2 && line[0] == 'R' && line[1] >= '0' && line[1] <= '9' {
// 0: (95) exit
// R0 !read_ok
return true
}

return false
}

// Format the error.
//
// Understood verbs are %s and %v, which are equivalent to calling Error(). %v
Expand Down
4 changes: 4 additions & 0 deletions internal/errors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ func TestVerifierError(t *testing.T) {
t.Log(truncated)
qt.Assert(t, truncated.Truncated, qt.IsTrue)
qt.Assert(t, truncated.Error(), qt.Contains, "str_off: 3166088: str_len: 228")

invalidR0 := readErrorFromFile(t, "testdata/invalid-R0.log")
t.Log(invalidR0)
qt.Assert(t, invalidR0.Error(), qt.Contains, "0: (95) exit: R0 !read_ok")
}

func ExampleVerifierError() {
Expand Down
Binary file added internal/testdata/invalid-R0.log
Binary file not shown.

0 comments on commit c722347

Please sign in to comment.