ghc-debug-stub 0.2.1.0 → 0.3.0.0
raw patch · 5 files changed
+78/−50 lines, 5 filesdep ~ghc-debug-conventionPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: ghc-debug-convention
API changes (from Hackage documentation)
Files
- CHANGELOG.md +5/−0
- cbits/socket.cpp +7/−1
- cbits/socket.h +1/−1
- cbits/stub.cpp +61/−44
- ghc-debug-stub.cabal +4/−4
CHANGELOG.md view
@@ -1,5 +1,10 @@ # Revision history for ghc-debug-stub +## 0.3.0.0 -- 2022-10-06++* Allow clients to reconnect multiple times to debuggee (Finley McIlwaine)+* Fix initialisation bugs due to uninitialised len (Teo Camarasu)+ ## 0.2.1.0 -- 2022-05-06 * Fix bug with write_block on BF_COMPACT closures
cbits/socket.cpp view
@@ -8,15 +8,21 @@ Socket::Socket(int fd) : fd(fd) { } -void Socket::read(char *buf, size_t len) {+size_t Socket::read(char *buf, size_t len) {+ int n_read = 0; while (len > 0) { ssize_t ret = ::read(this->fd, (void *) buf, len); if (ret < 0) { throw SocketError(errno, "read");+ } else if (ret == 0) {+ // if read() returns 0 it should be considered a disconnect+ return 0; } len -= ret; buf += ret;+ n_read += ret; }+ return n_read; } void Socket::write(const char *buf, size_t len) {
cbits/socket.h view
@@ -17,6 +17,6 @@ public: Socket(int fd); /* read len bytes into the given buffer */- void read(char *buf, size_t len);+ size_t read(char *buf, size_t len); void write(const char *buf, size_t len); };
cbits/stub.cpp view
@@ -104,25 +104,26 @@ void flush(response_code status) { if (status != RESP_OKAY_CONTINUES || this->tail != this->buf + sizeof(Header)) { size_t len = this->tail - this->buf;- trace("LEN: %lu", len);+ trace("bytes in response payload: %lu\n", len); uint32_t len_payload; uint16_t status_payload; len_payload=htonl(len); status_payload = htons(status);- trace("STATUS: %d\n", status);+ trace("responding with status: %d\n", status); // Header is the length this->sock.write((char *) &len_payload, sizeof(uint32_t)); // Then status this->sock.write((char *) &status_payload, sizeof(uint16_t)); // then the body, usually empty- trace("FLUSHING(%lu)( ", len);- for (int i = 0; i < len; i++)- {- trace("%02X", buf[i]);- }- trace("\n");+ trace("responding with body of length %lu: ( ", len);+ for (int i = 0; i < len; i++)+ {+ trace("%02X", buf[i]);+ }+ trace(" )\n"); this->sock.write(this->buf, len); this->tail = this->buf;+ trace("response written to socket\n\n"); } } @@ -175,7 +176,7 @@ } void finish(enum response_code status) {- trace("FINISH: %d\n", status);+ trace("finishing with code: %d\n", status); this->flush(status); } @@ -191,6 +192,7 @@ extern "C" void pause_mutator() {+ trace("pausing mutator\n"); pid_t pid; if (use_fork){ pid = fork();@@ -214,11 +216,13 @@ extern "C" void resume_mutator() {- //trace("Resuming %p %p\n", r_paused.pausing_task, r_paused.capabilities);+ trace("resuming mutator\n"); if (use_fork){+ trace("exiting child\n"); // Exit, the parent is blocked until we are finished. exit(0); } else {+ trace("resuming rts\n"); rts_resume(r_paused); paused = false; }@@ -260,7 +264,7 @@ uint32_t b = 0; uint32_t size_payload; size_payload=htonl(size);- trace("SIZE %lu", size);+ trace("SIZE %llu", size); resp.write((uint32_t) size_payload); for (uint32_t i = 0; i < size; b++) {@@ -280,7 +284,7 @@ // Small bitmap uint32_t size_payload; size_payload=htonl(size);- trace("SIZE %lu", size);+ trace("SIZE %llu", size); resp.write((uint32_t) size_payload); while (size > 0) { resp.write((uint8_t) ! (bitmap & 1));@@ -361,34 +365,38 @@ /* return non-zero on error */ static int handle_command(Socket& sock, const char *buf, uint32_t cmd_len) {- trace("HANDLE: %d\n", cmd_len);+ trace("handling command of length: %d\n", cmd_len); Parser p(buf, cmd_len); Response resp(sock);- trace("P %lu\n", p.available()); uint32_t cmd = ntohl(p.get<uint32_t>());- trace("CMD: %d\n", cmd);+ trace("read CommandId: %d\n", cmd); switch (cmd) { case CMD_VERSION: uint32_t ver_payload;- ver_payload=htonl(0);+ uint32_t ver_payload1;+ ver_payload=htonl(__GLASGOW_HASKELL__) ;+ ver_payload1=htonl(__GLASGOW_HASKELL_PATCHLEVEL1__) ; resp.write(ver_payload);+ resp.write(ver_payload1); resp.finish(RESP_OKAY); break; case CMD_PAUSE:+ trace("handling pause command\n");+ trace("paused already?: %s\n", paused ? "yes" : "no"); use_fork = (bool)ntohl(p.get<uint8_t>());- trace("PAUSE: %d", paused);- trace("PAUSE(FORK): %d", use_fork); if (paused) {- trace("ALREADY"); resp.finish(RESP_ALREADY_PAUSED); } else {+ trace("fork?: %s\n", use_fork ? "yes" : "no"); pause_mutator(); resp.finish(RESP_OKAY); } break; case CMD_RESUME:+ trace("handling resume command\n");+ trace("already running?: %s\n", paused ? "no" : "yes"); if (!paused) { resp.finish(RESP_NOT_PAUSED); } else if (r_poll_pause_resp){@@ -638,23 +646,29 @@ Socket sock(sock_fd); char *buf = new char[MAX_CMD_SIZE]; while (true) {+ trace("handler is waiting for a request\n"); uint32_t cmdlen_n, cmdlen; - sock.read((char *)&cmdlen_n, 4);- cmdlen = ntohl(cmdlen_n);+ size_t n_read = sock.read((char *)&cmdlen_n, 4); + // If the read returns 0, consider it a disconnect+ if (n_read == 0) {+ trace("handler is done\n");+ return;+ }+ cmdlen = ntohl(cmdlen_n);+ char *large_buf = buf; bool use_large_buf = cmdlen > MAX_CMD_SIZE; if (use_large_buf) { large_buf = new char[cmdlen]; } - trace("LEN: %d\n", cmdlen);+ trace("reading cmd of length: %d\n", cmdlen); sock.read(large_buf, cmdlen);- trace("CONT:%s\n", buf);+ trace("leftover: %s\n", buf); try {- trace("LEN2: %d\n", cmdlen); handle_command(sock, large_buf, cmdlen); } catch (Parser::EndOfInput e) { barf("error");@@ -698,55 +712,58 @@ extern "C" void start(const char* socket_path) {- trace("starting\n");+ trace("starting with socket path: %s\n", socket_path); struct sockaddr_un local, remote; if (strlen(socket_path) >= sizeof(local.sun_path)) { barf("socket_path too long: \"%s\"", socket_path); } - int s = socket(AF_UNIX, SOCK_STREAM, 0);- if (s == -1) {+ // Open the socket for listening+ int listenHdl = socket(AF_UNIX, SOCK_STREAM, 0);+ if (listenHdl == -1) { barf("socket failed"); } - // Bind socket- {- local.sun_family = AF_UNIX;- strncpy(local.sun_path, socket_path, sizeof(local.sun_path));- unlink(local.sun_path);- if (bind(s, (struct sockaddr *) &local, sizeof(local)) != 0) {- barf("bind failed");- }+ // Bind the socket to an address+ local.sun_family = AF_UNIX;+ strncpy(local.sun_path, socket_path, sizeof(local.sun_path));+ unlink(local.sun_path);+ if (bind(listenHdl, (struct sockaddr *) &local, sizeof(local)) != 0) {+ barf("bind failed"); } - if (listen(s, 1) != 0) {+ // Listen for connections+ if (listen(listenHdl, 1) != 0) { barf("listen failed"); } fflush(stdout);+ while (true) {- socklen_t len;- int s2 = accept(s, (struct sockaddr *) &remote, &len);- if (s2 == -1) {- barf("accept failed %d", s2);+ // Wait for client connection+ socklen_t len = sizeof(remote);+ int commHdl = accept(listenHdl, (struct sockaddr *) &remote, &len);+ if (commHdl == -1) {+ barf("accept failed %s", strerror(errno)); }- handle_connection(s2);+ + // Handle and on disconnect listen for more connections+ handle_connection(commHdl); } } extern "C" StgWord saveClosures(StgWord n, HsStablePtr *sps) {- struct savedObjectsState *ps = &g_savedObjectState; StgWord i; if(n > maxSavedObjects) return maxSavedObjects; for (i = 0; i < n; i++) {- ps->objects[i] = sps[i];+ g_savedObjectState.objects[i] = sps[i]; }- ps->n_objects = i;+ g_savedObjectState.n_objects = i; return 0; }
ghc-debug-stub.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: ghc-debug-stub-version: 0.2.1.0+version: 0.3.0.0 synopsis: Functions for instrumenting your application so the heap can be analysed with ghc-debug-common. description: Functions for instrumenting your application so the heap can@@ -27,12 +27,12 @@ , directory ^>= 1.3 , filepath ^>= 1.4 , ghc-prim ^>= 0.8- , ghc-debug-convention == 0.2.0.0+ , ghc-debug-convention == 0.3.0.0 default-language: Haskell2010 cxx-sources: cbits/stub.cpp, cbits/socket.cpp, cbits/trace.cpp- cxx-options: -std=gnu++11 -O3 -g3 -DTHREADED_RTS+ cxx-options: -std=gnu++11 -pthread -O3 -g3 -DTHREADED_RTS extra-libraries: stdc++ cpp-options: -DTHREADED_RTS if flag(trace)- cpp-options: -DTRACE+ cxx-options: -DTRACE