1
1
#!/usr/bin/env python
2
2
3
- # This script uses a regex to validate the output of our backtraces.
4
- # The layout we assume is:
5
- #
6
- # <frame number> <library name> <address> <demangled name> + <offset>
7
- #
8
- # It currently just checks that the backtrace results in at least one correctly
9
- # formatted entry. It does not directly validate the input since the output
10
- # would not be robust against standard library changes.
11
- #
12
- # TODO: We could have the user pass in the frame number, library name, and
13
- # demangled name. These we can always validate as true in a robust way. On the
14
- # other hand, address and offset are more difficult to validate in a robust way
15
- # in the face of small codegen differences, so without any further thought I
16
- # imagine we can just check the format.
17
- #
18
- # 11 libswiftCore.dylib 0x000000000dce84d0l _fatalErrorMessage(StaticString,
19
- # StaticString, StaticString, UInt, flags : UInt32) -> () + 444
20
-
21
- from __future__ import print_function
3
+
4
+ """
5
+ This script uses a regex to validate the output of our backtraces.
6
+ The layout we assume is:
7
+
8
+ <frame number> <library name> <address> <demangled name> + <offset>
9
+
10
+ It currently just checks that the backtrace results in at least one correctly
11
+ formatted entry. It does not directly validate the input since the output
12
+ would not be robust against standard library changes.
13
+
14
+ TODO: We could have the user pass in the frame number, library name, and
15
+ demangled name. These we can always validate as true in a robust way. On the
16
+ other hand, address and offset are more difficult to validate in a robust way
17
+ in the face of small codegen differences, so without any further thought I
18
+ imagine we can just check the format.
19
+
20
+ 11 libswiftCore.dylib 0x000000000dce84d0l _fatalErrorMessage(StaticString,
21
+ StaticString, StaticString, UInt, flags : UInt32) -> () + 444
22
+ """
23
+
24
+
25
+ from __future__ import absolute_import , print_function , unicode_literals
22
26
23
27
import argparse
24
28
import re
25
29
import sys
26
30
27
31
28
- def main ():
32
+ # -----------------------------------------------------------------------------
33
+ # Constants
34
+
35
+ DESCRIPTION = """
36
+ Checks that a stacktrace dump follows canonical formatting.
37
+ """
38
+
39
+ TARGET_PATTERN = re .compile (
40
+ r'(?P<index>\d+) +(?P<object>\S+) +(?P<address>0x[0-9a-fA-F]{16}) '
41
+ r'(?P<routine>[^+]+) [+] (?P<offset>\d+)' )
42
+
43
+ RESULTS_FORMAT = """Stack Trace Entry:
44
+ \t Index: '%(index)s'
45
+ \t Object File: '%(object)s'
46
+ \t Address: '%(address)s'
47
+ \t Routine: '%(routine)s'
48
+ \t Offset: '%(offset)s'
49
+ """
50
+
51
+
52
+ # -----------------------------------------------------------------------------
53
+
54
+ def parse_args ():
29
55
parser = argparse .ArgumentParser (
30
56
formatter_class = argparse .RawDescriptionHelpFormatter ,
31
- description = """Checks that a stacktrace dump follows canonical
32
- formatting.""" )
57
+ description = DESCRIPTION )
58
+
33
59
parser .add_argument (
34
- "-u" , " --check-unavailable" , action = 'store_true ' ,
35
- help = "Checks if any symbols were unavailable" )
36
- args = parser . parse_args ( )
60
+ '-u' , ' --check-unavailable' ,
61
+ action = 'store_true' ,
62
+ help = 'Checks if any symbols were unavailable' )
37
63
38
- TARGET_RE = re .compile (
39
- r"(?P<index>\d+) +(?P<object>\S+) +(?P<address>0x[0-9a-fA-F]{16}) "
40
- r"(?P<routine>[^+]+) [+] (?P<offset>\d+)" )
64
+ return parser .parse_args ()
65
+
66
+
67
+ def main ():
68
+ args = parse_args ()
41
69
42
70
lines = sys .stdin .readlines ()
43
71
44
72
found_stack_trace_start = False
45
73
found_stack_trace_entry = False
46
74
for line in lines :
47
- line = line .rstrip (" \n " )
75
+ line = line .rstrip (' \n ' )
48
76
49
77
# First see if we found the start of our stack trace start. If so, set
50
78
# the found stack trace flag and continue.
51
- if line == " Current stack trace:" :
79
+ if line == ' Current stack trace:' :
52
80
assert (not found_stack_trace_start )
53
81
found_stack_trace_start = True
54
82
continue
@@ -59,21 +87,19 @@ formatting.""")
59
87
continue
60
88
61
89
# Ok, we are in the middle of matching a stack trace entry.
62
- m = TARGET_RE .match (line )
90
+ matches = TARGET_PATTERN .match (line )
91
+
63
92
# If we fail to match, we have exited the stack trace entry region
64
- if m is None :
93
+ if matches is None :
65
94
break
66
95
67
96
# At this point, we know that we have some sort of match.
68
97
found_stack_trace_entry = True
69
- print ("Stack Trace Entry:" )
70
- print ("\t Index: '%(index)s'\n \t Object File: '%(object)s'\n \t Address: "
71
- "'%(address)s'\n \t Routine: '%(routine)s'\n \t Offset: '%(offset)s'"
72
- "\n " % m .groupdict ())
98
+ print (RESULTS_FORMAT .format (** matches .groupdict ()))
73
99
74
100
# Check for unavailable symbols, if that was requested.
75
101
if args .check_unavailable :
76
- assert (" unavailable" not in m .group (" routine" ))
102
+ assert (' unavailable' not in matches .group (' routine' ))
77
103
78
104
# Once we have processed all of the lines, make sure that we found at least
79
105
# one stack trace entry.
0 commit comments