v / vlib / builtin
Raw file | 145 loc (136 sloc) | 3.72 KB | Latest commit hash 3da4f37b0
1// Copyright (c) 2019-2023 Alexander Medvednikov. All rights reserved.
2// Use of this source code is governed by an MIT license
3// that can be found in the LICENSE file.
4module builtin
5
6// pub fn vsyscall(id int
7//
8
9/*
10pub const (
11 sys_write = 1
12 sys_mkdir = 83
13)
14const (
15 stdin_value = 0
16 stdout_value = 1
17 stderr_value = 2
18)
19*/
20
21fn builtin_init() {
22 // Do nothing
23}
24
25fn print_backtrace_skipping_top_frames(xskipframes int) bool {
26 $if no_backtrace ? {
27 return false
28 } $else {
29 skipframes := xskipframes + 2
30 $if macos || freebsd || openbsd || netbsd {
31 return print_backtrace_skipping_top_frames_bsd(skipframes)
32 } $else $if linux {
33 return print_backtrace_skipping_top_frames_linux(skipframes)
34 } $else {
35 println('print_backtrace_skipping_top_frames is not implemented. skipframes: ${skipframes}')
36 }
37 }
38 return false
39}
40
41// the functions below are not called outside this file,
42// so there is no need to have their twins in builtin_windows.v
43fn print_backtrace_skipping_top_frames_bsd(skipframes int) bool {
44 $if no_backtrace ? {
45 return false
46 } $else {
47 $if macos || freebsd || netbsd {
48 buffer := [100]voidptr{}
49 nr_ptrs := C.backtrace(&buffer[0], 100)
50 if nr_ptrs < 2 {
51 eprintln('C.backtrace returned less than 2 frames')
52 return false
53 }
54 C.backtrace_symbols_fd(&buffer[skipframes], nr_ptrs - skipframes, 2)
55 }
56 return true
57 }
58}
59
60fn C.tcc_backtrace(fmt &char) int
61fn print_backtrace_skipping_top_frames_linux(skipframes int) bool {
62 $if android {
63 eprintln('On Android no backtrace is available.')
64 return false
65 }
66 $if !glibc {
67 eprintln('backtrace_symbols is missing => printing backtraces is not available.')
68 eprintln('Some libc implementations like musl simply do not provide it.')
69 return false
70 }
71 $if no_backtrace ? {
72 return false
73 } $else {
74 $if linux && !freestanding {
75 $if tinyc {
76 C.tcc_backtrace(c'Backtrace')
77 return false
78 } $else {
79 buffer := [100]voidptr{}
80 nr_ptrs := C.backtrace(&buffer[0], 100)
81 if nr_ptrs < 2 {
82 eprintln('C.backtrace returned less than 2 frames')
83 return false
84 }
85 nr_actual_frames := nr_ptrs - skipframes
86 mut sframes := []string{}
87 //////csymbols := backtrace_symbols(*voidptr(&buffer[skipframes]), nr_actual_frames)
88 csymbols := C.backtrace_symbols(voidptr(&buffer[skipframes]), nr_actual_frames)
89 for i in 0 .. nr_actual_frames {
90 sframes << unsafe { tos2(&u8(csymbols[i])) }
91 }
92 for sframe in sframes {
93 executable := sframe.all_before('(')
94 addr := sframe.all_after('[').all_before(']')
95 beforeaddr := sframe.all_before('[')
96 cmd := 'addr2line -e ${executable} ${addr}'
97 // taken from os, to avoid depending on the os module inside builtin.v
98 f := C.popen(&char(cmd.str), c'r')
99 if f == unsafe { nil } {
100 eprintln(sframe)
101 continue
102 }
103 buf := [1000]u8{}
104 mut output := ''
105 unsafe {
106 bp := &buf[0]
107 for C.fgets(&char(bp), 1000, f) != 0 {
108 output += tos(bp, vstrlen(bp))
109 }
110 }
111 output = output.trim_space() + ':'
112 if C.pclose(f) != 0 {
113 eprintln(sframe)
114 continue
115 }
116 if output in ['??:0:', '??:?:'] {
117 output = ''
118 }
119 // See http://wiki.dwarfstd.org/index.php?title=Path_Discriminators
120 // Note: it is shortened here to just d. , just so that it fits, and so
121 // that the common error file:lineno: line format is enforced.
122 output = output.replace(' (discriminator', ': (d.')
123 eprintln('${output:-55s} | ${addr:14s} | ${beforeaddr}')
124 }
125 }
126 }
127 }
128 return true
129}
130
131fn break_if_debugger_attached() {
132 unsafe {
133 mut ptr := &voidptr(0)
134 *ptr = nil
135 //_ = ptr
136 }
137}
138
139// These functions are Windows specific - provide dummys for *nix
140pub fn winapi_lasterr_str() string {
141 return ''
142}
143
144[noreturn]
145pub fn panic_lasterr() {}