Last Updated: April 06, 2017
·
23.02K
· themichael'tips

Practical lldb with core dump

Today I merged a C++11 compliant code that does not work on RELEASE mode on OS X El Capitan.

Only on DEBUG mode the code run without segmentation fault. This is may caused by severals reasons.

The same code works like a charm on Linux, so my curiosity was amplified.
Here the steps I used in order to find the method's call that caused the problem on OS X:

1° Activate the generation of core dump file on Os X:

ulimit -c unlimited  
defaults write com.apple.finder AppleShowAllFiles TRUE

2° Run the target program (in my case):

➜  build_deformetrica test/RunUnitTests --gtest_filter='TestReadConfiguration.data_set'  
Note: Google Test filter = TestReadConfiguration.data_set  
[==========] Running 1 test from 1 test case.  
[----------] Global test environment set-up.  
[----------] 1 test from TestReadConfiguration   
[ RUN      ] TestReadConfiguration.data_set  
[1]    21707 segmentation fault (core dumped)  test/RunUnitTests --gtest_filter='TestReadConfiguration.data_set'  

3° Inspect the code using lldb with the generated /cores/core.21707 dump:

➜  build_deformetrica lldb  test/RunUnitTests  -c /cores/core.21707 -- --gtest_filter='TestReadConfiguration.data_set'  
(lldb) target create "test/RunUnitTests" --core "/cores/core.21707"  
warning: (x86_64) /cores/core.21707 load command 130 LC_SEGMENT_64 has a fileoff + filesize (0x2892e000) that extends beyond the end of the file (0x2892d000), the segment will be truncated to match  
warning: (x86_64) /cores/core.21707 load command 131 LC_SEGMENT_64 has a fileoff (0x2892e000) that extends beyond the end of the file (0x2892d000), ignoring this section  
ruCore file '/cores/core.21707' (x86_64) was loaded.  
(lldb) settings set -- target.run-args "--gtest_filter=TestReadConfiguration.data_set"  

4° Show the stack backtraces for all threads using bt all command:

(lldb) bt all
* thread #1: tid = 0x0000, 0x000000010e9228b4 RunUnitTests`def::io::XmlDictionary::add_tag(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) + 548, stop reason = signal SIGSTOP
  * frame #0: 0x000000010e9228b4 RunUnitTests`def::io::XmlDictionary::add_tag(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) + 548
    frame #1: 0x000000010e91fac2 RunUnitTests`def::test::TestReadConfiguration_data_set_Test::TestBody() + 5394
    frame #2: 0x000000010e93e73a RunUnitTests`void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) + 154
    frame #3: 0x000000010e93e62f RunUnitTests`testing::Test::Run() + 255
    frame #4: 0x000000010e93f5ae RunUnitTests`testing::TestInfo::Run() + 366
    frame #5: 0x000000010e93fdc3 RunUnitTests`testing::TestCase::Run() + 419
    frame #6: 0x000000010e94778b RunUnitTests`testing::internal::UnitTestImpl::RunAllTests() + 939
    frame #7: 0x000000010e9472d3 RunUnitTests`bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) + 147
    frame #8: 0x000000010e9471ee RunUnitTests`testing::UnitTest::Run() + 174
    frame #9: 0x000000010e87da41 RunUnitTests`main + 33
    frame #10: 0x00007fff9990e5ad libdyld.dylib`start + 1
(lldb) q

5° Inspecting the def::io::XmlDictionary::add_tag method I've sorted out that the code used the move semantic as argument for a shared_pointer that caused the problem for the XCode 8 compiler.

//Do Not Work using X Code: 
//tag_[tag_id] = std::make_shared<XmlMap>(std::move(xml_map));
//Use Copy Constructor instead:
tag_[tag_id] = std::make_shared<XmlMap>(xml_map);

So, after changing it with copy constructor, recompiling and testing, all was fixed.

End of the story.