23
23
verbose = False
24
24
creduce_cmd = None
25
25
clang_cmd = None
26
- not_cmd = None
27
26
28
27
def verbose_print (* args , ** kwargs ):
29
28
if verbose :
@@ -77,7 +76,7 @@ def __init__(self, crash_script, file_to_reduce):
77
76
self .clang = clang_cmd
78
77
self .clang_args = []
79
78
self .expected_output = []
80
- self .is_crash = True
79
+ self .needs_stack_trace = False
81
80
self .creduce_flags = ["--tidy" ]
82
81
83
82
self .read_clang_args (crash_script , file_to_reduce )
@@ -128,36 +127,36 @@ def read_expected_output(self):
128
127
crash_output = re .sub (ansi_escape , '' , crash_output .decode ('utf-8' ))
129
128
130
129
# Look for specific error messages
131
- regexes = [r"Assertion `(.+)' failed" , # Linux assert()
132
- r"Assertion failed: (.+) ," , # FreeBSD/Mac assert()
133
- r"fatal error: error in backend: (.+) " ,
134
- r"LLVM ERROR: (.+) " ,
135
- r"UNREACHABLE executed ( at .+) ?!" ,
136
- r"LLVM IR generation of declaration '(.+) '" ,
137
- r"Generating code for declaration '(.+) '" ,
138
- r"\*\*\* Bad machine code: (.+) \*\*\*" ]
130
+ regexes = [r"Assertion .+ failed" , # Linux assert()
131
+ r"Assertion failed: .+ ," , # FreeBSD/Mac assert()
132
+ r"fatal error: error in backend: .+ " ,
133
+ r"LLVM ERROR: .+ " ,
134
+ r"UNREACHABLE executed at .+?!" ,
135
+ r"LLVM IR generation of declaration '.+ '" ,
136
+ r"Generating code for declaration '.+ '" ,
137
+ r"\*\*\* Bad machine code: .+ \*\*\*" ]
139
138
for msg_re in regexes :
140
139
match = re .search (msg_re , crash_output )
141
140
if match :
142
- msg = match .group (1 )
141
+ msg = match .group (0 )
143
142
result = [msg ]
144
143
print ("Found message:" , msg )
145
-
146
- if "fatal error:" in msg_re :
147
- self .is_crash = False
148
144
break
149
145
150
146
# If no message was found, use the top five stack trace functions,
151
147
# ignoring some common functions
152
148
# Five is a somewhat arbitrary number; the goal is to get a small number
153
149
# of identifying functions with some leeway for common functions
154
150
if not result :
151
+ self .needs_stack_trace = True
155
152
stacktrace_re = r'[0-9]+\s+0[xX][0-9a-fA-F]+\s*([^(]+)\('
156
- filters = ["PrintStackTraceSignalHandler" ,
157
- "llvm::sys::RunSignalHandlers" ,
158
- "SignalHandler" , "__restore_rt" , "gsignal" , "abort" ]
153
+ filters = ["PrintStackTrace" , "RunSignalHandlers" , "CleanupOnSignal" ,
154
+ "HandleCrash" , "SignalHandler" , "__restore_rt" , "gsignal" , "abort" ]
155
+ def skip_function (func_name ):
156
+ return any (name in func_name for name in filters )
157
+
159
158
matches = re .findall (stacktrace_re , crash_output )
160
- result = [x for x in matches if x and x . strip () not in filters ][:5 ]
159
+ result = [x for x in matches if x and not skip_function ( x ) ][:5 ]
161
160
for msg in result :
162
161
print ("Found stack trace function:" , msg )
163
162
@@ -184,10 +183,17 @@ def check_expected_output(self, args=None, filename=None):
184
183
def write_interestingness_test (self ):
185
184
print ("\n Creating the interestingness test..." )
186
185
187
- crash_flag = "--crash" if self .is_crash else ""
186
+ # Disable symbolization if it's not required to avoid slow symbolization.
187
+ disable_symbolization = ''
188
+ if not self .needs_stack_trace :
189
+ disable_symbolization = 'export LLVM_DISABLE_SYMBOLIZATION=1'
188
190
189
- output = "#!/bin/bash\n %s %s %s >& t.log || exit 1\n " % \
190
- (pipes .quote (not_cmd ), crash_flag , quote_cmd (self .get_crash_cmd ()))
191
+ output = """#!/bin/bash
192
+ %s
193
+ if %s >& t.log ; then
194
+ exit 1
195
+ fi
196
+ """ % (disable_symbolization , quote_cmd (self .get_crash_cmd ()))
191
197
192
198
for msg in self .expected_output :
193
199
output += 'grep -F %s t.log || exit 1\n ' % pipes .quote (msg )
@@ -372,7 +378,6 @@ def main():
372
378
global verbose
373
379
global creduce_cmd
374
380
global clang_cmd
375
- global not_cmd
376
381
377
382
parser = ArgumentParser (description = __doc__ ,
378
383
formatter_class = RawTextHelpFormatter )
@@ -382,9 +387,6 @@ def main():
382
387
help = "Name of the file to be reduced." )
383
388
parser .add_argument ('--llvm-bin' , dest = 'llvm_bin' , type = str ,
384
389
help = "Path to the LLVM bin directory." )
385
- parser .add_argument ('--llvm-not' , dest = 'llvm_not' , type = str ,
386
- help = "The path to the `not` executable. "
387
- "By default uses the llvm-bin directory." )
388
390
parser .add_argument ('--clang' , dest = 'clang' , type = str ,
389
391
help = "The path to the `clang` executable. "
390
392
"By default uses the llvm-bin directory." )
@@ -398,7 +400,6 @@ def main():
398
400
llvm_bin = os .path .abspath (args .llvm_bin ) if args .llvm_bin else None
399
401
creduce_cmd = check_cmd ('creduce' , None , args .creduce )
400
402
clang_cmd = check_cmd ('clang' , llvm_bin , args .clang )
401
- not_cmd = check_cmd ('not' , llvm_bin , args .llvm_not )
402
403
403
404
crash_script = check_file (args .crash_script [0 ])
404
405
file_to_reduce = check_file (args .file_to_reduce [0 ])
0 commit comments