Skip to content

Commit

Permalink
builtin: improve backtrace on Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
alexesprit authored Apr 20, 2020
1 parent cdb1b03 commit 9c0d973
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 63 deletions.
20 changes: 0 additions & 20 deletions vlib/builtin/builtin.v
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 2 additions & 11 deletions vlib/builtin/builtin_nix.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
}

Expand Down
58 changes: 26 additions & 32 deletions vlib/builtin/builtin_windows.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
}

Expand Down

0 comments on commit 9c0d973

Please sign in to comment.