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. |
4 | module builtin |
5 | |
6 | // pub fn vsyscall(id int |
7 | // |
8 | |
9 | /* |
10 | pub const ( |
11 | sys_write = 1 |
12 | sys_mkdir = 83 |
13 | ) |
14 | const ( |
15 | stdin_value = 0 |
16 | stdout_value = 1 |
17 | stderr_value = 2 |
18 | ) |
19 | */ |
20 | |
21 | fn builtin_init() { |
22 | // Do nothing |
23 | } |
24 | |
25 | fn 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 |
43 | fn 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 | |
60 | fn C.tcc_backtrace(fmt &char) int |
61 | fn 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 | |
131 | fn 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 |
140 | pub fn winapi_lasterr_str() string { |
141 | return '' |
142 | } |
143 | |
144 | [noreturn] |
145 | pub fn panic_lasterr() {} |