static void hl_debug_loop( hl_module *m ) { void *inf_addr = hl_gc_threads_info(); int flags = 0; int hl_ver = HL_VERSION; bool loop = false; int pid = hl_sys_getpid(); # ifdef HL_64 flags |= 1; # endif if( sizeof(bool) == 4 ) flags |= 2; # ifdef HL_THREADS flags |= 4; loop = true; # endif hl_get_thread()->exc_flags |= HL_THREAD_INVISIBLE; do { int i; vbyte cmd; hl_socket *s = hl_socket_accept(debug_socket); client_socket = s; send("HLD1",4); send(&flags,4); send(&hl_ver, 4); send(&pid,4); send(&inf_addr, sizeof(void*)); send(&m->globals_data,sizeof(void*)); send(&m->jit_code,sizeof(void*)); send(&m->codesize,4); send(&m->code->types,sizeof(void*)); for(i=1;i<=HBYTES;i++) { hl_type t = {(hl_type_kind)i}; int k = 1 + hl_pad_struct(1,&t); send(&k,4); } send(&m->code->nfunctions,4); for(i=0;i<m->code->nfunctions;i++) { hl_function *f = m->code->functions + i; hl_debug_infos *d = m->jit_debug + i; struct { int nops; int start; unsigned char large; } fdata; fdata.nops = f->nops; fdata.start = d->start; fdata.large = (unsigned char)d->large; send(&fdata,9); send(d->offsets,(d->large ? sizeof(int) : sizeof(unsigned short)) * (f->nops + 1)); } // wait answer hl_socket_recv(s,&cmd,0,1); hl_socket_close(s); debugger_connected = true; client_socket = NULL; } while( loop ); }
HL_PRIM varray *hl_exception_stack() { hl_thread_info *t = hl_get_thread(); varray *a = hl_alloc_array(&hlt_bytes, t->exc_stack_count); int i; for(i=0;i<t->exc_stack_count;i++) { void *addr = t->exc_stack_trace[i]; uchar sym[512]; int size = 512; uchar *str = resolve_symbol_func(addr, sym, &size); if( str == NULL ) { int iaddr = (int)(int_val)addr; str = sym; size = usprintf(str,512,USTR("@0x%X"),iaddr); } hl_aptr(a,vbyte*)[i] = hl_copy_bytes((vbyte*)str,sizeof(uchar)*(size+1)); } return a; }
HL_PRIM void hl_throw( vdynamic *v ) { hl_thread_info *t = hl_get_thread(); hl_trap_ctx *trap = t->trap_current; bool was_rethrow = false; bool call_handler = false; if( t->exc_flags & HL_EXC_RETHROW ) { was_rethrow = true; t->exc_flags &= ~HL_EXC_RETHROW; } else t->exc_stack_count = capture_stack_func(t->exc_stack_trace, HL_EXC_MAX_STACK); t->exc_value = v; t->trap_current = trap->prev; call_handler = (t->exc_flags&HL_EXC_CATCH_ALL) || trap == t->trap_uncaught || t->trap_current == NULL; if( (t->exc_flags&HL_EXC_CATCH_ALL) || break_on_trap(t,trap,v) ) { if( trap == t->trap_uncaught ) t->trap_uncaught = NULL; t->exc_flags |= HL_EXC_IS_THROW; hl_debug_break(); t->exc_flags &= ~HL_EXC_IS_THROW; } if( t->exc_handler && call_handler ) hl_dyn_call(t->exc_handler,&v,1); if( throw_jump == NULL ) throw_jump = longjmp; throw_jump(trap->buf,1); HL_UNREACHABLE; }
HL_PRIM void hl_set_error_handler( vclosure *d ) { hl_thread_info *t = hl_get_thread(); t->trap_uncaught = t->trap_current; t->exc_handler = d; }
HL_PRIM void hl_rethrow( vdynamic *v ) { hl_get_thread()->exc_flags |= HL_EXC_RETHROW; hl_throw(v); }