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:
./bin/lldb /tmp/a.out -o 'b main' -o r -o 'script print(lldb.frame.Disassemble())'
(lldb) target create "/tmp/a.out"
Current executable set to '/tmp/a.out' (x86_64).
(lldb) b main
Breakpoint 1: where = a.out`main + 11 at foo.c:2:3, address = 0x0000000100003fab
(lldb) r
Process 22141 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x0000000100003fab a.out`main at foo.c:2:3
1 int main() {
-> 2 return 10;
3 }
Process 22141 launched: '/tmp/a.out' (x86_64)
(lldb) script print(lldb.frame.Disassemble())
error: error reading data from section __text
Maybe change this to take a StackFrame& argument? The only caller StackFrame::Disassemble, so the frame argument is always valid (and a lot of this defensive code is not needed).