Skip to content

Commit

Permalink
Error message on bus error or segmentation fault. Some additional SIG… (
Browse files Browse the repository at this point in the history
#848)

* Error message on bus error or segmentation fault. Some additional SIG info. Full debug info by default. Trapping is now debugtrap rather than trap for LLVM. Row now initialized when entering function for stacktrace.
  • Loading branch information
lerno authored Jul 13, 2023
1 parent c99f298 commit c7d90ba
Show file tree
Hide file tree
Showing 16 changed files with 179 additions and 67 deletions.
27 changes: 13 additions & 14 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ jobs:
..\build\${{ matrix.build_type }}\c3c.exe compile-run examples\time.c3
..\build\${{ matrix.build_type }}\c3c.exe compile-run examples\fannkuch-redux.c3
..\build\${{ matrix.build_type }}\c3c.exe compile-run examples\contextfree\boolerr.c3
..\build\${{ matrix.build_type }}\c3c.exe compile-run examples\ls.c3
..\build\${{ matrix.build_type }}\c3c.exe compile-run examples\load_world.c3
..\build\${{ matrix.build_type }}\c3c.exe compile-run examples\process.c3
..\build\${{ matrix.build_type }}\c3c.exe compile-run examples\ls.c3
- name: Build testproject
Expand Down Expand Up @@ -108,6 +108,7 @@ jobs:
../build/c3c compile-run examples/fannkuch-redux.c3
../build/c3c compile-run examples/contextfree/boolerr.c3
../build/c3c compile-run examples/load_world.c3
../build/c3c compile-run examples/load_world.c3
- name: Build testproject
run: |
Expand Down Expand Up @@ -339,31 +340,29 @@ jobs:
- name: Compile and run some examples
run: |
cd resources
../build/c3c compile examples/base64.c3
../build/c3c compile examples/binarydigits.c3
../build/c3c compile examples/brainfk.c3
../build/c3c compile examples/factorial_macro.c3
../build/c3c compile examples/fasta.c3
../build/c3c compile examples/gameoflife.c3
../build/c3c compile examples/hash.c3
../build/c3c compile examples/levenshtein.c3
../build/c3c compile examples/load_world.c3
../build/c3c compile examples/map.c3
../build/c3c compile examples/mandelbrot.c3
../build/c3c compile examples/plus_minus.c3
../build/c3c compile examples/nbodies.c3
../build/c3c compile examples/spectralnorm.c3
../build/c3c compile examples/swap.c3
../build/c3c compile examples/contextfree/boolerr.c3
../build/c3c compile examples/contextfree/dynscope.c3
../build/c3c compile examples/contextfree/guess_number.c3
../build/c3c compile examples/contextfree/multi.c3
../build/c3c compile examples/contextfree/cleanup.c3
../build/c3c compile-run examples/hash.c3
../build/c3c compile-run examples/nbodies.c3
../build/c3c compile-run examples/contextfree/boolerr.c3
../build/c3c compile-run examples/contextfree/dynscope.c3
../build/c3c compile-run examples/contextfree/multi.c3
../build/c3c compile-run examples/contextfree/cleanup.c3
../build/c3c compile-run examples/hello_world_many.c3
../build/c3c compile-run examples/time.c3
../build/c3c compile-run examples/fannkuch-redux.c3
../build/c3c compile-run examples/contextfree/boolerr.c3
../build/c3c compile-run examples/load_world.c3
../build/c3c compile-run examples/base64.c3
../build/c3c compile-run examples/binarydigits.c3
../build/c3c compile-run examples/brainfk.c3
../build/c3c compile-run examples/factorial_macro.c3
../build/c3c compile-run examples/fasta.c3
../build/c3c compile-run examples/process.c3
- name: Compile run unit tests
Expand Down
52 changes: 51 additions & 1 deletion lib/std/core/builtin.c3
Original file line number Diff line number Diff line change
Expand Up @@ -285,4 +285,54 @@ macro uint uint128.hash(uint128 i) => (uint)((i >> 96) ^ (i >> 64) ^ (i >> 32) ^
macro uint bool.hash(bool b) => (uint)b;
macro uint typeid.hash(typeid t) => ((ulong)(uptr)t).hash();
macro uint String.hash(String c) => (uint)fnv32a::encode(c);
macro uint char[].hash(char[] c) => (uint)fnv32a::encode(c);
macro uint char[].hash(char[] c) => (uint)fnv32a::encode(c);

module std::core::builtin @if((env::LINUX || env::DARWIN) && env::COMPILER_SAFE_MODE && env::DEBUG_SYMBOLS);
import libc;

fn void sig_panic(String message)
{
$if $defined(io::stderr) && $defined(File.printf):
CallstackElement* stack = $$stacktrace();
if (stack) stack = stack.prev;
if (stack) stack = stack.prev;
(void)io::stderr().print("\nERROR: '");
(void)io::stderr().print(message);
(void)io::stderr().printn("'");
while (stack)
{
(void)io::stderr().printfn(" in function %s (%s:%s)", stack.function, stack.file, stack.line);
if (stack == stack.prev) break;
stack = stack.prev;
}
$endif
}

SignalFunction old_bus_error;
SignalFunction old_segmentation_fault;

fn void sig_bus_error(CInt i)
{
sig_panic("Illegal memory access.");
$$trap();
}

fn void sig_segmentation_fault(CInt i)
{
sig_panic("Out of bounds memory access.");
$$trap();
}

fn void install_signal_handler(CInt signal, SignalFunction func) @local
{
SignalFunction old = libc::signal(signal, func);
// Restore
if ((iptr)old > 1024) libc::signal(signal, old);
}

// Clean this up
static initialize @priority(101)
{
install_signal_handler(libc::SIGBUS, &sig_bus_error);
install_signal_handler(libc::SIGSEGV, &sig_segmentation_fault);
}
1 change: 1 addition & 0 deletions lib/std/core/env.c3
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ const bool I128_NATIVE_SUPPORT = $$PLATFORM_I128_SUPPORTED;
const bool F16_SUPPORT = $$PLATFORM_F16_SUPPORTED;
const bool F128_SUPPORT = $$PLATFORM_F128_SUPPORTED;
const bool COMPILER_SAFE_MODE = $$COMPILER_SAFE_MODE;
const bool DEBUG_SYMBOLS = $$DEBUG_SYMBOLS;
const usz LLVM_VERSION = $$LLVM_VERSION;
const bool BENCHMARKING = $$BENCHMARKING;
const bool TESTING = $$TESTING;
Expand Down
24 changes: 24 additions & 0 deletions lib/std/libc/libc.c3
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,30 @@ def JmpBuf = uptr[$$JMP_BUF_SIZE];
def Fd = CInt;
def Fpos_t = long; // TODO make sure fpos is correct on all targets.
def SignalFunction = fn void(int);


const CInt SIGHUP = 1;
const CInt SIGINT = 2;
const CInt SIGQUIT = 3;
const CInt SIGILL = 4;
const CInt SIGTRAP = 5;
const CInt SIGABTR = 6;
const CInt SIGBUS = BSD_FLAVOR_SIG ? 10 : 7; // Or Mips
const CInt SIGFPE = 8;
const CInt SIGKILL = 9;
const CInt SIGSEGV = 11;
const CInt SIGSYS = BSD_FLAVOR_SIG ? 12 : 31;
const CInt SIGPIPE = 13;
const CInt SIGALRM = 14;
const CInt SIGTERM = 15;
const CInt SIGURG = BSD_FLAVOR_SIG ? 16 : 23;
const CInt SIGSTOP = BSD_FLAVOR_SIG ? 17 : 19;
const CInt SIGTSTP = BSD_FLAVOR_SIG ? 18 : 20;
const CInt SIGCONT = BSD_FLAVOR_SIG ? 19 : 18;
const CInt SIGCHLD = BSD_FLAVOR_SIG ? 20 : 17;

const bool BSD_FLAVOR_SIG @local = env::OPENBSD || env::DARWIN || env::FREEBSD || env::NETBSD;

def Time_t = $typefrom(env::WIN32 ? long.typeid : CLong.typeid);
def Off_t = $typefrom(env::WIN32 ? int.typeid : usz.typeid);

Expand Down
1 change: 1 addition & 0 deletions releasenotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
- Dropped support for LLVM 13-14.
- Updated grammar and lexer definition.
- Removal of `$elif`.
- `@stdcall` etc removed in favor of `@callconv`
- Empty fault definitions is now an error.
- Better errors on incorrect bitstruct syntax.
- Internal use wildcard type rather than optional wildcard.
Expand Down
16 changes: 8 additions & 8 deletions resources/grammar/grammar.y
Original file line number Diff line number Diff line change
Expand Up @@ -335,31 +335,31 @@ or_stmt_expr
| or_stmt_expr OR_OP and_expr
;

or_expr_with_suffix
suffix_expr
: or_expr
| or_expr '?'
| or_expr '?' '!'
;

or_stmt_expr_with_suffix
suffix_stmt_expr
: or_stmt_expr
| or_stmt_expr '?'
| or_stmt_expr '?' '!'
;

ternary_expr
: or_expr_with_suffix
: suffix_expr
| or_expr '?' expr ':' ternary_expr
| or_expr_with_suffix ELVIS ternary_expr
| or_expr_with_suffix OPTELSE ternary_expr
| suffix_expr ELVIS ternary_expr
| suffix_expr OPTELSE ternary_expr
| lambda_decl implies_body
;

ternary_stmt_expr
: or_stmt_expr_with_suffix
: suffix_stmt_expr
| or_stmt_expr '?' expr ':' ternary_expr
| or_stmt_expr_with_suffix ELVIS ternary_expr
| or_stmt_expr_with_suffix OPTELSE ternary_expr
| suffix_stmt_expr ELVIS ternary_expr
| suffix_stmt_expr OPTELSE ternary_expr
| lambda_decl implies_body
;

Expand Down
2 changes: 1 addition & 1 deletion src/build/builder.c
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ void init_default_build_target(BuildTarget *target, BuildOptions *options)
.size_optimization_level = SIZE_OPTIMIZATION_NONE,
.symtab_size = options->symtab_size ? options->symtab_size : DEFAULT_SYMTAB_SIZE,
.switchrange_max_size = DEFAULT_SWITCHRANGE_MAX_SIZE,
.debug_info = DEBUG_INFO_NONE,
.debug_info = DEBUG_INFO_NOT_SET,
.arch_os_target = ARCH_OS_TARGET_DEFAULT,
.reloc_model = RELOC_DEFAULT,
.feature.x86_vector_capability = X86VECTOR_DEFAULT,
Expand Down
2 changes: 1 addition & 1 deletion src/build/project.c
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ static void project_add_targets(Project *project, JSONObject *project_data)
.memory_environment = MEMORY_ENV_NORMAL,
.size_optimization_level = SIZE_OPTIMIZATION_NONE,
.arch_os_target = ARCH_OS_TARGET_DEFAULT,
.debug_info = DEBUG_INFO_NONE,
.debug_info = DEBUG_INFO_NOT_SET,
.symtab_size = DEFAULT_SYMTAB_SIZE,
.cc = "cc",
.version = "1.0.0",
Expand Down
1 change: 1 addition & 0 deletions src/compiler/compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -835,6 +835,7 @@ void compile()
setup_int_define("OS_TYPE", (uint64_t)platform_target.os, type_int);
setup_int_define("COMPILER_SIZE_OPT_LEVEL", (uint64_t)active_target.size_optimization_level, type_int);
setup_bool_define("COMPILER_SAFE_MODE", active_target.feature.safe_mode);
setup_bool_define("DEBUG_SYMBOLS", active_target.debug_info == DEBUG_INFO_FULL);
setup_int_define("LLVM_VERSION", llvm_version_major, type_int);
setup_bool_define("BENCHMARKING", active_target.benchmarking);
setup_int_define("JMP_BUF_SIZE", jump_buffer_size(), type_int);
Expand Down
4 changes: 1 addition & 3 deletions src/compiler/enums.h
Original file line number Diff line number Diff line change
Expand Up @@ -757,7 +757,7 @@ typedef enum
ATTRIBUTE_ALIGN,
ATTRIBUTE_BIGENDIAN,
ATTRIBUTE_BUILTIN,
ATTRIBUTE_CDECL,
ATTRIBUTE_CALLCONV,
ATTRIBUTE_DEPRECATED,
ATTRIBUTE_DYNAMIC,
ATTRIBUTE_EXPORT,
Expand All @@ -784,11 +784,9 @@ typedef enum
ATTRIBUTE_PURE,
ATTRIBUTE_REFLECT,
ATTRIBUTE_SECTION,
ATTRIBUTE_STDCALL,
ATTRIBUTE_TEST,
ATTRIBUTE_UNUSED,
ATTRIBUTE_USED,
ATTRIBUTE_VECCALL,
ATTRIBUTE_WASM,
ATTRIBUTE_WEAK,
ATTRIBUTE_WINMAIN,
Expand Down
12 changes: 8 additions & 4 deletions src/compiler/llvm_codegen_function.c
Original file line number Diff line number Diff line change
Expand Up @@ -429,8 +429,9 @@ void llvm_emit_stacktrace_definitions(GenContext *c)
LLVMSetThreadLocal(current_stack, true);
LLVMSetInitializer(current_stack, llvm_get_zero_raw(c->ptr_type));
llvm_set_weak(c, current_stack);
LLVMTypeRef args[5] = { c->ptr_type, c->ptr_type, c->size_type, c->ptr_type, c->size_type };
LLVMTypeRef func_type = c->debug.stack_init_fn_type = LLVMFunctionType(LLVMVoidTypeInContext(c->context), args, 5, false);
LLVMTypeRef uint_type = llvm_get_type(c, type_uint);
LLVMTypeRef args[6] = { c->ptr_type, c->ptr_type, c->size_type, c->ptr_type, c->size_type, uint_type };
LLVMTypeRef func_type = c->debug.stack_init_fn_type = LLVMFunctionType(LLVMVoidTypeInContext(c->context), args, 6, false);
LLVMValueRef func = c->debug.stack_init_fn = LLVMAddFunction(c->module, ".stacktrace_init", func_type);
llvm_set_weak(c, func);
LLVMBuilderRef builder = LLVMCreateBuilderInContext(c->context);
Expand Down Expand Up @@ -460,6 +461,8 @@ void llvm_emit_stacktrace_definitions(GenContext *c)
c->debug.current_stack_ptr,
stacktrace,
type_alloca_alignment(type_voidptr));
LLVMValueRef line = llvm_emit_struct_gep_raw(c, stacktrace, slot_type, 3, alignment, &align_to_use);
llvm_store_to_ptr_raw_aligned(c, line, LLVMGetParam(func, 5), align_to_use);
LLVMBuildRetVoid(c->builder);
LLVMDisposeBuilder(c->builder);
c->builder = NULL;
Expand Down Expand Up @@ -526,8 +529,9 @@ void llvm_emit_body(GenContext *c, LLVMValueRef function, const char *module_nam
AlignSize alignment = llvm_abi_alignment(c, slot_type);
LLVMValueRef stacktrace = c->debug.stack_slot = llvm_emit_alloca(c, slot_type, alignment, ".$stacktrace");
LLVMValueRef args[] = { stacktrace, c->debug.func_name, llvm_const_int(c, type_usz, func_name_len),
c->debug.file_name, llvm_const_int(c, type_usz, file_name_len) };
LLVMBuildCall2(c->builder, c->debug.stack_init_fn_type, c->debug.stack_init_fn, args, 5, "");
c->debug.file_name, llvm_const_int(c, type_usz, file_name_len),
llvm_const_int(c, type_uint, body->span.row) };
LLVMBuildCall2(c->builder, c->debug.stack_init_fn_type, c->debug.stack_init_fn, args, 6, "");
c->debug.stack_slot_row = LLVMBuildStructGEP2(c->builder, slot_type, c->debug.stack_slot, 3, ".$row");
if (function_name == kw_main || function_name == kw_mainstub)
{
Expand Down
Loading

0 comments on commit c7d90ba

Please sign in to comment.