code cleanup; breakpoint creation
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 4 Aug 2022 00:37:23 +0000 (19:37 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 4 Aug 2022 00:37:23 +0000 (19:37 -0500)
include/bh.h
include/ovm_debug.h
src/debug/debug_host.c
src/debug/debug_info_builder.c
src/debug/debug_thread.c

index 9ce04ef37ffbcfde9fe5c8cfbb7adde3708a1df9..3cf52f981152242a6041754370ead682d5b27223 100644 (file)
@@ -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 {
index 41a9879a2cff6c8a5f9616a843e6637458d9f005..c4de4cfab14bb8292c94b81c711a56ec7d9cbc2a 100644 (file)
@@ -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;
index fafdcfc7acd6a7b68ccabfa56e501375640e5ff4..48c3eaeba05727f005db1e0c5b21d6dac63dd9b9 100644 (file)
@@ -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;
 
index 28855f5ecb7af3550666025593a94990b9d22cf7..489b5e607a8c4db94c600c584da46b99150afcfa 100644 (file)
@@ -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;
index 4d938daff8a2ee5284dd621654931144e1b50ffa..4748c8e7b30b1476c4a43970d6bd51df9ee9364a 100644 (file)
@@ -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);