This is an automated email from the ASF dual-hosted git repository.

alexey pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/kudu.git


The following commit(s) were added to refs/heads/master by this push:
     new df40fff0d [macos] Add sample to PstackWatcher
df40fff0d is described below

commit df40fff0dea06fde06c3cc4967047177524f0b09
Author: Marton Greber <[email protected]>
AuthorDate: Mon Aug 29 18:39:27 2022 +0200

    [macos] Add sample to PstackWatcher
    
    As of now, PstackWatcher is not working on macOS. None of the utilized
    tools (gdb, pstack, gstack) work on macOS. ‘sample’ is an OSX specific
    command-line tool, which can collect call stacks of all threads in a
    process. [1] To get the instantaneous call stack of a process, one can
    call: ‘sample $PID 0’. This patch adds sample to PstackWatcher. With
    sample added, the PstackWatcher tests are enabled and running
    successfully on macOS. I tested it on my M1 MacBook Pro.
    
    The origin of this investigation has been the memory_gc-itest, which was
    failing on my M1 MacBook Pro, with the following error message:
    “Couldn't dump stacks: Service unavailable: Neither gdb, pstack, nor
    gstack appear to be installed.”. Using this patch the test still fails,
    however now I obtain a proper call stack dump, which is valuable for
    future investigations.
    
    [1] https://www.unix.com/man-page/osx/1/sample/
    
    Change-Id: I59cea0e8dc99ceb00901f13805a43ec4f11d0a64
    Reviewed-on: http://gerrit.cloudera.org:8080/18971
    Tested-by: Kudu Jenkins
    Reviewed-by: Alexey Serbin <[email protected]>
---
 src/kudu/util/CMakeLists.txt    |  2 +-
 src/kudu/util/pstack_watcher.cc | 28 ++++++++++++++++++++++++++--
 src/kudu/util/pstack_watcher.h  |  8 ++++++++
 3 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/src/kudu/util/CMakeLists.txt b/src/kudu/util/CMakeLists.txt
index ea1374223..7fe9b5f43 100644
--- a/src/kudu/util/CMakeLists.txt
+++ b/src/kudu/util/CMakeLists.txt
@@ -506,6 +506,7 @@ ADD_KUDU_TEST(once-test)
 ADD_KUDU_TEST(os-util-test)
 ADD_KUDU_TEST(path_util-test)
 ADD_KUDU_TEST(process_memory-test RUN_SERIAL true)
+ADD_KUDU_TEST(pstack_watcher-test)
 ADD_KUDU_TEST(random-test)
 ADD_KUDU_TEST(random_util-test)
 ADD_KUDU_TEST(rle-test)
@@ -535,7 +536,6 @@ ADD_KUDU_TEST(yamlreader-test)
 
 if (NOT APPLE)
   ADD_KUDU_TEST(minidump-test)
-  ADD_KUDU_TEST(pstack_watcher-test)
 endif()
 
 #######################################
diff --git a/src/kudu/util/pstack_watcher.cc b/src/kudu/util/pstack_watcher.cc
index 3b43eda29..07ab6cef3 100644
--- a/src/kudu/util/pstack_watcher.cc
+++ b/src/kudu/util/pstack_watcher.cc
@@ -163,7 +163,6 @@ Status PstackWatcher::DumpStacks(int flags) {
 }
 
 Status PstackWatcher::DumpPidStacks(pid_t pid, int flags) {
-
   // Prefer GDB if available; it gives us line numbers and thread names.
   Status s = HasGoodGdb();
   if (s.ok()) {
@@ -180,7 +179,15 @@ Status PstackWatcher::DumpPidStacks(pid_t pid, int flags) {
     WARN_NOT_OK(s, Substitute("$0 not available", p));
   }
 
-  return Status::ServiceUnavailable("Neither gdb, pstack, nor gstack appear to 
be installed.");
+#if defined(__APPLE__)
+  s = HasGoodSample();
+  if (s.ok()) {
+    return RunSampleStackDump(pid);
+  }
+#endif
+
+  return Status::ServiceUnavailable(
+      "Neither gdb, pstack, gstack, nor sample (OSX) appear to be installed.");
 }
 
 Status PstackWatcher::RunGdbStackDump(pid_t pid, int flags) {
@@ -219,6 +226,23 @@ Status PstackWatcher::RunPstack(const std::string& 
progname, pid_t pid) {
   return RunStackDump(argv);
 }
 
+#if defined(__APPLE__)
+Status PstackWatcher::HasGoodSample() {
+  // Check for the existence of sample.
+  RETURN_NOT_OK(HasProgram("sample"));
+  return Status::OK();
+}
+
+Status PstackWatcher::RunSampleStackDump(pid_t pid) {
+  // Command: sample $PID 0
+  vector<string> argv;
+  argv.emplace_back("sample");
+  argv.emplace_back(Substitute("$0", pid));
+  argv.emplace_back("0");
+  return RunStackDump(argv);
+}
+#endif
+
 Status PstackWatcher::RunStackDump(const vector<string>& argv) {
   printf("************************ BEGIN STACKS **************************\n");
   if (fflush(stdout) == EOF) {
diff --git a/src/kudu/util/pstack_watcher.h b/src/kudu/util/pstack_watcher.h
index 882e6d2a3..0a958f402 100644
--- a/src/kudu/util/pstack_watcher.h
+++ b/src/kudu/util/pstack_watcher.h
@@ -83,6 +83,14 @@ class PstackWatcher {
   // Get a stack dump using the pstack or gstack program.
   static Status RunPstack(const std::string& progname, pid_t pid);
 
+#if defined(__APPLE__)
+  // Check whether the system path has 'sample'
+  static Status HasGoodSample();
+
+  // Get a stack dump using sample directly.
+  static Status RunSampleStackDump(pid_t pid);
+#endif
+
   // Invoke and wait for the stack dump program.
   static Status RunStackDump(const std::vector<std::string>& argv);
 

Reply via email to