authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-01-14 19:40:02-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-01-14 19:40:02-05:00
logd973b40884be1c7874805c81981cac7edca5605b
treeaac4046ebfdcf920b54a6a62ba342f2476807f98
parentf0df2cdde9181f954dc124dab004663e56c86d0f

stack traces are a variable number of frames


1 files changed, 43 insertions(+), 14 deletions(-)

src/codegen.cpp+43-14
...@@ -22,8 +22,6 @@...@@ -22,8 +22,6 @@
22#include <stdio.h>22#include <stdio.h>
23#include <errno.h>23#include <errno.h>
2424
25static const size_t stack_trace_ptr_count = 31;
26
27static void init_darwin_native(CodeGen *g) {25static void init_darwin_native(CodeGen *g) {
28 char *osx_target = getenv("MACOSX_DEPLOYMENT_TARGET");26 char *osx_target = getenv("MACOSX_DEPLOYMENT_TARGET");
29 char *ios_target = getenv("IPHONEOS_DEPLOYMENT_TARGET");27 char *ios_target = getenv("IPHONEOS_DEPLOYMENT_TARGET");
...@@ -958,7 +956,7 @@ static LLVMValueRef get_return_err_fn(CodeGen *g) {...@@ -958,7 +956,7 @@ static LLVMValueRef get_return_err_fn(CodeGen *g) {
958956
959 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->type_ref;957 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->type_ref;
960958
961 // stack_trace.instruction_addresses[stack_trace.index % stack_trace_ptr_count] = return_address;959 // stack_trace.instruction_addresses[stack_trace.index % stack_trace.instruction_addresses.len] = return_address;
962960
963 LLVMValueRef err_ret_trace_ptr = LLVMGetParam(fn_val, 0);961 LLVMValueRef err_ret_trace_ptr = LLVMGetParam(fn_val, 0);
964 size_t index_field_index = g->stack_trace_type->data.structure.fields[0].gen_index;962 size_t index_field_index = g->stack_trace_type->data.structure.fields[0].gen_index;
...@@ -966,13 +964,21 @@ static LLVMValueRef get_return_err_fn(CodeGen *g) {...@@ -966,13 +964,21 @@ static LLVMValueRef get_return_err_fn(CodeGen *g) {
966 size_t addresses_field_index = g->stack_trace_type->data.structure.fields[1].gen_index;964 size_t addresses_field_index = g->stack_trace_type->data.structure.fields[1].gen_index;
967 LLVMValueRef addresses_field_ptr = LLVMBuildStructGEP(g->builder, err_ret_trace_ptr, (unsigned)addresses_field_index, "");965 LLVMValueRef addresses_field_ptr = LLVMBuildStructGEP(g->builder, err_ret_trace_ptr, (unsigned)addresses_field_index, "");
968966
967 TypeTableEntry *slice_type = g->stack_trace_type->data.structure.fields[1].type_entry;
968 size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index].gen_index;
969 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)ptr_field_index, "");
970 size_t len_field_index = slice_type->data.structure.fields[slice_len_index].gen_index;
971 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)len_field_index, "");
972
973 LLVMValueRef len_value = gen_load_untyped(g, len_field_ptr, 0, false, "");
969 LLVMValueRef index_val = gen_load_untyped(g, index_field_ptr, 0, false, "");974 LLVMValueRef index_val = gen_load_untyped(g, index_field_ptr, 0, false, "");
970 LLVMValueRef modded_val = LLVMBuildURem(g->builder, index_val, LLVMConstInt(usize_type_ref, stack_trace_ptr_count, false), "");975 LLVMValueRef modded_val = LLVMBuildURem(g->builder, index_val, len_value, "");
971 LLVMValueRef address_indices[] = {976 LLVMValueRef address_indices[] = {
972 LLVMConstNull(usize_type_ref),
973 modded_val,977 modded_val,
974 };978 };
975 LLVMValueRef address_slot = LLVMBuildInBoundsGEP(g->builder, addresses_field_ptr, address_indices, 2, "");979
980 LLVMValueRef ptr_value = gen_load_untyped(g, ptr_field_ptr, 0, false, "");
981 LLVMValueRef address_slot = LLVMBuildInBoundsGEP(g->builder, ptr_value, address_indices, 1, "");
976982
977 LLVMValueRef return_address = LLVMBuildPtrToInt(g->builder, LLVMGetParam(fn_val, 1), usize_type_ref, "");983 LLVMValueRef return_address = LLVMBuildPtrToInt(g->builder, LLVMGetParam(fn_val, 1), usize_type_ref, "");
978984
...@@ -1052,8 +1058,8 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {...@@ -1052,8 +1058,8 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
10521058
1053 Buf *fn_name = get_mangled_name(g, buf_create_from_str("__zig_fail_unwrap"), false);1059 Buf *fn_name = get_mangled_name(g, buf_create_from_str("__zig_fail_unwrap"), false);
1054 LLVMTypeRef arg_types[] = {1060 LLVMTypeRef arg_types[] = {
1055 g->err_tag_type->type_ref,
1056 g->ptr_to_stack_trace_type->type_ref,1061 g->ptr_to_stack_trace_type->type_ref,
1062 g->err_tag_type->type_ref,
1057 };1063 };
1058 LLVMTypeRef fn_type_ref = LLVMFunctionType(LLVMVoidType(), arg_types, 2, false);1064 LLVMTypeRef fn_type_ref = LLVMFunctionType(LLVMVoidType(), arg_types, 2, false);
1059 LLVMValueRef fn_val = LLVMAddFunction(g->module, buf_ptr(fn_name), fn_type_ref);1065 LLVMValueRef fn_val = LLVMAddFunction(g->module, buf_ptr(fn_name), fn_type_ref);
...@@ -1077,7 +1083,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {...@@ -1077,7 +1083,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
1077 LLVMPositionBuilderAtEnd(g->builder, entry_block);1083 LLVMPositionBuilderAtEnd(g->builder, entry_block);
1078 ZigLLVMClearCurrentDebugLocation(g->builder);1084 ZigLLVMClearCurrentDebugLocation(g->builder);
10791085
1080 LLVMValueRef err_val = LLVMGetParam(fn_val, 0);1086 LLVMValueRef err_val = LLVMGetParam(fn_val, 1);
10811087
1082 LLVMValueRef err_table_indices[] = {1088 LLVMValueRef err_table_indices[] = {
1083 LLVMConstNull(g->builtin_types.entry_usize->type_ref),1089 LLVMConstNull(g->builtin_types.entry_usize->type_ref),
...@@ -1107,7 +1113,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {...@@ -1107,7 +1113,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
1107 LLVMValueRef global_slice_len_field_ptr = LLVMBuildStructGEP(g->builder, global_slice, slice_len_index, "");1113 LLVMValueRef global_slice_len_field_ptr = LLVMBuildStructGEP(g->builder, global_slice, slice_len_index, "");
1108 gen_store(g, full_buf_len, global_slice_len_field_ptr, u8_ptr_type);1114 gen_store(g, full_buf_len, global_slice_len_field_ptr, u8_ptr_type);
11091115
1110 gen_panic(g, global_slice, LLVMGetParam(fn_val, 1));1116 gen_panic(g, global_slice, LLVMGetParam(fn_val, 0));
11111117
1112 LLVMPositionBuilderAtEnd(g->builder, prev_block);1118 LLVMPositionBuilderAtEnd(g->builder, prev_block);
1113 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);1119 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
...@@ -1124,8 +1130,8 @@ static void gen_debug_safety_crash_for_err(CodeGen *g, LLVMValueRef err_val) {...@@ -1124,8 +1130,8 @@ static void gen_debug_safety_crash_for_err(CodeGen *g, LLVMValueRef err_val) {
1124 err_ret_trace_val = LLVMConstNull(ptr_to_stack_trace_type->type_ref);1130 err_ret_trace_val = LLVMConstNull(ptr_to_stack_trace_type->type_ref);
1125 }1131 }
1126 LLVMValueRef args[] = {1132 LLVMValueRef args[] = {
1127 err_val,
1128 err_ret_trace_val,1133 err_ret_trace_val,
1134 err_val,
1129 };1135 };
1130 LLVMValueRef call_instruction = ZigLLVMBuildCall(g->builder, safety_crash_err_fn, args, 2, get_llvm_cc(g, CallingConventionUnspecified),1136 LLVMValueRef call_instruction = ZigLLVMBuildCall(g->builder, safety_crash_err_fn, args, 2, get_llvm_cc(g, CallingConventionUnspecified),
1131 ZigLLVM_FnInlineAuto, "");1137 ZigLLVM_FnInlineAuto, "");
...@@ -4651,11 +4657,34 @@ static void do_code_gen(CodeGen *g) {...@@ -4651,11 +4657,34 @@ static void do_code_gen(CodeGen *g) {
4651 if (err_ret_trace_arg_index != UINT32_MAX) {4657 if (err_ret_trace_arg_index != UINT32_MAX) {
4652 g->cur_err_ret_trace_val = LLVMGetParam(fn, err_ret_trace_arg_index);4658 g->cur_err_ret_trace_val = LLVMGetParam(fn, err_ret_trace_arg_index);
4653 } else if (fn_table_entry->calls_errorable_function) {4659 } else if (fn_table_entry->calls_errorable_function) {
4660 // TODO call graph analysis to find out what this number needs to be for every function
4661 static const size_t stack_trace_ptr_count = 30;
4662
4663 TypeTableEntry *usize = g->builtin_types.entry_usize;
4664 TypeTableEntry *array_type = get_array_type(g, usize, stack_trace_ptr_count);
4665 LLVMValueRef err_ret_array_val = build_alloca(g, array_type, "error_return_trace_addresses",
4666 get_abi_alignment(g, array_type));
4654 g->cur_err_ret_trace_val = build_alloca(g, g->stack_trace_type, "error_return_trace", get_abi_alignment(g, g->stack_trace_type));4667 g->cur_err_ret_trace_val = build_alloca(g, g->stack_trace_type, "error_return_trace", get_abi_alignment(g, g->stack_trace_type));
4655 size_t index_field_index = g->stack_trace_type->data.structure.fields[0].gen_index;4668 size_t index_field_index = g->stack_trace_type->data.structure.fields[0].gen_index;
4656 LLVMValueRef index_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_err_ret_trace_val, (unsigned)index_field_index, "");4669 LLVMValueRef index_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_err_ret_trace_val, (unsigned)index_field_index, "");
4657 TypeTableEntry *usize = g->builtin_types.entry_usize;
4658 gen_store_untyped(g, LLVMConstNull(usize->type_ref), index_field_ptr, 0, false);4670 gen_store_untyped(g, LLVMConstNull(usize->type_ref), index_field_ptr, 0, false);
4671
4672 size_t addresses_field_index = g->stack_trace_type->data.structure.fields[1].gen_index;
4673 LLVMValueRef addresses_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_err_ret_trace_val, (unsigned)addresses_field_index, "");
4674
4675 TypeTableEntry *slice_type = g->stack_trace_type->data.structure.fields[1].type_entry;
4676 size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index].gen_index;
4677 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)ptr_field_index, "");
4678 LLVMValueRef zero = LLVMConstNull(usize->type_ref);
4679 LLVMValueRef indices[] = {zero, zero};
4680 LLVMValueRef err_ret_array_val_elem0_ptr = LLVMBuildInBoundsGEP(g->builder, err_ret_array_val,
4681 indices, 2, "");
4682 gen_store(g, err_ret_array_val_elem0_ptr, ptr_field_ptr,
4683 get_pointer_to_type(g, get_pointer_to_type(g, usize, false), false));
4684
4685 size_t len_field_index = slice_type->data.structure.fields[slice_len_index].gen_index;
4686 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)len_field_index, "");
4687 gen_store(g, LLVMConstInt(usize->type_ref, stack_trace_ptr_count, false), len_field_ptr, get_pointer_to_type(g, usize, false));
4659 } else {4688 } else {
4660 g->cur_err_ret_trace_val = nullptr;4689 g->cur_err_ret_trace_val = nullptr;
4661 }4690 }
...@@ -5246,11 +5275,11 @@ static void define_builtin_compile_vars(CodeGen *g) {...@@ -5246,11 +5275,11 @@ static void define_builtin_compile_vars(CodeGen *g) {
5246 os_path_join(g->cache_dir, buf_create_from_str(builtin_zig_basename), builtin_zig_path);5275 os_path_join(g->cache_dir, buf_create_from_str(builtin_zig_basename), builtin_zig_path);
5247 Buf *contents = buf_alloc();5276 Buf *contents = buf_alloc();
52485277
5249 buf_appendf(contents,5278 buf_append_str(contents,
5250 "pub const StackTrace = struct {\n"5279 "pub const StackTrace = struct {\n"
5251 " index: usize,\n"5280 " index: usize,\n"
5252 " instruction_addresses: [%" ZIG_PRI_usize "]usize,\n"5281 " instruction_addresses: []usize,\n"
5253 "};\n\n", stack_trace_ptr_count);5282 "};\n\n");
52545283
5255 const char *cur_os = nullptr;5284 const char *cur_os = nullptr;
5256 {5285 {