authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-07-22 12:15:16-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-07-22 12:15:16-04:00
log5b69a9cd83d3ec7d3e54ac4c2c4635838aafe0de
tree344dd0bd3514779e1f0025a94431fd90178e86c0
parent32d0ac135556903dc016a64ff4d6b5cb9e35c84a
signaturelock-open Commit is signed but in an unrecognized format.

disable segfault handler when panicking

this prevents a segfault in stack trace printing to activate the segfault handler.

6 files changed, 192 insertions(+), 172 deletions(-)

src/codegen.cpp+141-136
...@@ -89,126 +89,6 @@ static const char *symbols_that_llvm_depends_on[] = {...@@ -89,126 +89,6 @@ static const char *symbols_that_llvm_depends_on[] = {
89 // TODO probably all of compiler-rt needs to go here89 // TODO probably all of compiler-rt needs to go here
90};90};
9191
92CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target,
93 OutType out_type, BuildMode build_mode, Buf *override_lib_dir, Buf *override_std_dir,
94 ZigLibCInstallation *libc, Buf *cache_dir)
95{
96 CodeGen *g = allocate<CodeGen>(1);
97
98 codegen_add_time_event(g, "Initialize");
99
100 g->subsystem = TargetSubsystemAuto;
101 g->libc = libc;
102 g->zig_target = target;
103 g->cache_dir = cache_dir;
104
105 if (override_lib_dir == nullptr) {
106 g->zig_lib_dir = get_zig_lib_dir();
107 } else {
108 g->zig_lib_dir = override_lib_dir;
109 }
110
111 if (override_std_dir == nullptr) {
112 g->zig_std_dir = buf_alloc();
113 os_path_join(g->zig_lib_dir, buf_create_from_str("std"), g->zig_std_dir);
114 } else {
115 g->zig_std_dir = override_std_dir;
116 }
117
118 g->zig_c_headers_dir = buf_alloc();
119 os_path_join(g->zig_lib_dir, buf_create_from_str("include"), g->zig_c_headers_dir);
120
121 g->build_mode = build_mode;
122 g->out_type = out_type;
123 g->import_table.init(32);
124 g->builtin_fn_table.init(32);
125 g->primitive_type_table.init(32);
126 g->type_table.init(32);
127 g->fn_type_table.init(32);
128 g->error_table.init(16);
129 g->generic_table.init(16);
130 g->llvm_fn_table.init(16);
131 g->memoized_fn_eval_table.init(16);
132 g->exported_symbol_names.init(8);
133 g->external_prototypes.init(8);
134 g->string_literals_table.init(16);
135 g->type_info_cache.init(32);
136 g->is_test_build = false;
137 g->is_single_threaded = false;
138 buf_resize(&g->global_asm, 0);
139
140 for (size_t i = 0; i < array_length(symbols_that_llvm_depends_on); i += 1) {
141 g->external_prototypes.put(buf_create_from_str(symbols_that_llvm_depends_on[i]), nullptr);
142 }
143
144 if (root_src_path) {
145 Buf *root_pkg_path;
146 Buf *rel_root_src_path;
147 if (main_pkg_path == nullptr) {
148 Buf *src_basename = buf_alloc();
149 Buf *src_dir = buf_alloc();
150 os_path_split(root_src_path, src_dir, src_basename);
151
152 if (buf_len(src_basename) == 0) {
153 fprintf(stderr, "Invalid root source path: %s\n", buf_ptr(root_src_path));
154 exit(1);
155 }
156 root_pkg_path = src_dir;
157 rel_root_src_path = src_basename;
158 } else {
159 Buf resolved_root_src_path = os_path_resolve(&root_src_path, 1);
160 Buf resolved_main_pkg_path = os_path_resolve(&main_pkg_path, 1);
161
162 if (!buf_starts_with_buf(&resolved_root_src_path, &resolved_main_pkg_path)) {
163 fprintf(stderr, "Root source path '%s' outside main package path '%s'",
164 buf_ptr(root_src_path), buf_ptr(main_pkg_path));
165 exit(1);
166 }
167 root_pkg_path = main_pkg_path;
168 rel_root_src_path = buf_create_from_mem(
169 buf_ptr(&resolved_root_src_path) + buf_len(&resolved_main_pkg_path) + 1,
170 buf_len(&resolved_root_src_path) - buf_len(&resolved_main_pkg_path) - 1);
171 }
172
173 g->root_package = new_package(buf_ptr(root_pkg_path), buf_ptr(rel_root_src_path), "");
174 g->std_package = new_package(buf_ptr(g->zig_std_dir), "std.zig", "std");
175 g->root_package->package_table.put(buf_create_from_str("std"), g->std_package);
176 } else {
177 g->root_package = new_package(".", "", "");
178 }
179
180 g->root_package->package_table.put(buf_create_from_str("root"), g->root_package);
181
182 g->zig_std_special_dir = buf_alloc();
183 os_path_join(g->zig_std_dir, buf_sprintf("special"), g->zig_std_special_dir);
184
185 assert(target != nullptr);
186 if (!target->is_native) {
187 g->each_lib_rpath = false;
188 } else {
189 g->each_lib_rpath = true;
190
191 if (target_os_is_darwin(g->zig_target->os)) {
192 init_darwin_native(g);
193 }
194
195 }
196
197 if (target_os_requires_libc(g->zig_target->os)) {
198 g->libc_link_lib = create_link_lib(buf_create_from_str("c"));
199 g->link_libs_list.append(g->libc_link_lib);
200 }
201
202 target_triple_llvm(&g->llvm_triple_str, g->zig_target);
203 g->pointer_size_bytes = target_arch_pointer_bit_width(g->zig_target->arch) / 8;
204
205 if (!target_has_debug_info(g->zig_target)) {
206 g->strip_debug_symbols = true;
207 }
208
209 return g;
210}
211
212void codegen_set_clang_argv(CodeGen *g, const char **args, size_t len) {92void codegen_set_clang_argv(CodeGen *g, const char **args, size_t len) {
213 g->clang_argv = args;93 g->clang_argv = args;
214 g->clang_argv_len = len;94 g->clang_argv_len = len;
...@@ -233,10 +113,6 @@ void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patc...@@ -233,10 +113,6 @@ void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patc
233 g->version_patch = patch;113 g->version_patch = patch;
234}114}
235115
236void codegen_set_is_test(CodeGen *g, bool is_test_build) {
237 g->is_test_build = is_test_build;
238}
239
240void codegen_set_emit_file_type(CodeGen *g, EmitFileType emit_file_type) {116void codegen_set_emit_file_type(CodeGen *g, EmitFileType emit_file_type) {
241 g->emit_file_type = emit_file_type;117 g->emit_file_type = emit_file_type;
242}118}
...@@ -7459,6 +7335,14 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {...@@ -7459,6 +7335,14 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
7459 return contents;7335 return contents;
7460}7336}
74617337
7338static ZigPackage *create_test_runner_pkg(CodeGen *g) {
7339 return codegen_create_package(g, buf_ptr(g->zig_std_special_dir), "test_runner.zig", "std.special");
7340}
7341
7342static ZigPackage *create_panic_pkg(CodeGen *g) {
7343 return codegen_create_package(g, buf_ptr(g->zig_std_special_dir), "panic.zig", "std.special");
7344}
7345
7462static Error define_builtin_compile_vars(CodeGen *g) {7346static Error define_builtin_compile_vars(CodeGen *g) {
7463 if (g->std_package == nullptr)7347 if (g->std_package == nullptr)
7464 return ErrorNone;7348 return ErrorNone;
...@@ -7543,8 +7427,16 @@ static Error define_builtin_compile_vars(CodeGen *g) {...@@ -7543,8 +7427,16 @@ static Error define_builtin_compile_vars(CodeGen *g) {
7543 g->root_package->package_table.put(buf_create_from_str("builtin"), g->compile_var_package);7427 g->root_package->package_table.put(buf_create_from_str("builtin"), g->compile_var_package);
7544 g->std_package->package_table.put(buf_create_from_str("builtin"), g->compile_var_package);7428 g->std_package->package_table.put(buf_create_from_str("builtin"), g->compile_var_package);
7545 g->std_package->package_table.put(buf_create_from_str("std"), g->std_package);7429 g->std_package->package_table.put(buf_create_from_str("std"), g->std_package);
7546 g->std_package->package_table.put(buf_create_from_str("root"),7430 ZigPackage *root_pkg;
7547 g->is_test_build ? g->test_runner_package : g->root_package);7431 if (g->is_test_build) {
7432 if (g->test_runner_package == nullptr) {
7433 g->test_runner_package = create_test_runner_pkg(g);
7434 }
7435 root_pkg = g->test_runner_package;
7436 } else {
7437 root_pkg = g->root_package;
7438 }
7439 g->std_package->package_table.put(buf_create_from_str("root"), root_pkg);
7548 g->compile_var_import = add_source_file(g, g->compile_var_package, builtin_zig_path, contents,7440 g->compile_var_import = add_source_file(g, g->compile_var_package, builtin_zig_path, contents,
7549 SourceKindPkgMain);7441 SourceKindPkgMain);
75507442
...@@ -8036,14 +7928,6 @@ static ZigPackage *create_start_pkg(CodeGen *g, ZigPackage *pkg_with_main) {...@@ -8036,14 +7928,6 @@ static ZigPackage *create_start_pkg(CodeGen *g, ZigPackage *pkg_with_main) {
8036 return package;7928 return package;
8037}7929}
80387930
8039static ZigPackage *create_test_runner_pkg(CodeGen *g) {
8040 return codegen_create_package(g, buf_ptr(g->zig_std_special_dir), "test_runner.zig", "std.special");
8041}
8042
8043static ZigPackage *create_panic_pkg(CodeGen *g) {
8044 return codegen_create_package(g, buf_ptr(g->zig_std_special_dir), "panic.zig", "std.special");
8045}
8046
8047static void create_test_compile_var_and_add_test_runner(CodeGen *g) {7931static void create_test_compile_var_and_add_test_runner(CodeGen *g) {
8048 Error err;7932 Error err;
80497933
...@@ -8093,7 +7977,7 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) {...@@ -8093,7 +7977,7 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) {
8093 ConstExprValue *test_fn_slice = create_const_slice(g, test_fn_array, 0, g->test_fns.length, true);7977 ConstExprValue *test_fn_slice = create_const_slice(g, test_fn_array, 0, g->test_fns.length, true);
80947978
8095 update_compile_var(g, buf_create_from_str("test_functions"), test_fn_slice);7979 update_compile_var(g, buf_create_from_str("test_functions"), test_fn_slice);
8096 g->test_runner_package = create_test_runner_pkg(g);7980 assert(g->test_runner_package != nullptr);
8097 g->test_runner_import = add_special_code(g, g->test_runner_package, "test_runner.zig");7981 g->test_runner_import = add_special_code(g, g->test_runner_package, "test_runner.zig");
8098}7982}
80997983
...@@ -9207,7 +9091,8 @@ CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType o...@@ -9207,7 +9091,8 @@ CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType o
9207 ZigLibCInstallation *libc)9091 ZigLibCInstallation *libc)
9208{9092{
9209 CodeGen *child_gen = codegen_create(nullptr, root_src_path, parent_gen->zig_target, out_type,9093 CodeGen *child_gen = codegen_create(nullptr, root_src_path, parent_gen->zig_target, out_type,
9210 parent_gen->build_mode, parent_gen->zig_lib_dir, parent_gen->zig_std_dir, libc, get_stage1_cache_path());9094 parent_gen->build_mode, parent_gen->zig_lib_dir, parent_gen->zig_std_dir, libc, get_stage1_cache_path(),
9095 false);
9211 child_gen->disable_gen_h = true;9096 child_gen->disable_gen_h = true;
9212 child_gen->want_stack_check = WantStackCheckDisabled;9097 child_gen->want_stack_check = WantStackCheckDisabled;
9213 child_gen->verbose_tokenize = parent_gen->verbose_tokenize;9098 child_gen->verbose_tokenize = parent_gen->verbose_tokenize;
...@@ -9234,3 +9119,123 @@ CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType o...@@ -9234,3 +9119,123 @@ CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType o
9234 return child_gen;9119 return child_gen;
9235}9120}
92369121
9122CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target,
9123 OutType out_type, BuildMode build_mode, Buf *override_lib_dir, Buf *override_std_dir,
9124 ZigLibCInstallation *libc, Buf *cache_dir, bool is_test_build)
9125{
9126 CodeGen *g = allocate<CodeGen>(1);
9127
9128 codegen_add_time_event(g, "Initialize");
9129
9130 g->subsystem = TargetSubsystemAuto;
9131 g->libc = libc;
9132 g->zig_target = target;
9133 g->cache_dir = cache_dir;
9134
9135 if (override_lib_dir == nullptr) {
9136 g->zig_lib_dir = get_zig_lib_dir();
9137 } else {
9138 g->zig_lib_dir = override_lib_dir;
9139 }
9140
9141 if (override_std_dir == nullptr) {
9142 g->zig_std_dir = buf_alloc();
9143 os_path_join(g->zig_lib_dir, buf_create_from_str("std"), g->zig_std_dir);
9144 } else {
9145 g->zig_std_dir = override_std_dir;
9146 }
9147
9148 g->zig_c_headers_dir = buf_alloc();
9149 os_path_join(g->zig_lib_dir, buf_create_from_str("include"), g->zig_c_headers_dir);
9150
9151 g->build_mode = build_mode;
9152 g->out_type = out_type;
9153 g->import_table.init(32);
9154 g->builtin_fn_table.init(32);
9155 g->primitive_type_table.init(32);
9156 g->type_table.init(32);
9157 g->fn_type_table.init(32);
9158 g->error_table.init(16);
9159 g->generic_table.init(16);
9160 g->llvm_fn_table.init(16);
9161 g->memoized_fn_eval_table.init(16);
9162 g->exported_symbol_names.init(8);
9163 g->external_prototypes.init(8);
9164 g->string_literals_table.init(16);
9165 g->type_info_cache.init(32);
9166 g->is_test_build = is_test_build;
9167 g->is_single_threaded = false;
9168 buf_resize(&g->global_asm, 0);
9169
9170 for (size_t i = 0; i < array_length(symbols_that_llvm_depends_on); i += 1) {
9171 g->external_prototypes.put(buf_create_from_str(symbols_that_llvm_depends_on[i]), nullptr);
9172 }
9173
9174 if (root_src_path) {
9175 Buf *root_pkg_path;
9176 Buf *rel_root_src_path;
9177 if (main_pkg_path == nullptr) {
9178 Buf *src_basename = buf_alloc();
9179 Buf *src_dir = buf_alloc();
9180 os_path_split(root_src_path, src_dir, src_basename);
9181
9182 if (buf_len(src_basename) == 0) {
9183 fprintf(stderr, "Invalid root source path: %s\n", buf_ptr(root_src_path));
9184 exit(1);
9185 }
9186 root_pkg_path = src_dir;
9187 rel_root_src_path = src_basename;
9188 } else {
9189 Buf resolved_root_src_path = os_path_resolve(&root_src_path, 1);
9190 Buf resolved_main_pkg_path = os_path_resolve(&main_pkg_path, 1);
9191
9192 if (!buf_starts_with_buf(&resolved_root_src_path, &resolved_main_pkg_path)) {
9193 fprintf(stderr, "Root source path '%s' outside main package path '%s'",
9194 buf_ptr(root_src_path), buf_ptr(main_pkg_path));
9195 exit(1);
9196 }
9197 root_pkg_path = main_pkg_path;
9198 rel_root_src_path = buf_create_from_mem(
9199 buf_ptr(&resolved_root_src_path) + buf_len(&resolved_main_pkg_path) + 1,
9200 buf_len(&resolved_root_src_path) - buf_len(&resolved_main_pkg_path) - 1);
9201 }
9202
9203 g->root_package = new_package(buf_ptr(root_pkg_path), buf_ptr(rel_root_src_path), "");
9204 g->std_package = new_package(buf_ptr(g->zig_std_dir), "std.zig", "std");
9205 g->root_package->package_table.put(buf_create_from_str("std"), g->std_package);
9206 } else {
9207 g->root_package = new_package(".", "", "");
9208 }
9209
9210 g->root_package->package_table.put(buf_create_from_str("root"), g->root_package);
9211
9212 g->zig_std_special_dir = buf_alloc();
9213 os_path_join(g->zig_std_dir, buf_sprintf("special"), g->zig_std_special_dir);
9214
9215 assert(target != nullptr);
9216 if (!target->is_native) {
9217 g->each_lib_rpath = false;
9218 } else {
9219 g->each_lib_rpath = true;
9220
9221 if (target_os_is_darwin(g->zig_target->os)) {
9222 init_darwin_native(g);
9223 }
9224
9225 }
9226
9227 if (target_os_requires_libc(g->zig_target->os)) {
9228 g->libc_link_lib = create_link_lib(buf_create_from_str("c"));
9229 g->link_libs_list.append(g->libc_link_lib);
9230 }
9231
9232 target_triple_llvm(&g->llvm_triple_str, g->zig_target);
9233 g->pointer_size_bytes = target_arch_pointer_bit_width(g->zig_target->arch) / 8;
9234
9235 if (!target_has_debug_info(g->zig_target)) {
9236 g->strip_debug_symbols = true;
9237 }
9238
9239 return g;
9240}
9241
src/codegen.hpp+1-2
...@@ -18,14 +18,13 @@...@@ -18,14 +18,13 @@
1818
19CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target,19CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target,
20 OutType out_type, BuildMode build_mode, Buf *zig_lib_dir, Buf *override_std_dir,20 OutType out_type, BuildMode build_mode, Buf *zig_lib_dir, Buf *override_std_dir,
21 ZigLibCInstallation *libc, Buf *cache_dir);21 ZigLibCInstallation *libc, Buf *cache_dir, bool is_test_build);
2222
23CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType out_type,23CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType out_type,
24 ZigLibCInstallation *libc);24 ZigLibCInstallation *libc);
2525
26void codegen_set_clang_argv(CodeGen *codegen, const char **args, size_t len);26void codegen_set_clang_argv(CodeGen *codegen, const char **args, size_t len);
27void codegen_set_llvm_argv(CodeGen *codegen, const char **args, size_t len);27void codegen_set_llvm_argv(CodeGen *codegen, const char **args, size_t len);
28void codegen_set_is_test(CodeGen *codegen, bool is_test);
29void codegen_set_each_lib_rpath(CodeGen *codegen, bool each_lib_rpath);28void codegen_set_each_lib_rpath(CodeGen *codegen, bool each_lib_rpath);
3029
31void codegen_set_emit_file_type(CodeGen *g, EmitFileType emit_file_type);30void codegen_set_emit_file_type(CodeGen *g, EmitFileType emit_file_type);
src/main.cpp+3-4
...@@ -583,7 +583,7 @@ int main(int argc, char **argv) {...@@ -583,7 +583,7 @@ int main(int argc, char **argv) {
583 }583 }
584584
585 CodeGen *g = codegen_create(main_pkg_path, build_runner_path, &target, OutTypeExe,585 CodeGen *g = codegen_create(main_pkg_path, build_runner_path, &target, OutTypeExe,
586 BuildModeDebug, override_lib_dir, override_std_dir, nullptr, &full_cache_dir);586 BuildModeDebug, override_lib_dir, override_std_dir, nullptr, &full_cache_dir, false);
587 g->valgrind_support = valgrind_support;587 g->valgrind_support = valgrind_support;
588 g->enable_time_report = timing_info;588 g->enable_time_report = timing_info;
589 codegen_set_out_name(g, buf_create_from_str("build"));589 codegen_set_out_name(g, buf_create_from_str("build"));
...@@ -1011,7 +1011,7 @@ int main(int argc, char **argv) {...@@ -1011,7 +1011,7 @@ int main(int argc, char **argv) {
1011 }1011 }
1012 case CmdBuiltin: {1012 case CmdBuiltin: {
1013 CodeGen *g = codegen_create(main_pkg_path, nullptr, &target,1013 CodeGen *g = codegen_create(main_pkg_path, nullptr, &target,
1014 out_type, build_mode, override_lib_dir, override_std_dir, nullptr, nullptr);1014 out_type, build_mode, override_lib_dir, override_std_dir, nullptr, nullptr, false);
1015 codegen_set_strip(g, strip);1015 codegen_set_strip(g, strip);
1016 for (size_t i = 0; i < link_libs.length; i += 1) {1016 for (size_t i = 0; i < link_libs.length; i += 1) {
1017 LinkLib *link_lib = codegen_add_link_lib(g, buf_create_from_str(link_libs.at(i)));1017 LinkLib *link_lib = codegen_add_link_lib(g, buf_create_from_str(link_libs.at(i)));
...@@ -1115,7 +1115,7 @@ int main(int argc, char **argv) {...@@ -1115,7 +1115,7 @@ int main(int argc, char **argv) {
1115 cache_dir_buf = buf_create_from_str(cache_dir);1115 cache_dir_buf = buf_create_from_str(cache_dir);
1116 }1116 }
1117 CodeGen *g = codegen_create(main_pkg_path, zig_root_source_file, &target, out_type, build_mode,1117 CodeGen *g = codegen_create(main_pkg_path, zig_root_source_file, &target, out_type, build_mode,
1118 override_lib_dir, override_std_dir, libc, cache_dir_buf);1118 override_lib_dir, override_std_dir, libc, cache_dir_buf, cmd == CmdTest);
1119 if (llvm_argv.length >= 2) codegen_set_llvm_argv(g, llvm_argv.items + 1, llvm_argv.length - 2);1119 if (llvm_argv.length >= 2) codegen_set_llvm_argv(g, llvm_argv.items + 1, llvm_argv.length - 2);
1120 g->valgrind_support = valgrind_support;1120 g->valgrind_support = valgrind_support;
1121 g->want_pic = want_pic;1121 g->want_pic = want_pic;
...@@ -1125,7 +1125,6 @@ int main(int argc, char **argv) {...@@ -1125,7 +1125,6 @@ int main(int argc, char **argv) {
1125 g->enable_time_report = timing_info;1125 g->enable_time_report = timing_info;
1126 codegen_set_out_name(g, buf_out_name);1126 codegen_set_out_name(g, buf_out_name);
1127 codegen_set_lib_version(g, ver_major, ver_minor, ver_patch);1127 codegen_set_lib_version(g, ver_major, ver_minor, ver_patch);
1128 codegen_set_is_test(g, cmd == CmdTest);
1129 g->want_single_threaded = want_single_threaded;1128 g->want_single_threaded = want_single_threaded;
1130 codegen_set_linker_script(g, linker_script);1129 codegen_set_linker_script(g, linker_script);
1131 g->version_script_path = version_script; 1130 g->version_script_path = version_script;
std/debug.zig+44-18
...@@ -12,6 +12,7 @@ const coff = std.coff;...@@ -12,6 +12,7 @@ const coff = std.coff;
12const pdb = std.pdb;12const pdb = std.pdb;
13const ArrayList = std.ArrayList;13const ArrayList = std.ArrayList;
14const builtin = @import("builtin");14const builtin = @import("builtin");
15const root = @import("root");
15const maxInt = std.math.maxInt;16const maxInt = std.math.maxInt;
16const File = std.fs.File;17const File = std.fs.File;
17const windows = std.os.windows;18const windows = std.os.windows;
...@@ -217,6 +218,12 @@ var panicking: u8 = 0; // TODO make this a bool...@@ -217,6 +218,12 @@ var panicking: u8 = 0; // TODO make this a bool
217pub fn panicExtra(trace: ?*const builtin.StackTrace, first_trace_addr: ?usize, comptime format: []const u8, args: ...) noreturn {218pub fn panicExtra(trace: ?*const builtin.StackTrace, first_trace_addr: ?usize, comptime format: []const u8, args: ...) noreturn {
218 @setCold(true);219 @setCold(true);
219220
221 if (enable_segfault_handler) {
222 // If a segfault happens while panicking, we want it to actually segfault, not trigger
223 // the handler.
224 resetSegfaultHandler();
225 }
226
220 if (@atomicRmw(u8, &panicking, builtin.AtomicRmwOp.Xchg, 1, builtin.AtomicOrder.SeqCst) == 1) {227 if (@atomicRmw(u8, &panicking, builtin.AtomicRmwOp.Xchg, 1, builtin.AtomicOrder.SeqCst) == 1) {
221 // Panicked during a panic.228 // Panicked during a panic.
222229
...@@ -2312,39 +2319,58 @@ fn getDebugInfoAllocator() *mem.Allocator {...@@ -2312,39 +2319,58 @@ fn getDebugInfoAllocator() *mem.Allocator {
23122319
2313/// Whether or not the current target can print useful debug information when a segfault occurs.2320/// Whether or not the current target can print useful debug information when a segfault occurs.
2314pub const have_segfault_handling_support = (builtin.arch == builtin.Arch.x86_64 and builtin.os == .linux) or builtin.os == .windows;2321pub const have_segfault_handling_support = (builtin.arch == builtin.Arch.x86_64 and builtin.os == .linux) or builtin.os == .windows;
2322pub const enable_segfault_handler: bool = if (@hasDecl(root, "enable_segfault_handler"))
2323 root.enable_segfault_handler
2324else
2325 runtime_safety and have_segfault_handling_support;
2326
2327pub fn maybeEnableSegfaultHandler() void {
2328 if (enable_segfault_handler) {
2329 std.debug.attachSegfaultHandler();
2330 }
2331}
2332
2333var windows_segfault_handle: ?windows.HANDLE = null;
23152334
2316/// Attaches a global SIGSEGV handler which calls @panic("segmentation fault");2335/// Attaches a global SIGSEGV handler which calls @panic("segmentation fault");
2317pub fn attachSegfaultHandler() void {2336pub fn attachSegfaultHandler() void {
2318 if (!have_segfault_handling_support) {2337 if (!have_segfault_handling_support) {
2319 @compileError("segfault handler not supported for this target");2338 @compileError("segfault handler not supported for this target");
2320 }2339 }
2321 switch (builtin.os) {2340 if (windows.is_the_target) {
2322 .linux => {2341 windows_segfault_handle = windows.kernel32.AddVectoredExceptionHandler(0, handleSegfaultWindows);
2323 var act = os.Sigaction{2342 return;
2324 .sigaction = handleSegfaultLinux,
2325 .mask = os.empty_sigset,
2326 .flags = (os.SA_SIGINFO | os.SA_RESTART | os.SA_RESETHAND),
2327 };
2328
2329 os.sigaction(os.SIGSEGV, &act, null);
2330 },
2331 .windows => {
2332 _ = windows.kernel32.AddVectoredExceptionHandler(0, handleSegfaultWindows);
2333 },
2334 else => unreachable,
2335 }2343 }
2344 var act = os.Sigaction{
2345 .sigaction = handleSegfaultLinux,
2346 .mask = os.empty_sigset,
2347 .flags = (os.SA_SIGINFO | os.SA_RESTART | os.SA_RESETHAND),
2348 };
2349
2350 os.sigaction(os.SIGSEGV, &act, null);
2336}2351}
23372352
2338extern fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: *const c_void) noreturn {2353fn resetSegfaultHandler() void {
2339 // Reset to the default handler so that if a segfault happens in this handler it will crash2354 if (windows.is_the_target) {
2340 // the process. Also when this handler returns, the original instruction will be repeated2355 if (windows_segfault_handle) |handle| {
2341 // and the resulting segfault will crash the process rather than continually dump stack traces.2356 assert(windows.kernel32.RemoveVectoredExceptionHandler() != 0);
2357 windows_segfault_handle = null;
2358 }
2359 return;
2360 }
2342 var act = os.Sigaction{2361 var act = os.Sigaction{
2343 .sigaction = os.SIG_DFL,2362 .sigaction = os.SIG_DFL,
2344 .mask = os.empty_sigset,2363 .mask = os.empty_sigset,
2345 .flags = 0,2364 .flags = 0,
2346 };2365 };
2347 os.sigaction(os.SIGSEGV, &act, null);2366 os.sigaction(os.SIGSEGV, &act, null);
2367}
2368
2369extern fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: *const c_void) noreturn {
2370 // Reset to the default handler so that if a segfault happens in this handler it will crash
2371 // the process. Also when this handler returns, the original instruction will be repeated
2372 // and the resulting segfault will crash the process rather than continually dump stack traces.
2373 resetSegfaultHandler();
23482374
2349 const ctx = @ptrCast(*const os.ucontext_t, @alignCast(@alignOf(os.ucontext_t), ctx_ptr));2375 const ctx = @ptrCast(*const os.ucontext_t, @alignCast(@alignOf(os.ucontext_t), ctx_ptr));
2350 const ip = @intCast(usize, ctx.mcontext.gregs[os.REG_RIP]);2376 const ip = @intCast(usize, ctx.mcontext.gregs[os.REG_RIP]);
std/os/windows/kernel32.zig+1
...@@ -1,6 +1,7 @@...@@ -1,6 +1,7 @@
1usingnamespace @import("bits.zig");1usingnamespace @import("bits.zig");
22
3pub extern "kernel32" stdcallcc fn AddVectoredExceptionHandler(First: c_ulong, Handler: ?VECTORED_EXCEPTION_HANDLER) ?*c_void;3pub extern "kernel32" stdcallcc fn AddVectoredExceptionHandler(First: c_ulong, Handler: ?VECTORED_EXCEPTION_HANDLER) ?*c_void;
4pub extern "kernel32" stdcallcc fn RemoveVectoredExceptionHandler(Handle: HANDLE) c_ulong;
45
5pub extern "kernel32" stdcallcc fn CancelIoEx(hFile: HANDLE, lpOverlapped: LPOVERLAPPED) BOOL;6pub extern "kernel32" stdcallcc fn CancelIoEx(hFile: HANDLE, lpOverlapped: LPOVERLAPPED) BOOL;
67
std/special/start.zig+2-12
...@@ -24,16 +24,6 @@ comptime {...@@ -24,16 +24,6 @@ comptime {
24 }24 }
25}25}
2626
27fn enableSegfaultHandler() void {
28 const enable_segfault_handler: bool = if (@hasDecl(root, "enable_segfault_handler"))
29 root.enable_segfault_handler
30 else
31 std.debug.runtime_safety and std.debug.have_segfault_handling_support;
32 if (enable_segfault_handler) {
33 std.debug.attachSegfaultHandler();
34 }
35}
36
37extern fn wasm_freestanding_start() void {27extern fn wasm_freestanding_start() void {
38 _ = callMain();28 _ = callMain();
39}29}
...@@ -72,7 +62,7 @@ extern fn WinMainCRTStartup() noreturn {...@@ -72,7 +62,7 @@ extern fn WinMainCRTStartup() noreturn {
72 _ = @import("start_windows_tls.zig");62 _ = @import("start_windows_tls.zig");
73 }63 }
7464
75 enableSegfaultHandler();65 std.debug.maybeEnableSegfaultHandler();
7666
77 std.os.windows.kernel32.ExitProcess(callMain());67 std.os.windows.kernel32.ExitProcess(callMain());
78}68}
...@@ -113,7 +103,7 @@ inline fn callMainWithArgs(argc: usize, argv: [*][*]u8, envp: [][*]u8) u8 {...@@ -113,7 +103,7 @@ inline fn callMainWithArgs(argc: usize, argv: [*][*]u8, envp: [][*]u8) u8 {
113 std.os.argv = argv[0..argc];103 std.os.argv = argv[0..argc];
114 std.os.environ = envp;104 std.os.environ = envp;
115105
116 enableSegfaultHandler();106 std.debug.maybeEnableSegfaultHandler();
117107
118 return callMain();108 return callMain();
119}109}