Enable source debugging feature for windows platform (#910)

- use platform independent data types in debug-engine library
- add os_socket APIs and provide windows and posix implementation
- avoid using platform related header files in non-platform layer
- use format specifiers macros for sprintf and sscanf
- change thread handle type from uint64 to korp_tid
- add lock when sending socket packet to avoid thread racing
This commit is contained in:
Xu Jun
2021-12-22 19:52:07 +08:00
committed by GitHub
parent af251e45ca
commit ccb2de35d7
21 changed files with 851 additions and 316 deletions

View File

@ -3,22 +3,8 @@
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_platform.h"
#include "gdbserver.h"
#include <arpa/inet.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <unistd.h>
#include "bh_log.h"
#include "handler.h"
#include "packets.h"
#include "utils.h"
@ -51,14 +37,9 @@ static struct packet_handler_elem packet_handler_table[255] = {
};
WASMGDBServer *
wasm_create_gdbserver(char *host, int *port)
wasm_create_gdbserver(const char *host, int32 *port)
{
int listen_fd = -1;
const int one = 1;
struct sockaddr_in addr;
socklen_t socklen;
int ret;
bh_socket_t listen_fd = (bh_socket_t)-1;
WASMGDBServer *server;
bh_assert(port);
@ -70,52 +51,25 @@ wasm_create_gdbserver(char *host, int *port)
memset(server, 0, sizeof(WASMGDBServer));
listen_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (listen_fd < 0) {
LOG_ERROR("wasm gdb server error: socket() failed");
if (0 != os_socket_create(&listen_fd, 1)) {
LOG_ERROR("wasm gdb server error: create socket failed");
goto fail;
}
ret = fcntl(listen_fd, F_SETFD, FD_CLOEXEC);
if (ret < 0) {
LOG_ERROR(
"wasm gdb server error: fcntl() failed on setting FD_CLOEXEC");
if (0 != os_socket_bind(listen_fd, host, port)) {
LOG_ERROR("wasm gdb server error: socket bind failed");
goto fail;
}
ret = setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
if (ret < 0) {
LOG_ERROR("wasm gdb server error: setsockopt() failed");
goto fail;
}
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(host);
addr.sin_port = htons(*port);
ret = bind(listen_fd, (struct sockaddr *)&addr, sizeof(addr));
if (ret < 0) {
LOG_ERROR("wasm gdb server error: bind() failed");
goto fail;
}
socklen = sizeof(addr);
if (getsockname(listen_fd, (void *)&addr, &socklen) == -1) {
LOG_ERROR("%s", strerror(errno));
goto fail;
}
LOG_WARNING("Debug server listening on %s:%d\n", host,
ntohs(addr.sin_port));
*port = ntohs(addr.sin_port);
LOG_WARNING("Debug server listening on %s:%" PRIu32 "\n", host, *port);
server->listen_fd = listen_fd;
return server;
fail:
if (listen_fd >= 0) {
shutdown(listen_fd, SHUT_RDWR);
close(listen_fd);
os_socket_shutdown(listen_fd);
os_socket_close(listen_fd);
}
if (server)
wasm_runtime_free(server);
@ -125,18 +79,18 @@ fail:
bool
wasm_gdbserver_listen(WASMGDBServer *server)
{
int ret;
int sockt_fd = 0;
bh_socket_t sockt_fd = (bh_socket_t)-1;
int32 ret;
ret = listen(server->listen_fd, 1);
if (ret < 0) {
LOG_ERROR("wasm gdb server error: listen() failed");
ret = os_socket_listen(server->listen_fd, 1);
if (ret != 0) {
LOG_ERROR("wasm gdb server error: socket listen failed");
goto fail;
}
sockt_fd = accept(server->listen_fd, NULL, NULL);
os_socket_accept(server->listen_fd, &sockt_fd, NULL, NULL);
if (sockt_fd < 0) {
LOG_ERROR("wasm gdb server error: accept() failed");
LOG_ERROR("wasm gdb server error: socket accept failed");
goto fail;
}
@ -146,8 +100,8 @@ wasm_gdbserver_listen(WASMGDBServer *server)
return true;
fail:
shutdown(server->listen_fd, SHUT_RDWR);
close(server->listen_fd);
os_socket_shutdown(server->listen_fd);
os_socket_close(server->listen_fd);
return false;
}
@ -155,12 +109,12 @@ void
wasm_close_gdbserver(WASMGDBServer *server)
{
if (server->socket_fd > 0) {
shutdown(server->socket_fd, SHUT_RDWR);
close(server->socket_fd);
os_socket_shutdown(server->socket_fd);
os_socket_close(server->socket_fd);
}
if (server->listen_fd > 0) {
shutdown(server->listen_fd, SHUT_RDWR);
close(server->listen_fd);
os_socket_shutdown(server->listen_fd);
os_socket_close(server->listen_fd);
}
}
@ -180,33 +134,34 @@ handler_packet(WASMGDBServer *server, char request, char *payload)
static void
process_packet(WASMGDBServer *server)
{
uint8_t *inbuf = server->pkt.buf;
int inbuf_size = server->pkt.size;
uint8_t *packetend_ptr = (uint8_t *)memchr(inbuf, '#', inbuf_size);
int packetend = packetend_ptr - inbuf;
uint8 *inbuf = server->pkt.buf;
int32 inbuf_size = server->pkt.size;
uint8 *packetend_ptr = (uint8 *)memchr(inbuf, '#', inbuf_size);
int32 packet_size = (int32)(uintptr_t)(packetend_ptr - inbuf);
char request = inbuf[1];
char *payload = NULL;
uint8_t checksum = 0;
uint8 checksum = 0;
if (packetend == 1) {
if (packet_size == 1) {
LOG_VERBOSE("receive empty request, ignore it\n");
return;
}
bh_assert('$' == inbuf[0]);
inbuf[packetend] = '\0';
inbuf[packet_size] = '\0';
for (int i = 1; i < packetend; i++)
for (int i = 1; i < packet_size; i++)
checksum += inbuf[i];
bh_assert(checksum
== (hex(inbuf[packetend + 1]) << 4 | hex(inbuf[packetend + 2])));
bh_assert(
checksum
== (hex(inbuf[packet_size + 1]) << 4 | hex(inbuf[packet_size + 2])));
payload = (char *)&inbuf[2];
LOG_VERBOSE("receive request:%c %s\n", request, payload);
handler_packet(server, request, payload);
inbuf_erase_head(server, packetend + 3);
inbuf_erase_head(server, packet_size + 3);
}
bool