codegen worker must not exit process with running siblings

This commit is contained in:
kalsprite
2026-08-19 13:44:32 -07:00
parent 43d44e5942
commit cd8fc51efc
2 changed files with 53 additions and 7 deletions

View File

@@ -16,6 +16,41 @@ gb_global isize lb_global_type_info_member_offsets_index = 0;
gb_global isize lb_global_type_info_member_usings_index = 0;
gb_global isize lb_global_type_info_member_tags_index = 0;
// A backend worker must not end the process: its siblings are still inside LLVM, and tearing the
// process down under them is what turns a reported error into a crash. A failing worker records the
// failure and returns; the driver exits once the pool has drained. Work stealing can run a task on
// the main thread, so this must not depend on which thread is executing
gb_global std::atomic<bool> lb_worker_failure;
gb_internal void lb_record_worker_failure(void) {
lb_worker_failure.store(true, std::memory_order_release);
}
gb_internal void lb_exit_if_worker_failed(void) {
if (lb_worker_failure.load(std::memory_order_acquire)) {
exit_with_errors();
}
}
// Without a handler installed, LLVM prints an error of its own and calls exit(1) from whichever
// thread it is on.
gb_internal void lb_llvm_diagnostic_handler(LLVMDiagnosticInfoRef di, void *) {
char *description = LLVMGetDiagInfoDescription(di);
defer (LLVMDisposeMessage(description));
switch (LLVMGetDiagInfoSeverity(di)) {
case LLVMDSError:
gb_printf_err("LLVM Error: %s\n", description);
lb_record_worker_failure();
break;
case LLVMDSWarning:
gb_printf_err("LLVM Warning: %s\n", description);
break;
default:
break;
}
}
gb_internal WORKER_TASK_PROC(lb_init_module_worker_proc) {
lbModule *m = cast(lbModule *)data;
Checker *c = m->checker;
@@ -58,6 +93,7 @@ gb_internal WORKER_TASK_PROC(lb_init_module_worker_proc) {
m->module_name = module_name;
m->ctx = LLVMContextCreate();
LLVMContextSetDiagnosticHandler(m->ctx, lb_llvm_diagnostic_handler, nullptr);
m->mod = LLVMModuleCreateWithNameInContext(m->module_name, m->ctx);
// m->debug_builder = nullptr;
if (build_context.no_plt) {