diff --git a/lldb/test/API/tools/intel-features/intel-pt/test/Makefile b/lldb/test/API/tools/intel-features/intel-pt/test/Makefile new file mode 100644 --- /dev/null +++ b/lldb/test/API/tools/intel-features/intel-pt/test/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/lldb/test/API/tools/intel-features/intel-pt/test/TestIntelPTSimpleBinary.py b/lldb/test/API/tools/intel-features/intel-pt/test/TestIntelPTSimpleBinary.py new file mode 100644 --- /dev/null +++ b/lldb/test/API/tools/intel-features/intel-pt/test/TestIntelPTSimpleBinary.py @@ -0,0 +1,59 @@ +from __future__ import print_function + +import os +import lldb +import time + +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestIntelPTSimpleBinary(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + @skipIf(oslist=no_match(['linux'])) + @skipIf(archs=no_match(['i386', 'x86_64'])) + @skipIfRemote + def test_basic_flow(self): + """Test collection, decoding, and dumping instructions""" + lldb_exec_dir = os.environ["LLDB_IMPLIB_DIR"] + lldb_lib_dir = os.path.join(lldb_exec_dir, os.pardir, "lib") + plugin_file = os.path.join(lldb_lib_dir, "liblldbIntelFeatures.so") + if not os.path.isfile(plugin_file): + self.skipTest("features plugin missing.") + + self.build() + + self.runCmd("plugin load " + plugin_file) + + exe = self.getBuildArtifact("a.out") + lldbutil.run_to_name_breakpoint(self, "main", exe_name=exe) + # We start tracing from main + self.runCmd("processor-trace start all") + + # We check the trace after the for loop + self.runCmd("b " + str(line_number('main.cpp', '// Break 1'))) + self.runCmd("c") + + # We wait a little bit to ensure the processor has send the PT packets to + # the memory + time.sleep(.1) + + # We find the start address of the 'fun' function for a later check + target = self.dbg.GetSelectedTarget() + fun_start_adddress = target.FindFunctions("fun")[0].GetSymbol() \ + .GetStartAddress().GetLoadAddress(target) + + # We print the last instructions + self.expect("processor-trace show-instr-log -c 100", + patterns=[ + # We expect to have seen the first instruction of 'fun' + hex(fun_start_adddress), + # We expect to see the exit condition of the for loop + "at main.cpp:" + str(line_number('main.cpp', '// Break for loop')) + ]) + + self.runCmd("processor-trace stop") diff --git a/lldb/test/API/tools/intel-features/intel-pt/test/main.cpp b/lldb/test/API/tools/intel-features/intel-pt/test/main.cpp new file mode 100644 --- /dev/null +++ b/lldb/test/API/tools/intel-features/intel-pt/test/main.cpp @@ -0,0 +1,14 @@ +#include + +using namespace std; + +int fun(int a) { return a * a + 1; } + +int main() { + int z = 0; + for (int i = 0; i < 10000; i++) { // Break for loop + z += fun(z); + } + + return 0; // Break 1 +} diff --git a/lldb/tools/intel-features/intel-pt/cli-wrapper-pt.cpp b/lldb/tools/intel-features/intel-pt/cli-wrapper-pt.cpp --- a/lldb/tools/intel-features/intel-pt/cli-wrapper-pt.cpp +++ b/lldb/tools/intel-features/intel-pt/cli-wrapper-pt.cpp @@ -191,6 +191,7 @@ result.SetStatus(lldb::eReturnStatusFailed); return false; } + result.SetStatus(lldb::eReturnStatusSuccessFinishResult); return true; } @@ -290,6 +291,7 @@ s.GetData()); result.AppendMessage(res.GetOutput()); } + result.SetStatus(lldb::eReturnStatusSuccessFinishResult); return true; } @@ -428,6 +430,7 @@ } result.AppendMessage(res.GetOutput()); } + result.SetStatus(lldb::eReturnStatusSuccessFinishResult); return true; } @@ -480,6 +483,7 @@ result.SetStatus(lldb::eReturnStatusFailed); return false; } + result.SetStatus(lldb::eReturnStatusSuccessFinishResult); return true; }