debug->client_fd = 0;
}
-static void *debug_thread_entry(void *);
-
void debug_host_start(debug_state_t *debug) {
if (debug->debug_thread_running) return;
- pthread_create(&debug->debug_thread, NULL, debug_thread_entry, debug);
+ pthread_create(&debug->debug_thread, NULL, __debug_thread_entry, debug);
}
void debug_host_stop(debug_state_t *debug) {
return NULL;
}
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-
-static void *debug_thread_entry(void *data) {
- debug_state_t *debug = data;
- debug->debug_thread_running = true;
-
- // Set up socket listener
- // Wait for initial connection/handshake before entering loop?
-
- debug->listen_socket_fd = socket(AF_UNIX, SOCK_STREAM, 0);
-
- struct sockaddr_un local_addr, remote_addr;
- local_addr.sun_family = AF_UNIX;
- strcpy(local_addr.sun_path, "/tmp/ovm-debug.0000"); // TODO: Make this dynamic so mulitple servers can exist at a time.
- unlink(local_addr.sun_path); // TODO: Remove this line for the same reason.
- int len = strlen(local_addr.sun_path) + sizeof(local_addr.sun_family);
- bind(debug->listen_socket_fd, (struct sockaddr *)&local_addr, len);
-
- //
- // Currently, there can only be 1 connected debugger instance at a time.
- listen(debug->listen_socket_fd, 1);
-
- len = sizeof(struct sockaddr_un);
- debug->client_fd = accept(debug->listen_socket_fd, (void * restrict)&remote_addr, &len);
-
- close(debug->listen_socket_fd);
-
- printf("Client connected");
-
- while (debug->debug_thread_running) {
- // ...
-
- }
-
- close(debug->client_fd);
-
- return NULL;
-}
--- /dev/null
+
+#include "ovm_debug.h"
+#include "vm.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+
+
+#define CMD_NOP 0
+#define CMD_RES 1
+#define CMD_BRK 2
+
+struct msg_parse_ctx_t {
+ char *data;
+ unsigned int offset;
+ unsigned int bytes_read;
+};
+
+static void send_empty_response(debug_state_t *debug, unsigned int message_number) {
+ char message_buf[5];
+ message_buf[0] = 1;
+ message_buf[1] = (message_number >> 0) & 0xff;
+ message_buf[2] = (message_number >> 8) & 0xff;
+ message_buf[3] = (message_number >> 16) & 0xff;
+ message_buf[4] = (message_number >> 24) & 0xff;
+ send(debug->client_fd, message_buf, 5, 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);
+
+ u32 command_id = *(unsigned int *) &ctx->data[ctx->offset];
+ ctx->offset += sizeof(unsigned int);
+
+ switch (command_id) {
+ case CMD_NOP: {
+ send_empty_response(debug, msg_id);
+ break;
+ }
+
+ case CMD_RES: {
+ // Release the threads
+ bh_arr_each(debug_thread_state_t *, thread, debug->threads) {
+ // This logic for "how to resume a thread" should be moved
+ // elsewhere, but now its fine here.
+ (*thread)->run_count = -1;
+ sem_post(&(*thread)->wait_semaphore);
+ }
+
+ send_empty_response(debug, msg_id);
+ break;
+ }
+
+ case CMD_BRK:
+ break;
+ }
+}
+
+static void process_response(debug_state_t *debug, struct msg_parse_ctx_t *ctx) {
+}
+
+static void process_message(debug_state_t *debug, char *msg, unsigned int bytes_read) {
+ struct msg_parse_ctx_t ctx;
+ ctx.data = msg;
+ ctx.offset = 0;
+ ctx.bytes_read = bytes_read;
+
+ while (ctx.offset < ctx.bytes_read) {
+ u8 type = *(u8 *) &ctx.data[ctx.offset];
+ ctx.offset++;
+
+ if (type == 0) {
+ process_command(debug, &ctx);
+ } else {
+ process_response(debug, &ctx);
+ }
+ }
+}
+
+void *__debug_thread_entry(void * data) {
+ debug_state_t *debug = data;
+ debug->debug_thread_running = true;
+
+ // Set up socket listener
+ // Wait for initial connection/handshake before entering loop.
+
+ debug->listen_socket_fd = socket(AF_UNIX, SOCK_STREAM, 0);
+
+ struct sockaddr_un local_addr, remote_addr;
+ local_addr.sun_family = AF_UNIX;
+ strcpy(local_addr.sun_path, "/tmp/ovm-debug.0000"); // TODO: Make this dynamic so mulitple servers can exist at a time.
+ unlink(local_addr.sun_path); // TODO: Remove this line for the same reason.
+ int len = strlen(local_addr.sun_path) + sizeof(local_addr.sun_family);
+ bind(debug->listen_socket_fd, (struct sockaddr *)&local_addr, len);
+
+ //
+ // Currently, there can only be 1 connected debugger instance at a time.
+ listen(debug->listen_socket_fd, 1);
+
+ len = sizeof(struct sockaddr_un);
+ debug->client_fd = accept(debug->listen_socket_fd, (void * restrict)&remote_addr, &len);
+
+ close(debug->listen_socket_fd);
+
+ // Disable blocking reads and write in the client socket
+ // Alternatively, a MSG_DONTWAIT could be used below
+ fcntl(debug->client_fd, F_SETFL, O_NONBLOCK);
+
+ printf("[INFO ] Client connected\n");
+
+ char command[4096];
+ while (debug->debug_thread_running) {
+ //
+ // Try to read commands from the client.
+ // If an error was returned, bail out of this thread.
+ i32 bytes_read = recv(debug->client_fd, command, 4096, 0);
+ if (bytes_read == -1) {
+ switch (errno) {
+ case EAGAIN: break;
+
+ case ECONNRESET:
+ printf("[ERROR] OVM Debugger connection closed by peer.\n");
+ debug->debug_thread_running = false;
+ break;
+
+ default:
+ printf("[ERROR] OVM Debugger crashed when reading from UNIX socket.\n");
+ debug->debug_thread_running = false;
+ break;
+ }
+ }
+
+ //
+ // If data was returned, process the commands that are inside of it.
+ if (bytes_read > 0) {
+ process_message(debug, command, bytes_read);
+ }
+
+ //
+ // Check the state of the running program and report any changes.
+ }
+
+ close(debug->client_fd);
+ printf("[INFO ] Session closed\n");
+
+ unlink(local_addr.sun_path);
+ return NULL;
+}