github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/tools/syz-symbolize/symbolize.go (about)

     1  // Copyright 2016 syzkaller project authors. All rights reserved.
     2  // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
     3  
     4  package main
     5  
     6  import (
     7  	"flag"
     8  	"fmt"
     9  	"os"
    10  	"path/filepath"
    11  	"runtime"
    12  
    13  	"github.com/google/syzkaller/pkg/hash"
    14  	"github.com/google/syzkaller/pkg/mgrconfig"
    15  	"github.com/google/syzkaller/pkg/osutil"
    16  	"github.com/google/syzkaller/pkg/report"
    17  	"github.com/google/syzkaller/pkg/tool"
    18  	"github.com/google/syzkaller/pkg/vcs"
    19  )
    20  
    21  var (
    22  	flagOS        = flag.String("os", runtime.GOOS, "target os")
    23  	flagArch      = flag.String("arch", runtime.GOARCH, "target arch")
    24  	flagKernelObj = flag.String("kernel_obj", ".", "path to kernel build/obj dir")
    25  	flagKernelSrc = flag.String("kernel_src", "", "path to kernel sources (defaults to kernel_obj)")
    26  	flagOutDir    = flag.String("outdir", "", "output directory")
    27  )
    28  
    29  func main() {
    30  	flag.Parse()
    31  	if len(flag.Args()) != 1 {
    32  		fmt.Fprintf(os.Stderr, "usage: syz-symbolize [flags] kernel_log_file\n")
    33  		flag.PrintDefaults()
    34  		os.Exit(1)
    35  	}
    36  	cfg, err := mgrconfig.LoadPartialData([]byte(`{
    37  		"kernel_obj": "` + *flagKernelObj + `",
    38  		"kernel_src": "` + *flagKernelSrc + `",
    39  		"target": "` + *flagOS + "/" + *flagArch + `"
    40  	}`))
    41  	if err != nil {
    42  		tool.Fail(err)
    43  	}
    44  	cfg.CompleteKernelDirs()
    45  	reporter, err := report.NewReporter(cfg)
    46  	if err != nil {
    47  		tool.Failf("failed to create reporter: %v", err)
    48  	}
    49  	text, err := os.ReadFile(flag.Args()[0])
    50  	if err != nil {
    51  		tool.Failf("failed to open input file: %v", err)
    52  	}
    53  	reps := report.ParseAll(reporter, text)
    54  	if len(reps) == 0 {
    55  		rep := &report.Report{Report: text}
    56  		if err := reporter.Symbolize(rep); err != nil {
    57  			tool.Failf("failed to symbolize report: %v", err)
    58  		}
    59  		os.Stdout.Write(rep.Report)
    60  		return
    61  	}
    62  	for _, rep := range reps {
    63  		if *flagOutDir != "" {
    64  			saveCrash(rep, *flagOutDir)
    65  		}
    66  		if err := reporter.Symbolize(rep); err != nil {
    67  			fmt.Fprintf(os.Stderr, "failed to symbolize report: %v\n", err)
    68  		}
    69  		fmt.Printf("TITLE: %v\n", rep.Title)
    70  		fmt.Printf("CORRUPTED: %v (%v)\n", rep.Corrupted, rep.CorruptedReason)
    71  		fmt.Printf("MAINTAINERS (TO): %v\n", rep.Recipients.GetEmails(vcs.To))
    72  		fmt.Printf("MAINTAINERS (CC): %v\n", rep.Recipients.GetEmails(vcs.Cc))
    73  		fmt.Printf("\n")
    74  		os.Stdout.Write(rep.Report)
    75  		fmt.Printf("\n\n")
    76  	}
    77  }
    78  
    79  func saveCrash(rep *report.Report, path string) {
    80  	sig := hash.Hash([]byte(rep.Title))
    81  	id := sig.String()
    82  	dir := filepath.Join(path, id)
    83  	osutil.MkdirAll(dir)
    84  	if err := osutil.WriteFile(filepath.Join(dir, "description"), []byte(rep.Title+"\n")); err != nil {
    85  		tool.Failf("failed to write description: %v", err)
    86  	}
    87  
    88  	if err := osutil.WriteFile(filepath.Join(dir, "log"), rep.Output); err != nil {
    89  		tool.Failf("failed to write log: %v", err)
    90  	}
    91  
    92  	if len(rep.Report) > 0 {
    93  		if err := osutil.WriteFile(filepath.Join(dir, "report"), rep.Report); err != nil {
    94  			tool.Failf("failed to write report: %v", err)
    95  		}
    96  	}
    97  }