summaryrefslogtreecommitdiffstats
path: root/lldb/test/python_api
diff options
context:
space:
mode:
authorJohnny Chen <johnny.chen@apple.com>2011-04-19 22:44:20 +0000
committerJohnny Chen <johnny.chen@apple.com>2011-04-19 22:44:20 +0000
commit0b8fd4339758dd30531347e061d003a7478ba3ff (patch)
tree12912a6e33931a7155c91acaaa9c12467c34f3c1 /lldb/test/python_api
parent85866ba033faa0bd81e39184dfbd2344ee192fc0 (diff)
downloadbcm5719-llvm-0b8fd4339758dd30531347e061d003a7478ba3ff.tar.gz
bcm5719-llvm-0b8fd4339758dd30531347e061d003a7478ba3ff.zip
Rename test/threads to python_api/lldbutil; it uses lldbutil functions to print stack traces.
llvm-svn: 129828
Diffstat (limited to 'lldb/test/python_api')
-rw-r--r--lldb/test/python_api/lldbutil/Makefile6
-rw-r--r--lldb/test/python_api/lldbutil/TestPrintStackTraces.py57
-rw-r--r--lldb/test/python_api/lldbutil/main.cpp128
3 files changed, 191 insertions, 0 deletions
diff --git a/lldb/test/python_api/lldbutil/Makefile b/lldb/test/python_api/lldbutil/Makefile
new file mode 100644
index 00000000000..86af2f4bc70
--- /dev/null
+++ b/lldb/test/python_api/lldbutil/Makefile
@@ -0,0 +1,6 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp
+MAKE_DSYM :=NO
+
+include $(LEVEL)/Makefile.rules
diff --git a/lldb/test/python_api/lldbutil/TestPrintStackTraces.py b/lldb/test/python_api/lldbutil/TestPrintStackTraces.py
new file mode 100644
index 00000000000..4bd4bda8c33
--- /dev/null
+++ b/lldb/test/python_api/lldbutil/TestPrintStackTraces.py
@@ -0,0 +1,57 @@
+"""
+Test SBprocess and SBThread APIs with printing of the stack traces using lldbutil.
+"""
+
+import os, time
+import re
+import unittest2
+import lldb
+from lldbtest import *
+
+class ThreadsStackTracesTestCase(TestBase):
+
+ mydir = "python_api/lldbutil"
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break inside main().
+ self.line = line_number('main.cpp', '// Set break point at this line.')
+
+ def test_stack_traces(self):
+ """Test SBprocess and SBThread APIs with printing of the stack traces."""
+ self.buildDefault()
+ self.break_and_print_stacktraces()
+
+ def break_and_print_stacktraces(self):
+ """Break at main.cpp:68 and do a threads dump"""
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target.IsValid(), VALID_TARGET)
+
+ breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line)
+ self.assertTrue(breakpoint.IsValid(), VALID_BREAKPOINT)
+
+ # Now launch the process, and do not stop at entry point.
+ rc = lldb.SBError()
+ self.process = target.Launch (self.dbg.GetListener(), None, None, os.ctermid(), os.ctermid(), os.ctermid(), None, 0, False, rc)
+
+ if not rc.Success() or not self.process.IsValid():
+ self.fail("SBTarget.LaunchProcess() failed")
+
+ import lldbutil
+ if self.process.GetState() != lldb.eStateStopped:
+ self.fail("Process should be in the 'stopped' state, "
+ "instead the actual state is: '%s'" %
+ lldbutil.StateTypeString(self.process.GetState()))
+
+ if self.TraceOn():
+ lldbutil.PrintStackTraces(self.process)
+
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
diff --git a/lldb/test/python_api/lldbutil/main.cpp b/lldb/test/python_api/lldbutil/main.cpp
new file mode 100644
index 00000000000..0c5fd45388f
--- /dev/null
+++ b/lldb/test/python_api/lldbutil/main.cpp
@@ -0,0 +1,128 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// C includes
+#include <pthread.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+pthread_t g_thread_1 = NULL;
+pthread_t g_thread_2 = NULL;
+pthread_t g_thread_3 = NULL;
+
+typedef enum {
+ eGet,
+ eAssign,
+ eClearBits
+} MaskAction;
+
+uint32_t mask_access (MaskAction action, uint32_t mask = 0);
+
+uint32_t
+mask_access (MaskAction action, uint32_t mask)
+{
+ static pthread_mutex_t g_mask_mutex = PTHREAD_MUTEX_INITIALIZER;
+ static uint32_t g_mask = 0;
+ ::pthread_mutex_lock (&g_mask_mutex);
+ switch (action)
+ {
+ case eGet:
+ break;
+
+ case eAssign:
+ g_mask |= mask;
+ break;
+
+ case eClearBits:
+ g_mask &= ~mask;
+ break;
+ }
+ uint32_t new_mask = g_mask;
+ ::pthread_mutex_unlock (&g_mask_mutex);
+ return new_mask;
+}
+
+void *
+thread_func (void *arg)
+{
+ uint32_t thread_index = *((uint32_t *)arg);
+ uint32_t thread_mask = (1u << (thread_index));
+ printf ("%s (thread index = %u) startng...\n", __FUNCTION__, thread_index);
+
+ while (mask_access(eGet) & thread_mask)
+ {
+ // random micro second sleep from zero to 3 seconds
+ int usec = ::rand() % 3000000;
+ printf ("%s (thread = %u) doing a usleep (%d)...\n", __FUNCTION__, thread_index, usec);
+ ::usleep (usec);
+ printf ("%s (thread = %u) after usleep ...\n", __FUNCTION__, thread_index); // Set break point at this line.
+ }
+ printf ("%s (thread index = %u) exiting...\n", __FUNCTION__, thread_index);
+ return NULL;
+}
+
+
+int main (int argc, char const *argv[])
+{
+ int err;
+ void *thread_result = NULL;
+ uint32_t thread_index_1 = 1;
+ uint32_t thread_index_2 = 2;
+ uint32_t thread_index_3 = 3;
+ uint32_t thread_mask_1 = (1u << thread_index_1);
+ uint32_t thread_mask_2 = (1u << thread_index_2);
+ uint32_t thread_mask_3 = (1u << thread_index_3);
+
+ // Make a mask that will keep all threads alive
+ mask_access (eAssign, thread_mask_1 | thread_mask_2 | thread_mask_3);
+
+ // Create 3 threads
+ err = ::pthread_create (&g_thread_1, NULL, thread_func, &thread_index_1);
+ err = ::pthread_create (&g_thread_2, NULL, thread_func, &thread_index_2);
+ err = ::pthread_create (&g_thread_3, NULL, thread_func, &thread_index_3);
+
+ char line[64];
+ while (mask_access(eGet) != 0)
+ {
+ printf ("Enter thread index to kill or ENTER for all:\n");
+ fflush (stdout);
+ // Kill threads by index, or ENTER for all threads
+
+ if (fgets (line, sizeof(line), stdin))
+ {
+ if (line[0] == '\n' || line[0] == '\r' || line[0] == '\0')
+ {
+ printf ("Exiting all threads...\n");
+ break;
+ }
+ int32_t index = strtoul (line, NULL, 0);
+ switch (index)
+ {
+ case 1: mask_access (eClearBits, thread_mask_1); break;
+ case 2: mask_access (eClearBits, thread_mask_2); break;
+ case 3: mask_access (eClearBits, thread_mask_3); break;
+ }
+ continue;
+ }
+
+ break;
+ }
+
+ // Clear all thread bits to they all exit
+ mask_access (eClearBits, UINT32_MAX);
+
+ // Join all of our threads
+ err = ::pthread_join (g_thread_1, &thread_result);
+ err = ::pthread_join (g_thread_2, &thread_result);
+ err = ::pthread_join (g_thread_3, &thread_result);
+
+ return 0;
+}
OpenPOWER on IntegriCloud