packages feed

ghc-debug-stub 0.5.0.0 → 0.6.0.0

raw patch · 3 files changed

+129/−15 lines, 3 filesdep ~filepathdep ~ghc-debug-conventiondep ~ghc-primPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: filepath, ghc-debug-convention, ghc-prim

API changes (from Hackage documentation)

Files

CHANGELOG.md view
@@ -1,5 +1,10 @@ # Revision history for ghc-debug-stub +## 0.6.0.0 -- 2024-04-10++* Add requests for decoding cost centres and other profiling info+* Update support for GHC as of 9.11.20240410+ ## 0.5.0.0 -- 2023-06-06  * Add support for debugging over a TCP socket (`withGhcDebugTCP`)
cbits/stub.cpp view
@@ -92,7 +92,11 @@     CMD_BLOCKS = 14,     CMD_BLOCK = 15,     CMD_FUN_BITMAP = 16,-    CMD_GET_SRT = 17+    CMD_GET_SRT = 17,+    CMD_GET_CCS = 18,+    CMD_GET_CC = 19,+    CMD_GET_INDEX_TABLE = 20,+    CMD_GET_CSS_MAIN = 21 };  enum response_code {@@ -208,8 +212,6 @@         trace("finishing with code: %d\n", status);         this->flush(status);     }--    Response(Response &x) = delete; };  static bool paused = false;@@ -220,7 +222,7 @@   extern "C"-void pause_mutator() {+pid_t pause_mutator() {   trace("pausing mutator\n");   pid_t pid;   if (use_fork){@@ -238,9 +240,10 @@   }   else {     int status = 0;-    wait(&status);+    waitpid(pid,&status,0);     use_fork = false;   }+  return pid; }  extern "C"@@ -399,10 +402,36 @@       case CMD_VERSION:         uint32_t ver_payload;         uint32_t ver_payload1;+        uint8_t ver_payload2;+        uint8_t ver_payload3;         ver_payload=htonl(__GLASGOW_HASKELL__) ;         ver_payload1=htonl(__GLASGOW_HASKELL_PATCHLEVEL1__) ;+        if (rts_isProfiled()) {+          if (RtsFlags.ProfFlags.doHeapProfile == 0) {+            ver_payload2 = 1;+#if defined(PROFILING)+          // newer versions of GHC have doingRetainerProfiling(), doingLDVProfilingFunctions etc.+          // but we don't use them because they aren't exported in GHCs <= 9.8.+          } else if (RtsFlags.ProfFlags.doHeapProfile == HEAP_BY_RETAINER || RtsFlags.ProfFlags.retainerSelector != NULL) {+            ver_payload2 = 2;+          } else if (RtsFlags.ProfFlags.doHeapProfile == HEAP_BY_LDV || RtsFlags.ProfFlags.bioSelector != NULL) {+            ver_payload2 = 3;+#if defined(GHC_SUPPORTS_ERAS)+          } else if (RtsFlags.ProfFlags.doHeapProfile == HEAP_BY_ERA || RtsFlags.ProfFlags.eraSelector != NULL) {+            ver_payload2 = 4;+#endif+#endif+          } else {+            ver_payload2 = 5;+          }+        } else {+          ver_payload2 = 0;+        }+        ver_payload3=TABLES_NEXT_TO_CODE;         resp.write(ver_payload);         resp.write(ver_payload1);+        resp.write(ver_payload2);+        resp.write(ver_payload3);         resp.finish(RESP_OKAY);         break; @@ -414,8 +443,10 @@             resp.finish(RESP_ALREADY_PAUSED);         } else {             trace("fork?: %s\n", use_fork ? "yes" : "no");-            pause_mutator();-            resp.finish(RESP_OKAY);+            if(pause_mutator() == 0) {+                // only respond in the child+                resp.finish(RESP_OKAY);+            }         }         break; @@ -606,7 +637,7 @@         case CMD_POLL:-        r_poll_pause_resp = &resp;+        r_poll_pause_resp = new Response(resp);         // NOTE: Don't call finish so that the process blocks waiting for         // a response. We will send the response when the process pauses.         break;@@ -630,6 +661,66 @@       //  resp.finish(RESP_OKAY);       //  break; +      case CMD_GET_CCS:+        {+        trace("GET_CCS\n");+        CostCentreStack *ptr = (CostCentreStack *) p.get<uint64_t>();+        resp.write((uint64_t)ptr -> ccsID);+        resp.write((uint64_t)ptr -> cc);+        resp.write((uint64_t)ptr -> prevStack);+        resp.write((uint64_t)ptr -> indexTable);+        resp.write((uint64_t)ptr -> root);+        resp.write((uint64_t)ptr -> depth);+        resp.write((uint64_t)ptr -> scc_count);+        resp.write((uint64_t)ptr -> selected);+        resp.write((uint64_t)ptr -> time_ticks);+        resp.write((uint64_t)ptr -> mem_alloc);+        resp.write((uint64_t)ptr -> inherited_alloc);+        resp.write((uint64_t)ptr -> inherited_ticks);+        resp.finish(RESP_OKAY);+        break;+        }+      case CMD_GET_CC:+        {+        trace("GET_CC\n");+        CostCentre *ptr = (CostCentre *) p.get<uint64_t>();+        resp.write((uint64_t)ptr -> ccID);+        write_string(resp, ptr -> label);+        write_string(resp, ptr -> module);+        write_string(resp, ptr -> srcloc);+        resp.write((uint64_t)ptr -> mem_alloc);+        resp.write((uint64_t)ptr -> time_ticks);+        resp.write((uint64_t)ptr -> is_caf);+        resp.write((uint64_t)ptr -> link);+        resp.finish(RESP_OKAY);+        break;+        }+      case CMD_GET_INDEX_TABLE:+        {+        trace("CMD_GET_INDEX_TABLE\n");+#if defined(PROFILING)+        IndexTable_ *ptr = (IndexTable_ *) p.get<uint64_t>();+        resp.write((uint64_t)ptr -> cc);+        resp.write((uint64_t)ptr -> ccs);+        resp.write((uint64_t)ptr -> next);+        resp.write((uint8_t)ptr -> back_edge);+        resp.finish(RESP_OKAY);+#else /* !PROFILING */+        resp.finish(RESP_BAD_COMMAND);+#endif /* PROFILING */+        break;+        }+      case CMD_GET_CSS_MAIN:+        {+        trace("GET_CSS_MAIN");+#if defined(PROFILING)+        resp.write((uint64_t) CCS_MAIN);+        resp.finish(RESP_OKAY);+#else /* !PROFILING */+        resp.finish(RESP_BAD_COMMAND);+#endif /* PROFILING */+        break;+        }       case CMD_CON_DESCR:         {         trace("CON_DESCR\n");@@ -646,17 +737,28 @@         trace("SOURCE_INFO\n");         StgInfoTable *info_table = (StgInfoTable *) p.get<uint64_t>();         trace("INFO: %p\n", info_table);-        InfoProvEnt * elt = lookupIPE(info_table);++         trace("ELT: %p\n", info_table);+#if MIN_VERSION_GLASGOW_HASKELL(9,11,20240401,0)+        InfoProvEnt elt;+        int elt_res = lookupIPE(info_table, &elt);+#else+        InfoProvEnt * elt = lookupIPE(info_table);+        int elt_res = (bool) elt;+#endif         uint32_t len_payload;-        if (!elt){+        if (!elt_res){           trace("NOT FOUND\n");           resp.write((uint32_t) 0);         }         else {+#if MIN_VERSION_GLASGOW_HASKELL(9,11,20240401,0)+          InfoProv ip = elt.prov;+#else           InfoProv ip = elt->prov;+#endif           trace("FOUND\n");-           size_t len = 6;           write_size(resp, len); 
ghc-debug-stub.cabal view
@@ -1,6 +1,6 @@ cabal-version:       2.4 name:                ghc-debug-stub-version:             0.5.0.0+version:             0.6.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@@ -20,14 +20,19 @@   Default:     False   Manual:      True +flag eras+  Description: Enable eras+  Default:     False+  Manual:      True+ library   exposed-modules:     GHC.Debug.Stub   hs-source-dirs:      src   build-depends:       base >=4.16 && < 5                      , directory ^>= 1.3-                     , filepath ^>= 1.4-                     , ghc-prim >= 0.8 && < 0.11-                     , ghc-debug-convention == 0.5.0.0+                     , filepath >= 1.4 && < 1.6+                     , ghc-prim >= 0.8 && < 0.12+                     , ghc-debug-convention == 0.6.0.0   default-language:    Haskell2010   cxx-sources:         cbits/stub.cpp, cbits/socket.cpp, cbits/trace.cpp   cxx-options:         -std=gnu++11 -pthread -O3 -g3 -DTHREADED_RTS@@ -35,4 +40,6 @@   cpp-options: -DTHREADED_RTS   if flag(trace)     cxx-options: -DTRACE+  if flag(eras)+    cxx-options: -DGHC_SUPPORTS_ERAS