builtin: improve backtrace on Windows

pull/4529/head
Alexey 2020-04-20 21:59:08 +03:00 committed by GitHub
parent cdb1b0344c
commit 9c0d97335e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 28 additions and 63 deletions

View File

@ -21,26 +21,6 @@ fn on_panic(f fn(int)int) {
}
*/
pub fn print_backtrace_skipping_top_frames(skipframes int) {
$if windows {
$if msvc {
if print_backtrace_skipping_top_frames_msvc(skipframes) {
return
}
}
$if mingw {
if print_backtrace_skipping_top_frames_mingw(skipframes) {
return
}
}
} $else {
if print_backtrace_skipping_top_frames_nix(skipframes) {
return
}
}
println('print_backtrace_skipping_top_frames is not implemented on this platform for now...\n')
}
pub fn print_backtrace() {
// at the time of backtrace_symbols_fd call, the C stack would look something like this:
// 1 frame for print_backtrace_skipping_top_frames

View File

@ -38,17 +38,7 @@ pub fn println(s string) {
C.printf('%.*s\n', s.len, s.str)
}
fn print_backtrace_skipping_top_frames_msvc(skipframes int) bool {
println('not implemented, see builtin_windows.v')
return false
}
fn print_backtrace_skipping_top_frames_mingw(skipframes int) bool {
println('not implemented, see builtin_windows.v')
return false
}
fn print_backtrace_skipping_top_frames_nix(xskipframes int) bool {
fn print_backtrace_skipping_top_frames(xskipframes int) bool {
skipframes := xskipframes + 2
$if macos {
return print_backtrace_skipping_top_frames_mac(skipframes)
@ -65,6 +55,7 @@ fn print_backtrace_skipping_top_frames_nix(xskipframes int) bool {
$if openbsd {
return print_backtrace_skipping_top_frames_freebsd(skipframes)
}
println('print_backtrace_skipping_top_frames is not implemented')
return false
}

View File

@ -65,8 +65,19 @@ fn builtin_init() {
}
}
fn print_backtrace_skipping_top_frames_msvc(skipframes int) bool {
fn print_backtrace_skipping_top_frames(skipframes int) bool {
$if msvc {
return print_backtrace_skipping_top_frames_msvc(skipframes)
}
$if mingw {
return print_backtrace_skipping_top_frames_mingw(skipframes)
}
println('print_backtrace_skipping_top_frames is not implemented')
return false
}
fn print_backtrace_skipping_top_frames_msvc(skipframes int) bool {
$if msvc {
mut offset := u64(0)
backtraces := [100]voidptr
@ -88,58 +99,41 @@ $if msvc {
return true
}
frames := int( C.CaptureStackBackTrace(skipframes + 1, 100, backtraces, 0) )
for i:=0; i < frames; i++ {
// fugly pointer arithmetics follows ...
// FIXME Remove temp variable
tmp := u64(backtraces) + u64(i * sizeof(voidptr))
s := &voidptr(tmp)
symfa_ok := C.SymFromAddr( handle, *s, &offset, si )
if symfa_ok == 1 {
frames := int(C.CaptureStackBackTrace(skipframes + 1, 100, backtraces, 0))
for i in 0..frames {
frame_addr := backtraces[i]
if C.SymFromAddr(handle, frame_addr, &offset, si) == 1 {
nframe := frames - i - 1
mut lineinfo := ''
symglfa_ok := C.SymGetLineFromAddr64(handle, *s, &offset, &sline64)
if symglfa_ok == 1 {
lineinfo = ' ${sline64.f_file_name}:${sline64.f_line_number}'
}
else {
//cerr := int(C.GetLastError()) println('SymGetLineFromAddr64 failure: $cerr ')
lineinfo = ' ?? : address= ${&s}'
if C.SymGetLineFromAddr64(handle, frame_addr, &offset, &sline64) == 1 {
file_name := tos3(sline64.f_file_name)
lineinfo = '${file_name}:${sline64.f_line_number}'
} else {
addr :
lineinfo = '?? : address = 0x${&frame_addr:x}'
}
sfunc := tos3(fname)
println('${nframe:-2d}: ${sfunc:-25s} $lineinfo')
}
else {
} else {
// https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes
cerr := int(C.GetLastError())
if cerr == 87 {
println('SymFromAddr failure: $cerr = The parameter is incorrect)')
}
else if cerr == 487 {
} else if cerr == 487 {
// probably caused because the .pdb isn't in the executable folder
println('SymFromAddr failure: $cerr = Attempt to access invalid address (Verify that you have the .pdb file in the right folder.)')
}
else {
} else {
println('SymFromAddr failure: $cerr (see https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes)')
}
}
}
return true
}
$else {
println('TODO: Not implemented on Windows without msvc.')
} $else {
return false
}
}
fn print_backtrace_skipping_top_frames_mingw(skipframes int) bool {
println('TODO: print_backtrace_skipping_top_frames_mingw($skipframes)')
return false
}
fn print_backtrace_skipping_top_frames_nix(skipframes int) bool {
println('not implemented, see builtin_nix.v')
return false
}