github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/pkg/report/gvisor.go (about)

     1  // Copyright 2018 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 report
     5  
     6  import (
     7  	"bytes"
     8  	"regexp"
     9  )
    10  
    11  type gvisor struct {
    12  	*config
    13  }
    14  
    15  func ctorGvisor(cfg *config) (reporterImpl, []string, error) {
    16  	ctx := &gvisor{
    17  		config: cfg,
    18  	}
    19  	suppressions := []string{
    20  		"panic: ptrace sysemu failed: no such process",                                          // OOM kill
    21  		`panic: ptrace (s|g)et fpregs.* failed: no such process`,                                // OOM kill
    22  		`panic: ptrace (s|g)et regs.* failed: no such process`,                                  // OOM kill
    23  		"panic: error initializing first thread: resource temporarily unavailable",              // PID exhaustion
    24  		"panic: unable to activate mm: creating stub process: resource temporarily unavailable", // PID exhaustion
    25  		"panic: executor failed: pthread_create failed",                                         // PID exhaustion
    26  		"panic: failed to start executor binary",
    27  		"panic: error mapping run data: error mapping runData: cannot allocate memory",
    28  		"race: limit on 8128 simultaneously alive goroutines is exceeded, dying",
    29  		"ERROR: ThreadSanitizer", // Go race failing due to OOM.
    30  		"FATAL: ThreadSanitizer",
    31  		"ThreadSanitizer: clock allocator overflow \\(65536\\*1024\\). Dying.",
    32  	}
    33  	return ctx, suppressions, nil
    34  }
    35  
    36  func (ctx *gvisor) ContainsCrash(output []byte) bool {
    37  	return containsCrash(output, gvisorOopses, ctx.ignores)
    38  }
    39  
    40  func (ctx *gvisor) Parse(output []byte) *Report {
    41  	rep := simpleLineParser(output, gvisorOopses, nil, ctx.ignores)
    42  	if rep == nil {
    43  		return nil
    44  	}
    45  	rep.Title = replaceTable(gvisorTitleReplacement, rep.Title)
    46  	rep.Report = ctx.shortenReport(rep.Report)
    47  	return rep
    48  }
    49  
    50  func (ctx *gvisor) shortenReport(report []byte) []byte {
    51  	// gvisor panics include stacks of all goroutines.
    52  	// This output is too lengthy for report and not very useful.
    53  	// So we always take 5 lines from report and then cut it at the next empty line.
    54  	// The intention is to capture panic header and traceback of the first goroutine.
    55  	pos := 0
    56  	for i := 0; i < 5; i++ {
    57  		pos1 := bytes.IndexByte(report[pos:], '\n')
    58  		if pos1 == -1 {
    59  			return report
    60  		}
    61  		pos += pos1 + 1
    62  	}
    63  	end := bytes.Index(report[pos:], []byte{'\n', '\n'})
    64  	if end == -1 {
    65  		return report
    66  	}
    67  	if bytes.Contains(report, []byte("WARNING: DATA RACE")) {
    68  		// For data races extract both stacks.
    69  		end2 := bytes.Index(report[pos+end+2:], []byte{'\n', '\n'})
    70  		if end2 != -1 {
    71  			end += end2 + 2
    72  		}
    73  	}
    74  	return report[:pos+end+1]
    75  }
    76  
    77  func (ctx *gvisor) Symbolize(rep *Report) error {
    78  	return nil
    79  }
    80  
    81  var gvisorTitleReplacement = []replacement{
    82  	{
    83  		regexp.MustCompile(`container ".*"`),
    84  		"container NAME",
    85  	},
    86  	{
    87  		regexp.MustCompile(`sandbox ".*"`),
    88  		"sandbox NAME",
    89  	},
    90  	{
    91  		regexp.MustCompile(`(pid|PID) [0-9]+`),
    92  		"pid X",
    93  	},
    94  }
    95  
    96  var gvisorOopses = append([]*oops{
    97  	{
    98  		[]byte("Panic:"),
    99  		[]oopsFormat{
   100  			{
   101  				title:        compile("Panic:(.*)"),
   102  				fmt:          "Panic:%[1]v",
   103  				noStackTrace: true,
   104  			},
   105  		},
   106  		[]*regexp.Regexp{},
   107  	},
   108  	{
   109  		[]byte("SIGSEGV:"),
   110  		[]oopsFormat{
   111  			{
   112  				title:        compile("SIGSEGV:(.*)"),
   113  				fmt:          "SIGSEGV:%[1]v",
   114  				noStackTrace: true,
   115  			},
   116  		},
   117  		[]*regexp.Regexp{},
   118  	},
   119  	{
   120  		[]byte("SIGBUS:"),
   121  		[]oopsFormat{
   122  			{
   123  				title:        compile("SIGBUS:(.*)"),
   124  				fmt:          "SIGBUS:%[1]v",
   125  				noStackTrace: true,
   126  			},
   127  		},
   128  		[]*regexp.Regexp{},
   129  	},
   130  	{
   131  		[]byte("FATAL ERROR:"),
   132  		[]oopsFormat{
   133  			{
   134  				title:        compile("FATAL ERROR:(.*)"),
   135  				fmt:          "FATAL ERROR:%[1]v",
   136  				noStackTrace: true,
   137  			},
   138  		},
   139  		[]*regexp.Regexp{},
   140  	},
   141  	{
   142  		[]byte("WARNING: DATA RACE"),
   143  		[]oopsFormat{
   144  			{
   145  				title:        compile("WARNING: DATA RACE"),
   146  				report:       compile("WARNING: DATA RACE\n(?:.*\n)*?  (?:[a-zA-Z0-9./_-]+/)([a-zA-Z0-9.()*_]+)\\(\\)\n"),
   147  				fmt:          "DATA RACE in %[1]v",
   148  				noStackTrace: true,
   149  			},
   150  		},
   151  		[]*regexp.Regexp{},
   152  	},
   153  	{
   154  		[]byte("Invalid request partialResult"),
   155  		[]oopsFormat{
   156  			{
   157  				title:        compile("Invalid request partialResult"),
   158  				report:       compile("Invalid request partialResult .* for (.*) operation"),
   159  				fmt:          "Invalid request partialResult in %[1]v",
   160  				noStackTrace: true,
   161  			},
   162  		},
   163  		[]*regexp.Regexp{},
   164  	},
   165  	{
   166  		[]byte("fatal error:"),
   167  		[]oopsFormat{
   168  			{
   169  				title:        compile("fatal error:(.*)"),
   170  				fmt:          "fatal error:%[1]v",
   171  				noStackTrace: true,
   172  			},
   173  		},
   174  		[]*regexp.Regexp{},
   175  	},
   176  	{
   177  		[]byte("WARNING: BUG on"),
   178  		[]oopsFormat{
   179  			{
   180  				title:        compile("WARNING: BUG on (.*)"),
   181  				fmt:          "WARNING: BUG on %[1]v",
   182  				noStackTrace: true,
   183  			},
   184  		},
   185  		[]*regexp.Regexp{},
   186  	},
   187  }, commonOopses...)