summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/API/SBFrame.h4
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/frame-language/Makefile12
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/frame-language/TestGuessLanguage.py81
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/frame-language/main.cpp10
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/frame-language/other-2.cpp7
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/frame-language/other.cpp10
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/frame-language/other.h7
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/frame-language/somefunc.c7
-rw-r--r--lldb/scripts/interface/SBFrame.i8
-rw-r--r--lldb/source/API/SBFrame.cpp19
-rw-r--r--lldb/source/Core/Mangled.cpp8
-rw-r--r--lldb/source/Target/StackFrame.cpp11
12 files changed, 181 insertions, 3 deletions
diff --git a/lldb/include/lldb/API/SBFrame.h b/lldb/include/lldb/API/SBFrame.h
index be5c0920aee..58339750def 100644
--- a/lldb/include/lldb/API/SBFrame.h
+++ b/lldb/include/lldb/API/SBFrame.h
@@ -78,6 +78,10 @@ public:
const char *GetDisplayFunctionName();
const char *GetFunctionName() const;
+
+ // Return the frame function's language. If there isn't a function, then
+ // guess the language type from the mangled name.
+ lldb::LanguageType GuessLanguage() const;
/// Return true if this frame represents an inlined function.
///
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/frame-language/Makefile b/lldb/packages/Python/lldbsuite/test/functionalities/frame-language/Makefile
new file mode 100644
index 00000000000..089fc237b05
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/frame-language/Makefile
@@ -0,0 +1,12 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp other.cpp other-2.cpp
+C_SOURCES := somefunc.c
+
+include $(LEVEL)/Makefile.rules
+
+other-2.o: other-2.cpp
+ $(CXX) $(CFLAGS_NO_DEBUG) -c other-2.cpp
+
+somefunc.o: somefunc.c
+ $(CC) $(CFLAGS) -std=c99 -c somefunc.c \ No newline at end of file
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/frame-language/TestGuessLanguage.py b/lldb/packages/Python/lldbsuite/test/functionalities/frame-language/TestGuessLanguage.py
new file mode 100644
index 00000000000..7aa3e29af55
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/frame-language/TestGuessLanguage.py
@@ -0,0 +1,81 @@
+"""
+Test the SB API SBFrame::GuessLanguage.
+"""
+
+from __future__ import print_function
+
+
+import os
+import time
+import re
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.lldbtest import *
+
+
+class TestFrameGuessLanguage(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ # If your test case doesn't stress debug info, the
+ # set this to true. That way it won't be run once for
+ # each debug info format.
+ NO_DEBUG_INFO_TESTCASE = True
+
+ def test_guess_language(self):
+ """Test GuessLanguage for C and C++."""
+ self.build()
+ self.do_test()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+
+ def check_language(self, thread, frame_no, test_lang):
+ frame = thread.frames[frame_no]
+ self.assertTrue(frame.IsValid(), "Frame %d was not valid."%(frame_no))
+ lang = frame.GuessLanguage()
+ self.assertEqual(lang, test_lang)
+
+ def do_test(self):
+ """Test GuessLanguage for C & C++."""
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ # Create a target by the debugger.
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ # Now create a breakpoint in main.c at the source matching
+ # "Set a breakpoint here"
+ breakpoint = target.BreakpointCreateBySourceRegex(
+ "Set breakpoint here", lldb.SBFileSpec("somefunc.c"))
+ self.assertTrue(breakpoint and
+ breakpoint.GetNumLocations() >= 1,
+ VALID_BREAKPOINT)
+
+ error = lldb.SBError()
+ # This is the launch info. If you want to launch with arguments or
+ # environment variables, add them using SetArguments or
+ # SetEnvironmentEntries
+
+ launch_info = lldb.SBLaunchInfo(None)
+ process = target.Launch(launch_info, error)
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ # Did we hit our breakpoint?
+ from lldbsuite.test.lldbutil import get_threads_stopped_at_breakpoint
+ threads = get_threads_stopped_at_breakpoint(process, breakpoint)
+ self.assertTrue(
+ len(threads) == 1,
+ "There should be a thread stopped at our breakpoint")
+
+ # The hit count for the breakpoint should be 1.
+ self.assertTrue(breakpoint.GetHitCount() == 1)
+
+ thread = threads[0]
+ self.check_language(thread, 0, lldb.eLanguageTypeC99)
+ self.check_language(thread, 1, lldb.eLanguageTypeC_plus_plus)
+ self.check_language(thread, 2, lldb.eLanguageTypeC_plus_plus)
+
+
+
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/frame-language/main.cpp b/lldb/packages/Python/lldbsuite/test/functionalities/frame-language/main.cpp
new file mode 100644
index 00000000000..f5449f21790
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/frame-language/main.cpp
@@ -0,0 +1,10 @@
+#include <stdio.h>
+#include "other.h"
+
+int
+main()
+{
+ int test_var = 10;
+ Other::DoSomethingElse();
+ return 0;
+}
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/frame-language/other-2.cpp b/lldb/packages/Python/lldbsuite/test/functionalities/frame-language/other-2.cpp
new file mode 100644
index 00000000000..77632de3ceb
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/frame-language/other-2.cpp
@@ -0,0 +1,7 @@
+#include "other.h"
+
+void
+Other::DoSomethingElse()
+{
+ DoSomething();
+}
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/frame-language/other.cpp b/lldb/packages/Python/lldbsuite/test/functionalities/frame-language/other.cpp
new file mode 100644
index 00000000000..41f4f26079a
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/frame-language/other.cpp
@@ -0,0 +1,10 @@
+#include "other.h"
+
+extern "C" void some_func();
+
+void
+Other::DoSomething()
+{
+ some_func();
+}
+
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/frame-language/other.h b/lldb/packages/Python/lldbsuite/test/functionalities/frame-language/other.h
new file mode 100644
index 00000000000..0a2c125e6b4
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/frame-language/other.h
@@ -0,0 +1,7 @@
+class Other
+{
+ public:
+ static void DoSomething();
+ static void DoSomethingElse();
+};
+
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/frame-language/somefunc.c b/lldb/packages/Python/lldbsuite/test/functionalities/frame-language/somefunc.c
new file mode 100644
index 00000000000..a4b4f47f32e
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/frame-language/somefunc.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+void
+some_func()
+{
+ printf("Set breakpoint here.");
+}
diff --git a/lldb/scripts/interface/SBFrame.i b/lldb/scripts/interface/SBFrame.i
index 1c10a9b6e3e..b8654cb0eb6 100644
--- a/lldb/scripts/interface/SBFrame.i
+++ b/lldb/scripts/interface/SBFrame.i
@@ -133,6 +133,14 @@ public:
const char *
GetFunctionName() const;
+
+ %feature("docstring", "
+ /// Returns the language of the frame's SBFunction, or if there.
+ /// is no SBFunction, guess the language from the mangled name.
+ /// .
+ ") GuessLanguage;
+ lldb::LanguageType
+ GuessLanguage() const;
%feature("docstring", "
/// Return true if this frame represents an inlined function.
diff --git a/lldb/source/API/SBFrame.cpp b/lldb/source/API/SBFrame.cpp
index d31527450c7..d52bbe8069f 100644
--- a/lldb/source/API/SBFrame.cpp
+++ b/lldb/source/API/SBFrame.cpp
@@ -1370,6 +1370,25 @@ const char *SBFrame::GetFunctionName() {
return static_cast<const SBFrame *>(this)->GetFunctionName();
}
+lldb::LanguageType SBFrame::GuessLanguage() const {
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+
+ StackFrame *frame = nullptr;
+ Target *target = exe_ctx.GetTargetPtr();
+ Process *process = exe_ctx.GetProcessPtr();
+ if (target && process) {
+ Process::StopLocker stop_locker;
+ if (stop_locker.TryLock(&process->GetRunLock())) {
+ frame = exe_ctx.GetFramePtr();
+ if (frame) {
+ return frame->GuessLanguage();
+ }
+ }
+ }
+ return eLanguageTypeUnknown;
+}
+
const char *SBFrame::GetFunctionName() const {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
const char *name = nullptr;
diff --git a/lldb/source/Core/Mangled.cpp b/lldb/source/Core/Mangled.cpp
index 0baf0622c77..3d96340b911 100644
--- a/lldb/source/Core/Mangled.cpp
+++ b/lldb/source/Core/Mangled.cpp
@@ -432,6 +432,14 @@ lldb::LanguageType Mangled::GuessLanguage() const {
else if (ObjCLanguage::IsPossibleObjCMethodName(mangled_name))
return lldb::eLanguageTypeObjC;
}
+ } else {
+ // ObjC names aren't really mangled, so they won't necessarily be in the
+ // mangled name slot.
+ ConstString demangled_name = GetDemangledName(lldb::eLanguageTypeUnknown);
+ if (demangled_name
+ && ObjCLanguage::IsPossibleObjCMethodName(demangled_name.GetCString()))
+ return lldb::eLanguageTypeObjC;
+
}
return lldb::eLanguageTypeUnknown;
}
diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp
index 03151fbfc17..7b7b596c977 100644
--- a/lldb/source/Target/StackFrame.cpp
+++ b/lldb/source/Target/StackFrame.cpp
@@ -1212,9 +1212,14 @@ lldb::LanguageType StackFrame::GuessLanguage() {
LanguageType lang_type = GetLanguage();
if (lang_type == eLanguageTypeUnknown) {
- Function *f = GetSymbolContext(eSymbolContextFunction).function;
- if (f) {
- lang_type = f->GetMangled().GuessLanguage();
+ SymbolContext sc = GetSymbolContext(eSymbolContextFunction
+ | eSymbolContextSymbol);
+ if (sc.function) {
+ lang_type = sc.function->GetMangled().GuessLanguage();
+ }
+ else if (sc.symbol)
+ {
+ lang_type = sc.symbol->GetMangled().GuessLanguage();
}
}
OpenPOWER on IntegriCloud