[intel-pt] Implement a basic test case

* This is a reattempted commit due to a previous builtbot failure

- Now using a env var to determine whether to run the test, as
someone might have built liblldbIntelFeatures.so without intelPT
support, which would make this test fail.

Summary:
Depends on D76872.

There was no test for the Intel PT support on LLDB, so I'm creating one, which
will help making progress on solid grounds.

The test is skipped if the Intel PT plugin library is not built.

Reviewers: clayborg, labath, kusmour, aadsm

Subscribers: lldb-commits

Tags: #lldb

Differential Revision: https://reviews.llvm.org/D77107
This commit is contained in:
Walter Erquinigo 2020-03-30 17:26:58 -07:00
parent 631ee8b24a
commit b78157c88b
4 changed files with 77 additions and 0 deletions

View File

@ -0,0 +1,3 @@
CXX_SOURCES := main.cpp
include Makefile.rules

View File

@ -0,0 +1,60 @@
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"""
if os.environ.get('TEST_INTEL_PT') != '1':
self.skipTest("The environment variable TEST_INTEL_PT=1 is needed to run this test.")
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")
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")

View File

@ -0,0 +1,10 @@
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
}

View File

@ -191,6 +191,7 @@ public:
result.SetStatus(lldb::eReturnStatusFailed);
return false;
}
result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
return true;
}
@ -290,6 +291,7 @@ public:
s.GetData());
result.AppendMessage(res.GetOutput());
}
result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
return true;
}
@ -428,6 +430,7 @@ public:
}
result.AppendMessage(res.GetOutput());
}
result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
return true;
}
@ -480,6 +483,7 @@ public:
result.SetStatus(lldb::eReturnStatusFailed);
return false;
}
result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
return true;
}