FinalUserFrame returns the final frame that corresponds to the user code execution. That usually translates to the last frame before ntdll or kernel32 modules.
()
| 210 | // to the user code execution. That usually translates to |
| 211 | // the last frame before ntdll or kernel32 modules. |
| 212 | func (s *Callstack) FinalUserFrame() *Frame { |
| 213 | if s.IsEmpty() { |
| 214 | return nil |
| 215 | } |
| 216 | |
| 217 | var n int |
| 218 | for n = s.Depth() - 1; n > 0; n-- { |
| 219 | f := (*s)[n] |
| 220 | if f.Addr.InSystemRange() { |
| 221 | continue |
| 222 | } |
| 223 | mod := filepath.Base(strings.ToLower(f.Module)) |
| 224 | if mod != "ntdll.dll" && mod != "kernel32.dll" && mod != "kernelbase.dll" { |
| 225 | break |
| 226 | } |
| 227 | } |
| 228 | |
| 229 | if n >= 0 && n < s.Depth()-1 { |
| 230 | return &(*s)[n] |
| 231 | } |
| 232 | |
| 233 | return nil |
| 234 | } |
| 235 | |
| 236 | // FinalUserspaceFrame returns the final userspace frame. This |
| 237 | // frame is typically backed by the ntdll module. |