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.