Closed
Description
Here's an interesting issue I've encountered when debugging - Option<char>
seems to trigger a floating point exception in LLDB.
Environment details:
- Mac OS X 10.10.5
- rustc:
rustc 1.5.0-nightly (eafe106ef 2015-10-15)
- lldb:
lldb-330.0.44
Repro steps:
- Create a file
dwarf.rs
, with the following contents:
fn main() {
let c = thing_with_char('\n');
println!("{:?}", c);
}
fn thing_with_char(c: char) -> Option<char> {
thing_with_option_char(c)
}
fn thing_with_option_char(c: char) -> Option<char> {
Some(c)
}
- Compile it with debug info:
rustc -g dwarf.rs -o dwarf
- Run
dwarf
and see it has the correct output:
$ ./dwarf
Some('\n')
- Run
dwarf
under LLDB, set a breakpoint on thing_with_char, start the program, and step once:
$ lldb ./dwarf
(lldb) target create "./dwarf"
Current executable set to './dwarf' (x86_64).
(lldb) b thing_with_char
Breakpoint 1: where = dwarf`dwarf::thing_with_char + 15 at dwarf.rs:7, address = 0x000000010000148f
(lldb) r
Process 38743 launched: './dwarf' (x86_64)
error: need to add support for DW_TAG_base_type 'char' encoded with DW_ATE = 0x8, bit_size = 32
Process 38743 stopped
* thread #1: tid = 0x15343, 0x000000010000148f dwarf`dwarf::thing_with_char(c=<unavailable>) + 15 at dwarf.rs:7, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x000000010000148f dwarf`dwarf::thing_with_char(c=<unavailable>) + 15 at dwarf.rs:7
4 }
5
6 fn thing_with_char(c: char) -> Option<char> {
-> 7 thing_with_option_char(c)
8 }
9
10 fn thing_with_option_char(c: char) -> Option<char> {
(lldb) n
Floating point exception: 8
The result is a floating point exception. The error message
error: need to add support for DW_TAG_base_type 'char' encoded with DW_ATE = 0x8, bit_size = 32
makes it sound like this is DWARF-related. Also, the Option seems to be a crucial detail - this is what triggers the behavior in my program where I ran into this and also in this repro here.
LLDB's stack trace:
* thread #9: tid = 0x15ee6, 0x0000000101e0c341 LLDB`ExtractBytesFromRegisters(lldb_private::ExecutionContext&, lldb_private::ClangASTType&, lldb_private::DataExtractor const&, lldb_private::DataExtractor const&, lldb_private::DataExtractor const&, lldb_private::DataExtractor const&, lldb_private::DataExtractor const&, lldb_private::DataExtractor const&, lldb::ByteOrder, std::__1::shared_ptr<lldb_private::DataBuffer>&, unsigned int, unsigned int&, unsigned int&, bool&) + 1279, stop reason = EXC_ARITHMETIC (code=EXC_I386_DIV, subcode=0x0)
* frame #0: 0x0000000101e0c341 LLDB`ExtractBytesFromRegisters(lldb_private::ExecutionContext&, lldb_private::ClangASTType&, lldb_private::DataExtractor const&, lldb_private::DataExtractor const&, lldb_private::DataExtractor const&, lldb_private::DataExtractor const&, lldb_private::DataExtractor const&, lldb_private::DataExtractor const&, lldb::ByteOrder, std::__1::shared_ptr<lldb_private::DataBuffer>&, unsigned int, unsigned int&, unsigned int&, bool&) + 1279
frame #1: 0x0000000101e0c055 LLDB`ExtractBytesFromRegisters(lldb_private::ExecutionContext&, lldb_private::ClangASTType&, lldb_private::DataExtractor const&, lldb_private::DataExtractor const&, lldb_private::DataExtractor const&, lldb_private::DataExtractor const&, lldb_private::DataExtractor const&, lldb_private::DataExtractor const&, lldb::ByteOrder, std::__1::shared_ptr<lldb_private::DataBuffer>&, unsigned int, unsigned int&, unsigned int&, bool&) + 531
frame #2: 0x0000000101e0bb0a LLDB`ABISysV_x86_64::GetReturnValueObjectImpl(lldb_private::Thread&, lldb_private::ClangASTType&) const + 1166
frame #3: 0x0000000101d4ebac LLDB`lldb_private::ABI::GetReturnValueObject(lldb_private::Thread&, lldb_private::ClangASTType&, bool) const + 84
frame #4: 0x0000000101d9ad1a LLDB`lldb_private::ThreadPlanStepOut::CalculateReturnValue() + 202
frame #5: 0x0000000101d9abb7 LLDB`lldb_private::ThreadPlanStepOut::DoPlanExplainsStop(lldb_private::Event*) + 415
frame #6: 0x0000000101d96568 LLDB`lldb_private::ThreadPlan::PlanExplainsStop(lldb_private::Event*) + 40
frame #7: 0x0000000101d8f019 LLDB`lldb_private::Thread::ShouldStop(lldb_private::Event*) + 765
frame #8: 0x0000000101d94cc4 LLDB`lldb_private::ThreadList::ShouldStop(lldb_private::Event*) + 488
frame #9: 0x0000000101d66741 LLDB`lldb_private::Process::ShouldBroadcastEvent(lldb_private::Event*) + 379
frame #10: 0x0000000101d63d44 LLDB`lldb_private::Process::HandlePrivateEvent(std::__1::shared_ptr<lldb_private::Event>&) + 356
frame #11: 0x0000000101d66e81 LLDB`lldb_private::Process::RunPrivateStateThread() + 511
frame #12: 0x0000000101d66935 LLDB`lldb_private::Process::PrivateStateThread(void*) + 9
frame #13: 0x00007fff92d6605a libsystem_pthread.dylib`_pthread_body + 131
frame #14: 0x00007fff92d65fd7 libsystem_pthread.dylib`_pthread_start + 176
frame #15: 0x00007fff92d633ed libsystem_pthread.dylib`thread_start + 13
This could very well be a bug in lldb - it does look like it's dividing by zero.