builtin: improve backtrace on Windows
parent
cdb1b0344c
commit
9c0d97335e
|
@ -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() {
|
pub fn print_backtrace() {
|
||||||
// at the time of backtrace_symbols_fd call, the C stack would look something like this:
|
// at the time of backtrace_symbols_fd call, the C stack would look something like this:
|
||||||
// 1 frame for print_backtrace_skipping_top_frames
|
// 1 frame for print_backtrace_skipping_top_frames
|
||||||
|
|
|
@ -38,17 +38,7 @@ pub fn println(s string) {
|
||||||
C.printf('%.*s\n', s.len, s.str)
|
C.printf('%.*s\n', s.len, s.str)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_backtrace_skipping_top_frames_msvc(skipframes int) bool {
|
fn print_backtrace_skipping_top_frames(xskipframes 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 {
|
|
||||||
skipframes := xskipframes + 2
|
skipframes := xskipframes + 2
|
||||||
$if macos {
|
$if macos {
|
||||||
return print_backtrace_skipping_top_frames_mac(skipframes)
|
return print_backtrace_skipping_top_frames_mac(skipframes)
|
||||||
|
@ -65,6 +55,7 @@ fn print_backtrace_skipping_top_frames_nix(xskipframes int) bool {
|
||||||
$if openbsd {
|
$if openbsd {
|
||||||
return print_backtrace_skipping_top_frames_freebsd(skipframes)
|
return print_backtrace_skipping_top_frames_freebsd(skipframes)
|
||||||
}
|
}
|
||||||
|
println('print_backtrace_skipping_top_frames is not implemented')
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
$if msvc {
|
||||||
mut offset := u64(0)
|
mut offset := u64(0)
|
||||||
backtraces := [100]voidptr
|
backtraces := [100]voidptr
|
||||||
|
@ -88,58 +99,41 @@ $if msvc {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
frames := int( C.CaptureStackBackTrace(skipframes + 1, 100, backtraces, 0) )
|
frames := int(C.CaptureStackBackTrace(skipframes + 1, 100, backtraces, 0))
|
||||||
for i:=0; i < frames; i++ {
|
for i in 0..frames {
|
||||||
// fugly pointer arithmetics follows ...
|
frame_addr := backtraces[i]
|
||||||
// FIXME Remove temp variable
|
if C.SymFromAddr(handle, frame_addr, &offset, si) == 1 {
|
||||||
tmp := u64(backtraces) + u64(i * sizeof(voidptr))
|
|
||||||
s := &voidptr(tmp)
|
|
||||||
symfa_ok := C.SymFromAddr( handle, *s, &offset, si )
|
|
||||||
if symfa_ok == 1 {
|
|
||||||
nframe := frames - i - 1
|
nframe := frames - i - 1
|
||||||
mut lineinfo := ''
|
mut lineinfo := ''
|
||||||
symglfa_ok := C.SymGetLineFromAddr64(handle, *s, &offset, &sline64)
|
if C.SymGetLineFromAddr64(handle, frame_addr, &offset, &sline64) == 1 {
|
||||||
if symglfa_ok == 1 {
|
file_name := tos3(sline64.f_file_name)
|
||||||
lineinfo = ' ${sline64.f_file_name}:${sline64.f_line_number}'
|
lineinfo = '${file_name}:${sline64.f_line_number}'
|
||||||
}
|
} else {
|
||||||
else {
|
addr :
|
||||||
//cerr := int(C.GetLastError()) println('SymGetLineFromAddr64 failure: $cerr ')
|
lineinfo = '?? : address = 0x${&frame_addr:x}'
|
||||||
lineinfo = ' ?? : address= ${&s}'
|
|
||||||
}
|
}
|
||||||
sfunc := tos3(fname)
|
sfunc := tos3(fname)
|
||||||
println('${nframe:-2d}: ${sfunc:-25s} $lineinfo')
|
println('${nframe:-2d}: ${sfunc:-25s} $lineinfo')
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes
|
// https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes
|
||||||
cerr := int(C.GetLastError())
|
cerr := int(C.GetLastError())
|
||||||
if cerr == 87 {
|
if cerr == 87 {
|
||||||
println('SymFromAddr failure: $cerr = The parameter is incorrect)')
|
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
|
// 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.)')
|
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)')
|
println('SymFromAddr failure: $cerr (see https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes)')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
} $else {
|
||||||
$else {
|
|
||||||
println('TODO: Not implemented on Windows without msvc.')
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn print_backtrace_skipping_top_frames_mingw(skipframes int) bool {
|
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
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue