@@ -88,27 +88,55 @@ and so on.
88
88
function pregenerated_stacktrace (trace; topname = :capture_stacktrace )
89
89
usrtrace, defs = Method[], RelocatableExpr[]
90
90
methodsused = Set {Method} ()
91
+
92
+ function load_file (file, mod= Base)
93
+ ret = Revise. find_file (file, mod)
94
+ ret == nothing && return nothing
95
+ file, recipemod = ret
96
+ if ! haskey (Revise. fileinfos, file)
97
+ try
98
+ @info " tracking $recipemod "
99
+ Revise. track (recipemod)
100
+ catch err
101
+ err isa Revise. GitRepoException && return nothing
102
+ rethrow (err)
103
+ end
104
+ end
105
+ return file
106
+ end
107
+
108
+ # When the method can't be found directly in the tables,
109
+ # look it up by fie and line number
110
+ function add_by_file_line (defmap, sf)
111
+ for (def, info) in defmap
112
+ info == nothing && continue
113
+ sigts, offset = info
114
+ r = linerange (def, offset)
115
+ r == nothing && continue
116
+ if sf. line ∈ r
117
+ mths = Base. _methods_by_ftype (last (sigts), - 1 , typemax (UInt))
118
+ m = mths[end ][3 ] # the last method is the least specific that matches the signature (which would be more specific if it were used)
119
+ if m ∉ methodsused
120
+ push! (defs, def)
121
+ push! (usrtrace, m)
122
+ push! (methodsused, m)
123
+ return true
124
+ end
125
+ end
126
+ end
127
+ return false
128
+ end
129
+
91
130
for (i, sf) in enumerate (trace)
92
131
sf. func == topname && break # truncate at the chosen spot
93
132
sf. func ∈ notrace && continue
94
133
mi = sf. linfo
134
+ file = String (sf. file)
95
135
if mi isa Core. MethodInstance
96
136
method = mi. def
97
137
# Set up tracking, if necessary
98
- file = String (sf. file)
99
138
if ! haskey (Revise. fileinfos, file)
100
- ret = Revise. find_file (file, method. module)
101
- ret == nothing && continue
102
- file, recipemod = ret
103
- if ! haskey (Revise. fileinfos, file)
104
- try
105
- @info " tracking $recipemod "
106
- Revise. track (recipemod)
107
- catch err
108
- err isa Revise. GitRepoException && continue
109
- rethrow (err)
110
- end
111
- end
139
+ file = load_file (file, method. module)
112
140
end
113
141
haskey (Revise. fileinfos, file) || continue
114
142
fi = Revise. fileinfos[file]
@@ -118,31 +146,25 @@ function pregenerated_stacktrace(trace; topname = :capture_stacktrace)
118
146
# This is a generated method, perhaps it's a keyword function handler
119
147
# Look for it by line number
120
148
defmap = fi. fm[method. module]. defmap
121
- for (def, info) in defmap
122
- info == nothing && continue
123
- sigts, offset = info
124
- r = linerange (def, offset)
125
- r == nothing && continue
126
- if sf. line ∈ r
127
- mths = Base. _methods_by_ftype (last (sigts), - 1 , typemax (UInt))
128
- if length (mths) == 1
129
- m = mths[1 ][3 ]
130
- if m ∉ methodsused
131
- push! (defs, def)
132
- push! (usrtrace, m)
133
- push! (methodsused, m)
134
- break
135
- end
136
- end
137
- end
138
- end
149
+ add_by_file_line (defmap, sf)
139
150
else
140
151
method ∈ methodsused && continue
141
152
def = Revise. get_def (method; modified_files= String[])
142
153
def isa ExLike || continue
143
154
push! (defs, def)
144
155
push! (usrtrace, method)
145
156
end
157
+ else
158
+ # This method was inlined and hence linfo was not available
159
+ if ! haskey (Revise. fileinfos, file)
160
+ file = load_file (file)
161
+ end
162
+ haskey (Revise. fileinfos, file) || continue
163
+ fi = Revise. fileinfos[file]
164
+ Revise. maybe_parse_from_cache! (fi, file)
165
+ for (mod, fmm) in fi. fm
166
+ add_by_file_line (fmm. defmap, sf) && break
167
+ end
146
168
end
147
169
end
148
170
return usrtrace, defs
@@ -169,6 +191,7 @@ function capture_stacktrace(mod::Module, command::Expr)
169
191
end
170
192
errored || error (" $command did not throw an error" )
171
193
usrtrace, defs = pregenerated_stacktrace (trace)
194
+ isempty (usrtrace) && error (" failed to capture any elements of the stacktrace" )
172
195
println (stderr , " Captured elements of stacktrace:" )
173
196
show (stderr , MIME (" text/plain" ), usrtrace)
174
197
length (unique (usrtrace)) == length (usrtrace) || @error " the same method appeared twice, not supported. Try stepping into the command."
0 commit comments