From: Brendan Hansen Date: Thu, 4 Aug 2022 00:37:23 +0000 (-0500) Subject: code cleanup; breakpoint creation X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=20151559f61ca7cdbc341170de2f44fb1ea4939e;p=onyx-embedder.git code cleanup; breakpoint creation --- diff --git a/include/bh.h b/include/bh.h index 9ce04ef..3cf52f9 100644 --- a/include/bh.h +++ b/include/bh.h @@ -274,6 +274,7 @@ typedef struct bh__arena_internal { } bh__arena_internal; BH_DEF void bh_arena_init(bh_arena* alloc, bh_allocator backing, isize arena_size); +BH_DEF void bh_arena_clear(bh_arena* alloc); BH_DEF void bh_arena_free(bh_arena* alloc); BH_DEF bh_allocator bh_arena_allocator(bh_arena* alloc); BH_DEF BH_ALLOCATOR_PROC(bh_arena_allocator_proc); @@ -1058,6 +1059,22 @@ BH_DEF void bh_arena_init(bh_arena* alloc, bh_allocator backing, isize arena_siz ((bh__arena_internal *)(alloc->first_arena))->next_arena = NULL; } +BH_DEF void bh_arena_clear(bh_arena* alloc) { + bh__arena_internal *walker = (bh__arena_internal *) alloc->first_arena; + walker = walker->next_arena; + if (walker != NULL) { + bh__arena_internal *trailer = walker; + while (walker != NULL) { + walker = walker->next_arena; + bh_free(alloc->backing, trailer); + trailer = walker; + } + } + + alloc->current_arena = alloc->first_arena; + alloc->size = sizeof(ptr); +} + BH_DEF void bh_arena_free(bh_arena* alloc) { bh__arena_internal *walker = (bh__arena_internal *) alloc->first_arena; bh__arena_internal *trailer = walker; @@ -2385,6 +2402,8 @@ BH_DEF b32 bh__arr_grow(bh_allocator alloc, void** arr, i32 elemsize, i32 cap) { arrptr = (bh__arr *) bh_alloc(alloc, sizeof(*arrptr) + elemsize * cap); if (arrptr == NULL) return 0; + memset(arrptr + 1, 0, elemsize * cap); + arrptr->allocator = alloc; arrptr->capacity = cap; arrptr->length = 0; @@ -2394,12 +2413,15 @@ BH_DEF b32 bh__arr_grow(bh_allocator alloc, void** arr, i32 elemsize, i32 cap) { if (arrptr->capacity < cap) { void* p; + i32 oldcap = arrptr->capacity; i32 newcap = arrptr->capacity; while (newcap < cap) newcap = BH_ARR_GROW_FORMULA(newcap); p = bh_resize(arrptr->allocator, arrptr, sizeof(*arrptr) + elemsize * newcap); if (p) { + memset(bh_pointer_add(((bh__arr *) p + 1), elemsize * oldcap), 0, elemsize * (newcap - oldcap - 1)); + arrptr = (bh__arr *) p; arrptr->capacity = newcap; } else { diff --git a/include/ovm_debug.h b/include/ovm_debug.h index 41a9879..c4de4cf 100644 --- a/include/ovm_debug.h +++ b/include/ovm_debug.h @@ -111,6 +111,9 @@ typedef struct debug_thread_state_t { typedef struct debug_state_t { bh_allocator alloc; + bh_arena tmp_arena; + bh_allocator tmp_alloc; + debug_info_t *info; bh_arr(debug_thread_state_t *) threads; diff --git a/src/debug/debug_host.c b/src/debug/debug_host.c index fafdcfc..48c3eae 100644 --- a/src/debug/debug_host.c +++ b/src/debug/debug_host.c @@ -5,6 +5,9 @@ void debug_host_init(debug_state_t *debug) { memset(debug, 0, sizeof(*debug)); debug->alloc = bh_heap_allocator(); + + bh_arena_init(&debug->tmp_arena, bh_heap_allocator(), 16 * 1024); + debug->tmp_alloc = bh_arena_allocator(&debug->tmp_arena); debug->info = NULL; diff --git a/src/debug/debug_info_builder.c b/src/debug/debug_info_builder.c index 28855f5..489b5e6 100644 --- a/src/debug/debug_info_builder.c +++ b/src/debug/debug_info_builder.c @@ -80,8 +80,12 @@ void debug_info_builder_step(debug_info_builder_t *builder) { } u32 line_index = file_info->line_buffer_offset + builder->current_line; - u32 target = bh_arr_length(builder->info->instruction_reducer) - 1; - bh_arr_set_at(builder->info->line_to_instruction, line_index, target); + u32 target = bh_arr_length(builder->info->instruction_reducer); + + if (line_index >= bh_arr_capacity(builder->info->line_to_instruction) || + builder->info->line_to_instruction[line_index] == 0) { + bh_arr_set_at(builder->info->line_to_instruction, line_index, target); + } } if (builder->locked) return; diff --git a/src/debug/debug_thread.c b/src/debug/debug_thread.c index 4d938da..4748c8e 100644 --- a/src/debug/debug_thread.c +++ b/src/debug/debug_thread.c @@ -18,24 +18,75 @@ struct msg_parse_ctx_t { unsigned int bytes_read; }; -static void send_empty_response(debug_state_t *debug, unsigned int message_number) { +static void send_response_header(debug_state_t *debug, unsigned int message_number) { + unsigned int RESPONSE_HEADER = 0xffffffff; + send(debug->client_fd, &RESPONSE_HEADER, 4, 0); send(debug->client_fd, &message_number, 4, 0); } -static void process_command(debug_state_t *debug, struct msg_parse_ctx_t *ctx) { - u32 msg_id = *(unsigned int *) &ctx->data[ctx->offset]; - ctx->offset += sizeof(unsigned int); +static void send_string(debug_state_t *debug, const char *str) { + unsigned int len = strlen(str); + send(debug->client_fd, &len, 4, 0); + send(debug->client_fd, str, len, 0); +} + +static void send_bytes(debug_state_t *debug, const char *bytes, unsigned int len) { + send(debug->client_fd, &len, 4, 0); + send(debug->client_fd, bytes, len, 0); +} + +static void send_int(debug_state_t *debug, unsigned int x) { + send(debug->client_fd, &x, 4, 0); +} - u32 command_id = *(unsigned int *) &ctx->data[ctx->offset]; +static void send_bool(debug_state_t *debug, bool x) { + bool v = x ? 1 : 0; + send(debug->client_fd, &v, 1, 0); +} + +static int parse_int(debug_state_t *debug, struct msg_parse_ctx_t *ctx) { + int i = *(unsigned int *) &ctx->data[ctx->offset]; ctx->offset += sizeof(unsigned int); + return i; +} + +static char *parse_bytes(debug_state_t *debug, struct msg_parse_ctx_t *ctx) { + int len = parse_int(debug, ctx); + + char *buf = bh_alloc_array(debug->tmp_alloc, char, len); + memcpy(buf, &ctx->data[ctx->offset], len); + ctx->offset += len; + + return buf; +} + +static char *parse_string(debug_state_t *debug, struct msg_parse_ctx_t *ctx) { + int len = parse_int(debug, ctx); + + char *buf = bh_alloc_array(debug->tmp_alloc, char, len + 1); + memcpy(buf, &ctx->data[ctx->offset], len); + ctx->offset += len; + + buf[len] = 0; + return buf; +} + +static void process_command(debug_state_t *debug, struct msg_parse_ctx_t *ctx) { + u32 msg_id = parse_int(debug, ctx); + u32 command_id = parse_int(debug, ctx); + printf("[INFO ] Recv command: %d\n", command_id); switch (command_id) { case CMD_NOP: { - send_empty_response(debug, msg_id); + // Returns: header + + send_response_header(debug, msg_id); break; } case CMD_RES: { + // Returns: nothing + // Release the threads bh_arr_each(debug_thread_state_t *, thread, debug->threads) { // This logic for "how to resume a thread" should be moved @@ -44,12 +95,41 @@ static void process_command(debug_state_t *debug, struct msg_parse_ctx_t *ctx) { sem_post(&(*thread)->wait_semaphore); } - send_empty_response(debug, msg_id); + send_response_header(debug, msg_id); break; } - case CMD_BRK: + case CMD_BRK: { + // + // Returns: header success:bool breakpoint_handle:u32 + + char *filename = parse_string(debug, ctx); + int line = parse_int(debug, ctx); + + // + // TODO: This translation logic will have to be abstracted + debug_file_info_t file_info; + bool file_found = debug_info_lookup_file_by_name(debug->info, filename, &file_info); + if (!file_found) { + send_response_header(debug, msg_id); + send_bool(debug, false); + send_int(debug, -1); + return; + } + + u32 instr = debug->info->line_to_instruction[file_info.line_buffer_offset + line]; + + printf("[INFO ] Setting breakpoint at %s:%d (%xd)\n", filename, line, instr); + + bh_arr_each(debug_thread_state_t *, thread, debug->threads) { + bh_arr_push((*thread)->breakpoints, instr); + } + + send_response_header(debug, msg_id); + send_bool(debug, true); + send_int(debug, 0); break; + } } } @@ -134,6 +214,9 @@ void *__debug_thread_entry(void * data) { // // Check the state of the running program and report any changes. + + + bh_arena_clear(&debug->tmp_arena); } close(debug->client_fd);