Skip to content

Commit 826997c

Browse files
committed
[lldb] Fix a regression introduced by D75730
In a new Range class was introduced to simplify and the Disassembler API and reduce duplication. It unintentionally broke the SBFrame::Disassemble functionality because it unconditionally converts the number of instructions to a Range{Limit::Instructions, num_instructions}. This is subtly different from the previous behavior, where now we're passing a Range and assume it's valid in the callee, the original code would propagate num_instructions and the callee would compare the value and decided between disassembling instructions or bytes. Unfortunately the existing tests was not particularly strict: disassembly = frame.Disassemble() self.assertNotEqual(len(disassembly), 0, "Disassembly was empty.") This would pass because without this patch we'd disassemble zero instructions, resulting in an error: (lldb) script print(lldb.frame.Disassemble()) error: error reading data from section __text Differential revision: https://reviews.llvm.org/D89925
1 parent a8b0ae3 commit 826997c

File tree

5 files changed

+33
-42
lines changed

5 files changed

+33
-42
lines changed

lldb/include/lldb/Core/Disassembler.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class DataExtractor;
4848
class Debugger;
4949
class Disassembler;
5050
class Module;
51+
class StackFrame;
5152
class Stream;
5253
class SymbolContext;
5354
class SymbolContextList;
@@ -404,11 +405,8 @@ class Disassembler : public std::enable_shared_from_this<Disassembler>,
404405
uint32_t num_mixed_context_lines, uint32_t options,
405406
Stream &strm);
406407

407-
static bool
408-
Disassemble(Debugger &debugger, const ArchSpec &arch, const char *plugin_name,
409-
const char *flavor, const ExecutionContext &exe_ctx,
410-
uint32_t num_instructions, bool mixed_source_and_assembly,
411-
uint32_t num_mixed_context_lines, uint32_t options, Stream &strm);
408+
static bool Disassemble(Debugger &debugger, const ArchSpec &arch,
409+
StackFrame &frame, Stream &strm);
412410

413411
// Constructors and Destructors
414412
Disassembler(const ArchSpec &arch, const char *flavor);

lldb/source/Core/Disassembler.cpp

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -540,34 +540,29 @@ void Disassembler::PrintInstructions(Debugger &debugger, const ArchSpec &arch,
540540
}
541541

542542
bool Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch,
543-
const char *plugin_name, const char *flavor,
544-
const ExecutionContext &exe_ctx,
545-
uint32_t num_instructions,
546-
bool mixed_source_and_assembly,
547-
uint32_t num_mixed_context_lines,
548-
uint32_t options, Stream &strm) {
543+
StackFrame &frame, Stream &strm) {
549544
AddressRange range;
550-
StackFrame *frame = exe_ctx.GetFramePtr();
551-
if (frame) {
552-
SymbolContext sc(
553-
frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
554-
if (sc.function) {
555-
range = sc.function->GetAddressRange();
556-
} else if (sc.symbol && sc.symbol->ValueIsAddress()) {
557-
range.GetBaseAddress() = sc.symbol->GetAddressRef();
558-
range.SetByteSize(sc.symbol->GetByteSize());
559-
} else {
560-
range.GetBaseAddress() = frame->GetFrameCodeAddress();
561-
}
545+
SymbolContext sc(
546+
frame.GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
547+
if (sc.function) {
548+
range = sc.function->GetAddressRange();
549+
} else if (sc.symbol && sc.symbol->ValueIsAddress()) {
550+
range.GetBaseAddress() = sc.symbol->GetAddressRef();
551+
range.SetByteSize(sc.symbol->GetByteSize());
552+
} else {
553+
range.GetBaseAddress() = frame.GetFrameCodeAddress();
554+
}
562555

563556
if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
564557
range.SetByteSize(DEFAULT_DISASM_BYTE_SIZE);
565-
}
566558

567-
return Disassemble(
568-
debugger, arch, plugin_name, flavor, exe_ctx, range.GetBaseAddress(),
569-
{Limit::Instructions, num_instructions}, mixed_source_and_assembly,
570-
num_mixed_context_lines, options, strm);
559+
Disassembler::Limit limit = {Disassembler::Limit::Bytes,
560+
range.GetByteSize()};
561+
if (limit.value == 0)
562+
limit.value = DEFAULT_DISASM_BYTE_SIZE;
563+
564+
return Disassemble(debugger, arch, nullptr, nullptr, frame,
565+
range.GetBaseAddress(), limit, false, 0, 0, strm);
571566
}
572567

573568
Instruction::Instruction(const Address &address, AddressClass addr_class)

lldb/source/Target/StackFrame.cpp

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -229,21 +229,16 @@ bool StackFrame::ChangePC(addr_t pc) {
229229

230230
const char *StackFrame::Disassemble() {
231231
std::lock_guard<std::recursive_mutex> guard(m_mutex);
232-
if (m_disassembly.Empty()) {
233-
ExecutionContext exe_ctx(shared_from_this());
234-
Target *target = exe_ctx.GetTargetPtr();
235-
if (target) {
236-
const char *plugin_name = nullptr;
237-
const char *flavor = nullptr;
238-
Disassembler::Disassemble(target->GetDebugger(),
239-
target->GetArchitecture(), plugin_name, flavor,
240-
exe_ctx, 0, false, 0, 0, m_disassembly);
241-
}
242-
if (m_disassembly.Empty())
243-
return nullptr;
232+
if (!m_disassembly.Empty())
233+
return m_disassembly.GetData();
234+
235+
ExecutionContext exe_ctx(shared_from_this());
236+
if (Target *target = exe_ctx.GetTargetPtr()) {
237+
Disassembler::Disassemble(target->GetDebugger(), target->GetArchitecture(),
238+
*this, m_disassembly);
244239
}
245240

246-
return m_disassembly.GetData();
241+
return m_disassembly.Empty() ? nullptr : m_disassembly.GetData();
247242
}
248243

249244
Block *StackFrame::GetFrameBlock() {

lldb/test/API/commands/disassemble/basic/TestFrameDisassemble.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,6 @@ def frame_disassemble_test(self):
5757

5858
frame = threads[0].GetFrameAtIndex(0)
5959
disassembly = frame.Disassemble()
60-
self.assertNotEqual(len(disassembly), 0, "Disassembly was empty.")
60+
self.assertNotEqual(disassembly, "")
61+
self.assertNotIn("error", disassembly)
62+
self.assertIn(": nop", disassembly)

lldb/test/API/commands/disassemble/basic/main.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ int
22
sum (int a, int b)
33
{
44
int result = a + b; // Set a breakpoint here
5+
asm("nop");
56
return result;
67
}
78

0 commit comments

Comments
 (0)