aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTaras Madan <tarasmadan@google.com>2023-07-21 11:51:35 +0200
committerTaras Madan <tarasmadan@google.com>2023-07-24 09:12:13 +0000
commita36fe24b8383f6cd9b3519cd3eabdb9675d8992d (patch)
tree3fef9a57760ccc4013289acd60e94e083db466e6
parent7549a7e1b57831cf6b08ce4700fc6e53417919f9 (diff)
all: use errors.As instead of .(type)
-rw-r--r--dashboard/app/access_test.go5
-rw-r--r--dashboard/app/app_test.go9
-rw-r--r--dashboard/app/bisect_test.go5
-rw-r--r--dashboard/app/handler.go5
-rw-r--r--dashboard/app/reporting_email.go14
-rw-r--r--dashboard/app/reporting_external.go4
-rw-r--r--dashboard/app/util_test.go5
-rw-r--r--pkg/asset/storage.go6
-rw-r--r--pkg/bisect/bisect.go51
-rw-r--r--pkg/build/build.go5
-rw-r--r--pkg/gce/gce.go10
-rw-r--r--pkg/ifuzz/x86/gen/gen.go13
-rw-r--r--pkg/instance/instance.go7
-rw-r--r--pkg/osutil/osutil.go13
-rw-r--r--pkg/runtest/run.go4
-rw-r--r--syz-ci/jobs.go20
-rw-r--r--syz-ci/manager.go24
-rw-r--r--syz-ci/updater.go4
-rw-r--r--tools/syz-testbuild/testbuild.go31
-rw-r--r--vm/gce/gce.go6
-rw-r--r--vm/vmimpl/merger_test.go4
-rw-r--r--vm/vmimpl/vmimpl.go9
22 files changed, 152 insertions, 102 deletions
diff --git a/dashboard/app/access_test.go b/dashboard/app/access_test.go
index f7d02d990..7bd412acf 100644
--- a/dashboard/app/access_test.go
+++ b/dashboard/app/access_test.go
@@ -5,6 +5,7 @@ package main
import (
"bytes"
+ "errors"
"fmt"
"net/http"
"strconv"
@@ -387,8 +388,8 @@ func TestAccess(t *testing.T) {
t.Fatal(err1)
}
c.expectNE(err, nil)
- httpErr, ok := err.(*HTTPError)
- c.expectTrue(ok)
+ var httpErr *HTTPError
+ c.expectTrue(errors.As(err, &httpErr))
c.expectEQ(httpErr.Code, http.StatusTemporaryRedirect)
c.expectEQ(httpErr.Headers["Location"], []string{loginURL})
} else {
diff --git a/dashboard/app/app_test.go b/dashboard/app/app_test.go
index d7aae91ed..241e5141d 100644
--- a/dashboard/app/app_test.go
+++ b/dashboard/app/app_test.go
@@ -4,6 +4,7 @@
package main
import (
+ "errors"
"fmt"
"net/http"
"os"
@@ -820,8 +821,8 @@ func checkLoginRedirect(c *Ctx, accessLevel AccessLevel, url string) {
func checkRedirect(c *Ctx, accessLevel AccessLevel, from, to string, status int) {
_, err := c.AuthGET(accessLevel, from)
c.expectNE(err, nil)
- httpErr, ok := err.(*HTTPError)
- c.expectTrue(ok)
+ var httpErr *HTTPError
+ c.expectTrue(errors.As(err, &httpErr))
c.expectEQ(httpErr.Code, status)
c.expectEQ(httpErr.Headers["Location"], []string{to})
}
@@ -829,8 +830,8 @@ func checkRedirect(c *Ctx, accessLevel AccessLevel, from, to string, status int)
func checkResponseStatusCode(c *Ctx, accessLevel AccessLevel, url string, status int) {
_, err := c.AuthGET(accessLevel, url)
c.expectNE(err, nil)
- httpErr, ok := err.(*HTTPError)
- c.expectTrue(ok)
+ var httpErr *HTTPError
+ c.expectTrue(errors.As(err, &httpErr))
c.expectEQ(httpErr.Code, status)
}
diff --git a/dashboard/app/bisect_test.go b/dashboard/app/bisect_test.go
index a61f51286..334d5a04d 100644
--- a/dashboard/app/bisect_test.go
+++ b/dashboard/app/bisect_test.go
@@ -5,6 +5,7 @@ package main
import (
"bytes"
+ "errors"
"fmt"
"net/http"
"strings"
@@ -1106,8 +1107,8 @@ func TestBugBisectionInvalidation(t *testing.T) {
// Mark bisection as invalid.
_, err = c.AuthGET(AccessAdmin, "/admin?action=invalidate_bisection&key="+jobKey.Encode())
- httpErr, ok := err.(*HTTPError)
- c.expectTrue(ok)
+ var httpErr *HTTPError
+ c.expectTrue(errors.As(err, &httpErr))
c.expectEQ(httpErr.Code, http.StatusFound)
// The invalidated bisection should have vanished from the web UI
diff --git a/dashboard/app/handler.go b/dashboard/app/handler.go
index 6a115d0b2..6b72da0bb 100644
--- a/dashboard/app/handler.go
+++ b/dashboard/app/handler.go
@@ -50,7 +50,8 @@ func handleContext(fn contextHandler) http.Handler {
http.Error(w, "403 Forbidden", http.StatusForbidden)
return
}
- if redir, ok := err.(ErrRedirect); ok {
+ var redir *ErrRedirect
+ if errors.As(err, &redir) {
http.Redirect(w, r, redir.Error(), http.StatusFound)
return
}
@@ -201,7 +202,7 @@ func commonHeader(c context.Context, r *http.Request, w http.ResponseWriter, ns
ns = adminPage
}
if ns != adminPage || !isAdminPage {
- return nil, ErrRedirect{fmt.Errorf("/%v", ns)}
+ return nil, &ErrRedirect{fmt.Errorf("/%v", ns)}
}
}
if ns != adminPage {
diff --git a/dashboard/app/reporting_email.go b/dashboard/app/reporting_email.go
index ee87169b7..26a3e57ef 100644
--- a/dashboard/app/reporting_email.go
+++ b/dashboard/app/reporting_email.go
@@ -703,17 +703,19 @@ func handleTestCommand(c context.Context, info *bugInfoResult,
user: msg.Author, extID: msg.MessageID, link: msg.Link,
patch: []byte(msg.Patch), repo: args[0], branch: args[1], jobCC: msg.Cc})
if err != nil {
- switch e := err.(type) {
- case *TestRequestDeniedError:
+ var testDenied *TestRequestDeniedError
+ var badTest *BadTestRequestError
+ switch {
+ case errors.As(err, &testDenied):
// Don't send a reply in this case.
- log.Errorf(c, "patch test request denied: %v", e)
- case *BadTestRequestError:
- reply = e.Error()
+ log.Errorf(c, "patch test request denied: %v", testDenied)
+ case errors.As(err, &badTest):
+ reply = badTest.Error()
default:
// Don't leak any details to the reply email.
reply = "Processing failed due to an internal error"
// .. but they are useful for debugging, so we'd like to see it on the Admin page.
- log.Errorf(c, "handleTestRequest error: %v", e)
+ log.Errorf(c, "handleTestRequest error: %v", err)
}
}
return reply
diff --git a/dashboard/app/reporting_external.go b/dashboard/app/reporting_external.go
index ffe3f00c8..b296139ec 100644
--- a/dashboard/app/reporting_external.go
+++ b/dashboard/app/reporting_external.go
@@ -5,6 +5,7 @@ package main
import (
"encoding/json"
+ "errors"
"fmt"
"net/http"
@@ -95,7 +96,8 @@ func apiNewTestJob(c context.Context, r *http.Request, payload []byte) (interfac
err := handleExternalTestRequest(c, req)
if err != nil {
resp.ErrorText = err.Error()
- if _, ok := err.(*BadTestRequestError); !ok {
+ var badTest *BadTestRequestError
+ if !errors.As(err, &badTest) {
// Log errors that are not related to the invalid input.
log.Errorf(c, "external patch posting error: %v", err)
}
diff --git a/dashboard/app/util_test.go b/dashboard/app/util_test.go
index f748e0dcd..b0ac1c6fe 100644
--- a/dashboard/app/util_test.go
+++ b/dashboard/app/util_test.go
@@ -8,6 +8,7 @@ package main
import (
"bytes"
+ "errors"
"fmt"
"io"
"net/http"
@@ -107,8 +108,8 @@ func (c *Ctx) expectFailureStatus(err error, code int) {
if err == nil {
c.t.Fatalf("expected to fail as %d, but it does not", code)
}
- httpErr, ok := err.(*HTTPError)
- if !ok || httpErr.Code != code {
+ var httpErr *HTTPError
+ if !errors.As(err, &httpErr) || httpErr.Code != code {
c.t.Fatalf("expected to fail as %d, but it failed as %v", code, err)
}
}
diff --git a/pkg/asset/storage.go b/pkg/asset/storage.go
index 1debdaa4a..8bec1cca8 100644
--- a/pkg/asset/storage.go
+++ b/pkg/asset/storage.go
@@ -123,7 +123,8 @@ func (storage *Storage) uploadFileStream(reader io.Reader, assetType dashapi.Ass
compressor = typeDescr.customCompressor
}
res, err := compressor(req, storage.backend.upload)
- if existsErr, ok := err.(*FileExistsError); ok {
+ var existsErr *FileExistsError
+ if errors.As(err, &existsErr) {
storage.tracer.Log("asset %s already exists", path)
if extra == nil || !extra.SkipIfExists {
return "", err
@@ -137,7 +138,8 @@ func (storage *Storage) uploadFileStream(reader io.Reader, assetType dashapi.Ass
if err != nil {
more := ""
closeErr := res.writer.Close()
- if exiterr, ok := closeErr.(*exec.ExitError); ok {
+ var exiterr *exec.ExitError
+ if errors.As(closeErr, &exiterr) {
more = fmt.Sprintf(", process state '%s'", exiterr.ProcessState)
}
return "", fmt.Errorf("failed to redirect byte stream: copied %d bytes, error %w%s",
diff --git a/pkg/bisect/bisect.go b/pkg/bisect/bisect.go
index 4c02e6336..e1e251cd9 100644
--- a/pkg/bisect/bisect.go
+++ b/pkg/bisect/bisect.go
@@ -4,6 +4,7 @@
package bisect
import (
+ "errors"
"fmt"
"math"
"os"
@@ -622,12 +623,14 @@ func (env *env) test() (*testResult, error) {
}
if err != nil {
errInfo := fmt.Sprintf("failed building %v: ", current.Hash)
- if verr, ok := err.(*osutil.VerboseError); ok {
+ var verr *osutil.VerboseError
+ var kerr *build.KernelError
+ if errors.As(err, &verr) {
errInfo += verr.Title
env.saveDebugFile(current.Hash, 0, verr.Output)
- } else if verr, ok := err.(*build.KernelError); ok {
- errInfo += string(verr.Report)
- env.saveDebugFile(current.Hash, 0, verr.Output)
+ } else if errors.As(err, &kerr) {
+ errInfo += string(kerr.Report)
+ env.saveDebugFile(current.Hash, 0, kerr.Output)
} else {
errInfo += err.Error()
env.log("%v", err)
@@ -722,38 +725,40 @@ func (env *env) processResults(current *vcs.Commit, results []instance.EnvTestRe
verdicts = append(verdicts, "OK")
continue
}
- switch err := res.Error.(type) {
- case *instance.TestError:
- if err.Infra {
+ var testError *instance.TestError
+ var crashError *instance.CrashError
+ switch {
+ case errors.As(res.Error, &testError):
+ if testError.Infra {
infra++
- verdicts = append(verdicts, fmt.Sprintf("infra problem: %v", err))
- } else if err.Boot {
- verdicts = append(verdicts, fmt.Sprintf("boot failed: %v", err))
+ verdicts = append(verdicts, fmt.Sprintf("infra problem: %v", testError))
+ } else if testError.Boot {
+ verdicts = append(verdicts, fmt.Sprintf("boot failed: %v", testError))
} else {
- verdicts = append(verdicts, fmt.Sprintf("basic kernel testing failed: %v", err))
+ verdicts = append(verdicts, fmt.Sprintf("basic kernel testing failed: %v", testError))
}
- output := err.Output
- if err.Report != nil {
- output = err.Report.Output
+ output := testError.Output
+ if testError.Report != nil {
+ output = testError.Report.Output
}
env.saveDebugFile(current.Hash, i, output)
- case *instance.CrashError:
- verdicts = append(verdicts, fmt.Sprintf("crashed: %v", err))
- output := err.Report.Report
+ case errors.As(res.Error, &crashError):
+ verdicts = append(verdicts, fmt.Sprintf("crashed: %v", crashError))
+ output := crashError.Report.Report
if len(output) == 0 {
- output = err.Report.Output
+ output = crashError.Report.Output
}
env.saveDebugFile(current.Hash, i, output)
- if env.isTransientError(err.Report) {
- verdicts = append(verdicts, fmt.Sprintf("ignore: %v", err))
+ if env.isTransientError(crashError.Report) {
+ verdicts = append(verdicts, fmt.Sprintf("ignore: %v", crashError))
break
}
bad++
- reports = append(reports, err.Report)
- verdicts = append(verdicts, fmt.Sprintf("crashed: %v", err))
+ reports = append(reports, crashError.Report)
+ verdicts = append(verdicts, fmt.Sprintf("crashed: %v", crashError))
default:
infra++
- verdicts = append(verdicts, fmt.Sprintf("failed: %v", err))
+ verdicts = append(verdicts, fmt.Sprintf("failed: %v", res.Error))
}
}
unique := make(map[string]bool)
diff --git a/pkg/build/build.go b/pkg/build/build.go
index 9bcacbd90..52873e3b2 100644
--- a/pkg/build/build.go
+++ b/pkg/build/build.go
@@ -7,6 +7,7 @@ package build
import (
"bytes"
"encoding/json"
+ "errors"
"fmt"
"os"
"path/filepath"
@@ -195,8 +196,8 @@ func extractRootCause(err error, OS, kernelSrc string) error {
if err == nil {
return nil
}
- verr, ok := err.(*osutil.VerboseError)
- if !ok {
+ var verr *osutil.VerboseError
+ if !errors.As(err, &verr) {
return err
}
reason, file := extractCauseInner(verr.Output, kernelSrc)
diff --git a/pkg/gce/gce.go b/pkg/gce/gce.go
index 71b88e2ec..ecc2c9853 100644
--- a/pkg/gce/gce.go
+++ b/pkg/gce/gce.go
@@ -12,6 +12,7 @@
package gce
import (
+ "errors"
"fmt"
"io"
"math/rand"
@@ -170,7 +171,8 @@ retry:
return "", fmt.Errorf("failed to create instance: %w", err)
}
if err := ctx.waitForCompletion("zone", "create image", op.Name, false); err != nil {
- if _, ok := err.(resourcePoolExhaustedError); ok && instance.Scheduling.Preemptible {
+ var resourcePoolExhaustedError resourcePoolExhaustedError
+ if errors.As(err, &resourcePoolExhaustedError) && instance.Scheduling.Preemptible {
instance.Scheduling.Preemptible = false
goto retry
}
@@ -206,7 +208,8 @@ func (ctx *Context) DeleteInstance(name string, wait bool) error {
op, err = ctx.computeService.Instances.Delete(ctx.ProjectID, ctx.ZoneID, name).Do()
return
})
- if apiErr, ok := err.(*googleapi.Error); ok && apiErr.Code == 404 {
+ var apiErr *googleapi.Error
+ if errors.As(err, &apiErr) && apiErr.Code == 404 {
return nil
}
if err != nil {
@@ -270,7 +273,8 @@ func (ctx *Context) DeleteImage(imageName string) error {
op, err = ctx.computeService.Images.Delete(ctx.ProjectID, imageName).Do()
return
})
- if apiErr, ok := err.(*googleapi.Error); ok && apiErr.Code == 404 {
+ var apiErr *googleapi.Error
+ if errors.As(err, &apiErr) && apiErr.Code == 404 {
return nil
}
if err != nil {
diff --git a/pkg/ifuzz/x86/gen/gen.go b/pkg/ifuzz/x86/gen/gen.go
index aae7429c0..01ba8420b 100644
--- a/pkg/ifuzz/x86/gen/gen.go
+++ b/pkg/ifuzz/x86/gen/gen.go
@@ -7,6 +7,7 @@ package main
import (
"bufio"
+ "errors"
"fmt"
"os"
"reflect"
@@ -19,7 +20,7 @@ import (
"github.com/google/syzkaller/pkg/tool"
)
-// nolint: gocyclo, gocognit, funlen
+// nolint: gocyclo, gocognit, funlen, dupl
func main() {
if len(os.Args) != 2 {
tool.Failf("usage: gen instructions.txt")
@@ -113,8 +114,9 @@ func main() {
insn1 = new(x86.Insn)
*insn1 = *insn
if err := parsePattern(insn1, vals); err != nil {
- if _, ok := err.(errSkip); !ok {
- reportError(err.Error())
+ var errSkip errSkip
+ if !errors.As(err, &errSkip) {
+ reportError(errSkip.Error())
}
if err.Error() != "" {
fmt.Fprintf(os.Stderr, "skipping %v on line %v (%v)\n", insn.Name, i, err)
@@ -127,8 +129,9 @@ func main() {
break
}
if err := parseOperands(insn1, vals); err != nil {
- if _, ok := err.(errSkip); !ok {
- reportError(err.Error())
+ var errSkip errSkip
+ if !errors.As(err, &errSkip) {
+ reportError(errSkip.Error())
}
if err.Error() != "" {
fmt.Fprintf(os.Stderr, "skipping %v on line %v (%v)\n", insn.Name, i, err)
diff --git a/pkg/instance/instance.go b/pkg/instance/instance.go
index ea4084def..7696a945d 100644
--- a/pkg/instance/instance.go
+++ b/pkg/instance/instance.go
@@ -7,6 +7,7 @@ package instance
import (
"encoding/json"
+ "errors"
"fmt"
"net"
"os"
@@ -305,7 +306,8 @@ func (inst *inst) test() EnvTestResult {
ret := EnvTestResult{
Error: testErr,
}
- if bootErr, ok := err.(vm.BootErrorer); ok {
+ var bootErr vm.BootErrorer
+ if errors.As(err, &bootErr) {
testErr.Title, testErr.Output = bootErr.BootError()
ret.RawOutput = testErr.Output
rep := inst.reporter.Parse(testErr.Output)
@@ -327,7 +329,8 @@ func (inst *inst) test() EnvTestResult {
testErr.Title = rep.Title
} else {
testErr.Infra = true
- if infraErr, ok := err.(vm.InfraErrorer); ok {
+ var infraErr vm.InfraErrorer
+ if errors.As(err, &infraErr) {
// In case there's more info available.
testErr.Title, testErr.Output = infraErr.InfraError()
}
diff --git a/pkg/osutil/osutil.go b/pkg/osutil/osutil.go
index 1687cef9d..478c091dc 100644
--- a/pkg/osutil/osutil.go
+++ b/pkg/osutil/osutil.go
@@ -7,6 +7,7 @@ import (
"bytes"
"compress/gzip"
"context"
+ "errors"
"fmt"
"io"
"os"
@@ -67,7 +68,8 @@ func Run(timeout time.Duration, cmd *exec.Cmd) ([]byte, error) {
text = fmt.Sprintf("timedout after %v %q", timeout, cmd.Args)
}
exitCode := 0
- if exitErr, ok := err.(*exec.ExitError); ok {
+ var exitErr *exec.ExitError
+ if errors.As(err, &exitErr) {
if status, ok := exitErr.Sys().(syscall.WaitStatus); ok {
exitCode = status.ExitStatus()
}
@@ -120,10 +122,11 @@ func (err *VerboseError) Error() string {
}
func PrependContext(ctx string, err error) error {
- switch err1 := err.(type) {
- case *VerboseError:
- err1.Title = fmt.Sprintf("%v: %v", ctx, err1.Title)
- return err1
+ var verboseError *VerboseError
+ switch {
+ case errors.As(err, &verboseError):
+ verboseError.Title = fmt.Sprintf("%v: %v", ctx, verboseError.Title)
+ return verboseError
default:
return fmt.Errorf("%v: %w", ctx, err)
}
diff --git a/pkg/runtest/run.go b/pkg/runtest/run.go
index 4f6170fbb..864a9f5f1 100644
--- a/pkg/runtest/run.go
+++ b/pkg/runtest/run.go
@@ -13,6 +13,7 @@ package runtest
import (
"bufio"
"bytes"
+ "errors"
"fmt"
"os"
"path/filepath"
@@ -691,7 +692,8 @@ func runTestC(req *RunRequest) {
// Tell ASAN to not mess with our NONFAILING.
cmd.Env = append(append([]string{}, os.Environ()...), "ASAN_OPTIONS=handle_segv=0 allow_user_segv_handler=1")
req.Output, req.Err = osutil.Run(20*time.Second, cmd)
- if verr, ok := req.Err.(*osutil.VerboseError); ok {
+ var verr *osutil.VerboseError
+ if errors.As(req.Err, &verr) {
// The process can legitimately do something like exit_group(1).
// So we ignore the error and rely on the rest of the checks (e.g. syscall return values).
req.Err = nil
diff --git a/syz-ci/jobs.go b/syz-ci/jobs.go
index 203a7a8e3..89276c04e 100644
--- a/syz-ci/jobs.go
+++ b/syz-ci/jobs.go
@@ -5,6 +5,7 @@ package main
import (
"bytes"
+ "errors"
"fmt"
"io"
"os"
@@ -517,7 +518,8 @@ func (jp *JobProcessor) bisect(job *Job, mgrcfg *mgrconfig.Config) error {
res, err := bisect.Run(cfg)
resp.Log = trace.Bytes()
if err != nil {
- if _, ok := err.(*bisect.InfraError); ok {
+ var infraErr *bisect.InfraError
+ if errors.As(err, &infraErr) {
resp.Flags |= dashapi.BisectResultInfraError
}
return err
@@ -735,18 +737,20 @@ func aggregateTestResults(results []instance.EnvTestResult) (*patchTestResult, e
continue
}
anyErr = res.Error
- switch err := res.Error.(type) {
- case *instance.TestError:
+ var testError *instance.TestError
+ var crashError *instance.CrashError
+ switch {
+ case errors.As(res.Error, &testError):
// We should not put rep into resp.CrashTitle/CrashReport,
// because that will be treated as patch not fixing the bug.
- if rep := err.Report; rep != nil {
+ if rep := testError.Report; rep != nil {
testErr = fmt.Errorf("%v\n\n%s\n\n%s", rep.Title, rep.Report, rep.Output)
} else {
- testErr = fmt.Errorf("%v\n\n%s", err.Title, err.Output)
+ testErr = fmt.Errorf("%v\n\n%s", testError.Title, testError.Output)
}
- case *instance.CrashError:
- if resReport == nil || (len(resReport.report.Report) == 0 && len(err.Report.Report) != 0) {
- resReport = &patchTestResult{report: err.Report, rawOutput: res.RawOutput}
+ case errors.As(res.Error, &crashError):
+ if resReport == nil || (len(resReport.report.Report) == 0 && len(crashError.Report.Report) != 0) {
+ resReport = &patchTestResult{report: crashError.Report, rawOutput: res.RawOutput}
}
}
}
diff --git a/syz-ci/manager.go b/syz-ci/manager.go
index 14dd6114c..13f8768e1 100644
--- a/syz-ci/manager.go
+++ b/syz-ci/manager.go
@@ -5,6 +5,7 @@ package main
import (
"crypto/sha256"
+ "errors"
"fmt"
"io"
"net/http"
@@ -339,14 +340,16 @@ func (mgr *Manager) build(kernelCommit *vcs.Commit) error {
rep := &report.Report{
Title: fmt.Sprintf("%v build error", mgr.mgrcfg.RepoAlias),
}
- switch err1 := err.(type) {
- case *build.KernelError:
- rep.Report = err1.Report
- rep.Output = err1.Output
- rep.Recipients = err1.Recipients
- case *osutil.VerboseError:
- rep.Report = []byte(err1.Title)
- rep.Output = err1.Output
+ var kernelError *build.KernelError
+ var verboseError *osutil.VerboseError
+ switch {
+ case errors.As(err, &kernelError):
+ rep.Report = kernelError.Report
+ rep.Output = kernelError.Output
+ rep.Recipients = kernelError.Recipients
+ case errors.As(err, &verboseError):
+ rep.Report = []byte(verboseError.Title)
+ rep.Output = verboseError.Output
default:
rep.Report = []byte(err.Error())
}
@@ -437,8 +440,9 @@ func (mgr *Manager) testImage(imageDir string, info *BuildInfo) error {
continue
}
failures++
- switch err := res.Error.(type) {
- case *instance.TestError:
+ var err *instance.TestError
+ switch {
+ case errors.As(res.Error, &err):
if rep := err.Report; rep != nil {
what := "test"
if err.Boot {
diff --git a/syz-ci/updater.go b/syz-ci/updater.go
index 1d632ddcd..41d6d48f9 100644
--- a/syz-ci/updater.go
+++ b/syz-ci/updater.go
@@ -4,6 +4,7 @@
package main
import (
+ "errors"
"fmt"
"os"
"path/filepath"
@@ -297,7 +298,8 @@ func (upd *SyzUpdater) build(commit *vcs.Commit) error {
func (upd *SyzUpdater) uploadBuildError(commit *vcs.Commit, buildErr error) {
var title string
var output []byte
- if verbose, ok := buildErr.(*osutil.VerboseError); ok {
+ var verbose *osutil.VerboseError
+ if errors.As(buildErr, &verbose) {
title = verbose.Title
output = verbose.Output
} else {
diff --git a/tools/syz-testbuild/testbuild.go b/tools/syz-testbuild/testbuild.go
index daadff3e3..a0d80f057 100644
--- a/tools/syz-testbuild/testbuild.go
+++ b/tools/syz-testbuild/testbuild.go
@@ -23,6 +23,7 @@ package main
import (
"encoding/json"
+ "errors"
"flag"
"fmt"
"log"
@@ -143,7 +144,8 @@ func test(repo vcs.Repo, bisecter vcs.Bisecter, kernelConfig []byte, env instanc
KernelConfig: bisectEnv.KernelConfig,
})
if err != nil {
- if verr, ok := err.(*osutil.VerboseError); ok {
+ var verr *osutil.VerboseError
+ if errors.As(err, &verr) {
log.Printf("BUILD BROKEN: %v", verr.Title)
saveLog(com.Hash, 0, verr.Output)
} else {
@@ -162,23 +164,26 @@ func test(repo vcs.Repo, bisecter vcs.Bisecter, kernelConfig []byte, env instanc
verdicts = append(verdicts, "OK")
continue
}
- switch err := res.Error.(type) {
- case *instance.TestError:
- if err.Boot {
- verdicts = append(verdicts, fmt.Sprintf("boot failed: %v", err))
+
+ var testError *instance.TestError
+ var crashError *instance.CrashError
+ switch {
+ case errors.As(res.Error, &testError):
+ if testError.Boot {
+ verdicts = append(verdicts, fmt.Sprintf("boot failed: %v", testError))
} else {
- verdicts = append(verdicts, fmt.Sprintf("basic kernel testing failed: %v", err))
+ verdicts = append(verdicts, fmt.Sprintf("basic kernel testing failed: %v", testError))
}
- output := err.Output
- if err.Report != nil {
- output = err.Report.Output
+ output := testError.Output
+ if testError.Report != nil {
+ output = testError.Report.Output
}
saveLog(com.Hash, i, output)
- case *instance.CrashError:
- verdicts = append(verdicts, fmt.Sprintf("crashed: %v", err))
- output := err.Report.Report
+ case errors.As(res.Error, &crashError):
+ verdicts = append(verdicts, fmt.Sprintf("crashed: %v", crashError))
+ output := crashError.Report.Report
if len(output) == 0 {
- output = err.Report.Output
+ output = crashError.Report.Output
}
saveLog(com.Hash, i, output)
default:
diff --git a/vm/gce/gce.go b/vm/gce/gce.go
index 60a88010c..5c91f08de 100644
--- a/vm/gce/gce.go
+++ b/vm/gce/gce.go
@@ -15,6 +15,7 @@ import (
"archive/tar"
"bytes"
"compress/gzip"
+ "errors"
"fmt"
"io"
"os"
@@ -318,14 +319,15 @@ func (inst *instance) Run(timeout time.Duration, stop <-chan bool, command strin
ssh.Process.Kill()
merger.Wait()
con.Wait()
+ var mergeError *vmimpl.MergerError
if cmdErr := ssh.Wait(); cmdErr == nil {
// If the command exited successfully, we got EOF error from merger.
// But in this case no error has happened and the EOF is expected.
err = nil
- } else if merr, ok := err.(vmimpl.MergerError); ok && merr.R == conRpipe {
+ } else if errors.As(err, &mergeError) && mergeError.R == conRpipe {
// Console connection must never fail. If it does, it's either
// instance preemption or a GCE bug. In either case, not a kernel bug.
- log.Logf(0, "%v: gce console connection failed with %v", inst.name, merr.Err)
+ log.Logf(0, "%v: gce console connection failed with %v", inst.name, mergeError.Err)
err = vmimpl.ErrTimeout
} else {
// Check if the instance was terminated due to preemption or host maintenance.
diff --git a/vm/vmimpl/merger_test.go b/vm/vmimpl/merger_test.go
index 8308aff5e..ef5570509 100644
--- a/vm/vmimpl/merger_test.go
+++ b/vm/vmimpl/merger_test.go
@@ -5,6 +5,7 @@ package vmimpl
import (
"bytes"
+ "errors"
"io"
"testing"
"time"
@@ -62,9 +63,10 @@ func TestMerger(t *testing.T) {
t.Fatalf("bad line: '%s', want '%s'", got, want)
}
+ var merr MergerError
if err := <-merger.Err; err == nil {
t.Fatalf("merger did not produce an error on pipe close")
- } else if merr := err.(MergerError); merr.Name != "pipe1" || merr.R != rp1 || merr.Err != io.EOF {
+ } else if !errors.As(err, &merr) || merr.Name != "pipe1" || merr.R != rp1 || merr.Err != io.EOF {
t.Fatalf("merger produced wrong error: %v", err)
}
diff --git a/vm/vmimpl/vmimpl.go b/vm/vmimpl/vmimpl.go
index 9dbd61a92..0a4ada028 100644
--- a/vm/vmimpl/vmimpl.go
+++ b/vm/vmimpl/vmimpl.go
@@ -93,12 +93,11 @@ type BootError struct {
}
func MakeBootError(err error, output []byte) error {
- switch err1 := err.(type) {
- case *osutil.VerboseError:
- return BootError{err1.Title, append(err1.Output, output...)}
- default:
- return BootError{err.Error(), output}
+ var verboseError *osutil.VerboseError
+ if errors.As(err, &verboseError) {
+ return BootError{verboseError.Title, append(verboseError.Output, output...)}
}
+ return BootError{err.Error(), output}
}
func (err BootError) Error() string {