mirror of
https://github.com/intel/llvm.git
synced 2026-01-27 06:06:34 +08:00
[lldb][Symbol] Make sure we decrement PC before checking location list (#74772)
This commit is contained in:
@@ -227,7 +227,8 @@ bool Variable::LocationIsValidForFrame(StackFrame *frame) {
|
||||
// contains the current address when converted to a load address
|
||||
return m_location_list.ContainsAddress(
|
||||
loclist_base_load_addr,
|
||||
frame->GetFrameCodeAddress().GetLoadAddress(target_sp.get()));
|
||||
frame->GetFrameCodeAddressForSymbolication().GetLoadAddress(
|
||||
target_sp.get()));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
C_SOURCES := main.c
|
||||
CXX_SOURCES := main.cpp
|
||||
CFLAGS_EXTRAS := -O1
|
||||
include Makefile.rules
|
||||
|
||||
@@ -7,16 +7,11 @@ from lldbsuite.test import lldbutil
|
||||
|
||||
|
||||
class LocationListLookupTestCase(TestBase):
|
||||
def setUp(self):
|
||||
# Call super's setUp().
|
||||
TestBase.setUp(self)
|
||||
|
||||
@skipIf(oslist=["linux"], archs=["arm"])
|
||||
def test_loclist(self):
|
||||
self.build()
|
||||
exe = self.getBuildArtifact("a.out")
|
||||
|
||||
# Create a target by the debugger.
|
||||
exe = self.getBuildArtifact("a.out")
|
||||
target = self.dbg.CreateTarget(exe)
|
||||
self.assertTrue(target, VALID_TARGET)
|
||||
self.dbg.SetAsync(False)
|
||||
@@ -27,12 +22,15 @@ class LocationListLookupTestCase(TestBase):
|
||||
self.assertTrue(process.IsValid())
|
||||
self.assertTrue(process.is_stopped)
|
||||
|
||||
# Find `main` on the stack, then
|
||||
# find `argv` local variable, then
|
||||
# check that we can read the c-string in argv[0]
|
||||
# Find `bar` on the stack, then
|
||||
# make sure we can read out the local
|
||||
# variables (with both `frame var` and `expr`)
|
||||
for f in process.GetSelectedThread().frames:
|
||||
if f.GetDisplayFunctionName() == "main":
|
||||
if f.GetDisplayFunctionName().startswith("Foo::bar"):
|
||||
argv = f.GetValueForVariablePath("argv").GetChildAtIndex(0)
|
||||
strm = lldb.SBStream()
|
||||
argv.GetDescription(strm)
|
||||
self.assertNotEqual(strm.GetData().find("a.out"), -1)
|
||||
|
||||
process.GetSelectedThread().SetSelectedFrame(f.idx)
|
||||
self.expect_expr("this", result_type="Foo *")
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// The goal with this test is:
|
||||
// 1. Have main() followed by foo()
|
||||
// 2. Have the no-return call to abort() in main be the last instruction
|
||||
// 3. Have the next instruction be the start of foo()
|
||||
// 4. The debug info for argv uses a location list.
|
||||
// clang at -O1 on x86_64 or arm64 has debuginfo like
|
||||
// DW_AT_location (0x00000049:
|
||||
// [0x0000000100003f15, 0x0000000100003f25): DW_OP_reg4 RSI
|
||||
// [0x0000000100003f25, 0x0000000100003f5b): DW_OP_reg15 R15)
|
||||
|
||||
void foo(int);
|
||||
int main(int argc, char **argv) {
|
||||
char *file = argv[0];
|
||||
char f0 = file[0];
|
||||
printf("%c\n", f0);
|
||||
foo(f0);
|
||||
printf("%s %d\n", argv[0], argc);
|
||||
abort(); /// argv is still be accessible here
|
||||
}
|
||||
void foo(int in) { printf("%d\n", in); }
|
||||
23
lldb/test/API/functionalities/location-list-lookup/main.cpp
Normal file
23
lldb/test/API/functionalities/location-list-lookup/main.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
void func(int in);
|
||||
|
||||
struct Foo {
|
||||
int x;
|
||||
[[clang::noinline]] void bar(char **argv);
|
||||
};
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
Foo f{.x = 5};
|
||||
std::printf("%p\n", &f.x);
|
||||
f.bar(argv);
|
||||
return f.x;
|
||||
}
|
||||
|
||||
void Foo::bar(char **argv) {
|
||||
std::printf("%p %p\n", argv, this);
|
||||
std::abort(); /// 'this' should be still accessible
|
||||
}
|
||||
|
||||
void func(int in) { printf("%d\n", in); }
|
||||
Reference in New Issue
Block a user