Solved the issue the brute force way. Came up with a trivial application using the existing CMake files. Once it crashed I backed out libraries until it did not. Turns out it was gperftools and tcmalloc.
Post
Replies
Boosts
Views
Activity
Even though the log4cxx unit tests pass I decided to add some debug to the function which is now crashing.
The modified code breaks each step down.
bool Class::registerClass(const Class& newClass)
{
log4cxx::LogString new_class_name = newClass.getName();
log4cxx::LogString new_class_name_lower = StringHelper::toLowerCase(new_class_name);
log4cxx::helpers::Class::ClassMap& class_map = getRegistry();
class_map[new_class_name_lower] = &newClass;
//getRegistry()[StringHelper::toLowerCase(newClass.getName())] = &newClass;
return true;
}
The back trace seems to indicate we crash when exiting. All the debug looks fine, the map was populated 10 times and we crash when adding the 11th element.
(lldb) bt
* thread #1, stop reason = signal SIGSTOP
* frame #0: 0x0000000000000000
frame #1: 0x0000000105370901 liblog4cxx.12.dylib`log4cxx::helpers::Class::registerClass(newClass=0x00000001054ff320) at class.cpp:164:1
frame #2: 0x000000010537478b liblog4cxx.12.dylib`log4cxx::helpers::ClassRegistration::ClassRegistration(this=0x00000001054ff330, accessor=(liblog4cxx.12.dylib`log4cxx::pattern::ClassNamePatternConverter::getStaticClass() at classnamepatternconverter.cpp:32))()) at classregistration.cpp:26:2
frame #3: 0x00000001053747bd liblog4cxx.12.dylib`log4cxx::helpers::ClassRegistration::ClassRegistration(this=0x00000001054ff330, accessor=(liblog4cxx.12.dylib`log4cxx::pattern::ClassNamePatternConverter::getStaticClass() at classnamepatternconverter.cpp:32))()) at classregistration.cpp:25:1
frame #4: 0x0000000105372c7d liblog4cxx.12.dylib`log4cxx::pattern::ClassNamePatternConverter::registerClass() at classnamepatternconverter.cpp:32:1
frame #5: 0x0000000105374749 liblog4cxx.12.dylib`::__cxx_global_var_init() at classnamepatternconverter.cpp:32:1
frame #6: 0x0000000105374769 liblog4cxx.12.dylib`_GLOBAL__sub_I_classnamepatternconverter.cpp at classnamepatternconverter.cpp:0
frame #7: 0x000000010b823b49 dyld`invocation function for block in dyld4::Loader::findAndRunAllInitializers(dyld4::RuntimeState&) const + 182
frame #8: 0x000000010b84a29b dyld`invocation function for block in dyld3::MachOAnalyzer::forEachInitializer(Diagnostics&, dyld3::MachOAnalyzer::VMAddrConverter const&, void (unsigned int) block_pointer, void const*) const + 242
frame #9: 0x000000010b841893 dyld`invocation function for block in dyld3::MachOFile::forEachSection(void (dyld3::MachOFile::SectionInfo const&, bool, bool&) block_pointer) const + 566
frame #10: 0x000000010b810d91 dyld`dyld3::MachOFile::forEachLoadCommand(Diagnostics&, void (load_command const*, bool&) block_pointer) const + 129
frame #11: 0x000000010b84161b dyld`dyld3::MachOFile::forEachSection(void (dyld3::MachOFile::SectionInfo const&, bool, bool&) block_pointer) const + 179
frame #12: 0x000000010b849df2 dyld`dyld3::MachOAnalyzer::forEachInitializer(Diagnostics&, dyld3::MachOAnalyzer::VMAddrConverter const&, void (unsigned int) block_pointer, void const*) const + 466
frame #13: 0x000000010b823a7c dyld`dyld4::Loader::findAndRunAllInitializers(dyld4::RuntimeState&) const + 144
frame #14: 0x000000010b823c08 dyld`dyld4::Loader::runInitializersBottomUp(dyld4::RuntimeState&, dyld3::Array<dyld4::Loader const*>&) const + 178
frame #15: 0x000000010b823beb dyld`dyld4::Loader::runInitializersBottomUp(dyld4::RuntimeState&, dyld3::Array<dyld4::Loader const*>&) const + 149
frame #16: 0x000000010b823cac dyld`dyld4::Loader::runInitializersBottomUpPlusUpwardLinks(dyld4::RuntimeState&) const + 108
frame #17: 0x000000010b83732e dyld`dyld4::APIs::runAllInitializersForMain() + 222
frame #18: 0x000000010b815358 dyld`dyld4::prepare(dyld4::APIs&, dyld3::MachOAnalyzer const*) + 3438
frame #19: 0x000000010b8144b4 dyld`start + 388
(lldb) f 1
frame #1: 0x0000000105370901 liblog4cxx.12.dylib`log4cxx::helpers::Class::registerClass(newClass=0x00000001054ff320) at class.cpp:164:1
161 class_map[new_class_name_lower] = &newClass;
162 //getRegistry()[StringHelper::toLowerCase(newClass.getName())] = &newClass;
163 return true;
-> 164 }
165
166 void Class::registerClasses()
167 {
(lldb) frame variable
(log4cxx::pattern::ClassNamePatternConverter::ClazzClassNamePatternConverter &) newClass = 0x00000001054ff320 {}
(log4cxx::LogString) new_class_name = "ClassNamePatternConverter"
(log4cxx::LogString) new_class_name_lower = "classnamepatternconverter"
(log4cxx::helpers::Class::ClassMap &) class_map = size=11: {
[0] = (first = "action", second = 0x00000001054ff0e0)
[1] = (first = "andfilter", second = 0x00000001054ff100)
[2] = (first = "appenderattachableimpl", second = 0x00000001054ff120)
[3] = (first = "appenderskeleton", second = 0x00000001054ff140)
[4] = (first = "asyncappender", second = 0x00000001054ff1d8)
[5] = (first = "bufferedwriter", second = 0x00000001054ff218)
[6] = (first = "bytearrayinputstream", second = 0x00000001054ff238)
[7] = (first = "bytearrayoutputstream", second = 0x00000001054ff258)
[8] = (first = "charsetdecoder", second = 0x00000001054ff278)
[9] = (first = "charsetencoder", second = 0x00000001054ff2c8)
[10] = (first = "classnamepatternconverter", second = 0x00000001054ff320)
}
Sure, here's the back trace . . .
(lldb) bt
* thread #1, stop reason = signal SIGSTOP
* frame #0: 0x0000000000000000
frame #1: 0x000000010b98d12d liblog4cxx.12.dylib`log4cxx::helpers::Class::registerClass(newClass=0x000000010bb1c320) at class.cpp:158:2
frame #2: 0x000000010b99172b liblog4cxx.12.dylib`log4cxx::helpers::ClassRegistration::ClassRegistration(this=0x000000010bb1c330, accessor=(liblog4cxx.12.dylib`log4cxx::pattern::ClassNamePatternConverter::getStaticClass() at classnamepatternconverter.cpp:32))()) at classregistration.cpp:26:2
frame #3: 0x000000010b99175d liblog4cxx.12.dylib`log4cxx::helpers::ClassRegistration::ClassRegistration(this=0x000000010bb1c330, accessor=(liblog4cxx.12.dylib`log4cxx::pattern::ClassNamePatternConverter::getStaticClass() at classnamepatternconverter.cpp:32))()) at classregistration.cpp:25:1
frame #4: 0x000000010b98fc1d liblog4cxx.12.dylib`log4cxx::pattern::ClassNamePatternConverter::registerClass() at classnamepatternconverter.cpp:32:1
frame #5: 0x000000010b9916e9 liblog4cxx.12.dylib`::__cxx_global_var_init() at classnamepatternconverter.cpp:32:1
frame #6: 0x000000010b991709 liblog4cxx.12.dylib`_GLOBAL__sub_I_classnamepatternconverter.cpp at classnamepatternconverter.cpp:0
frame #7: 0x0000000119085b49 dyld`invocation function for block in dyld4::Loader::findAndRunAllInitializers(dyld4::RuntimeState&) const + 182
frame #8: 0x00000001190ac29b dyld`invocation function for block in dyld3::MachOAnalyzer::forEachInitializer(Diagnostics&, dyld3::MachOAnalyzer::VMAddrConverter const&, void (unsigned int) block_pointer, void const*) const + 242
frame #9: 0x00000001190a3893 dyld`invocation function for block in dyld3::MachOFile::forEachSection(void (dyld3::MachOFile::SectionInfo const&, bool, bool&) block_pointer) const + 566
frame #10: 0x0000000119072d91 dyld`dyld3::MachOFile::forEachLoadCommand(Diagnostics&, void (load_command const*, bool&) block_pointer) const + 129
frame #11: 0x00000001190a361b dyld`dyld3::MachOFile::forEachSection(void (dyld3::MachOFile::SectionInfo const&, bool, bool&) block_pointer) const + 179
frame #12: 0x00000001190abdf2 dyld`dyld3::MachOAnalyzer::forEachInitializer(Diagnostics&, dyld3::MachOAnalyzer::VMAddrConverter const&, void (unsigned int) block_pointer, void const*) const + 466
frame #13: 0x0000000119085a7c dyld`dyld4::Loader::findAndRunAllInitializers(dyld4::RuntimeState&) const + 144
frame #14: 0x0000000119085c08 dyld`dyld4::Loader::runInitializersBottomUp(dyld4::RuntimeState&, dyld3::Array<dyld4::Loader const*>&) const + 178
frame #15: 0x0000000119085beb dyld`dyld4::Loader::runInitializersBottomUp(dyld4::RuntimeState&, dyld3::Array<dyld4::Loader const*>&) const + 149
frame #16: 0x0000000119085cac dyld`dyld4::Loader::runInitializersBottomUpPlusUpwardLinks(dyld4::RuntimeState&) const + 108
frame #17: 0x000000011909932e dyld`dyld4::APIs::runAllInitializersForMain() + 222
frame #18: 0x0000000119077358 dyld`dyld4::prepare(dyld4::APIs&, dyld3::MachOAnalyzer const*) + 3438
frame #19: 0x00000001190764b4 dyld`start + 388
Here's the end of our CMake file with changes (with tweaks based on other similar issues I found) . . .
target_link_libraries (mantis log4cxx)
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
find_library(FoundationLib Foundation)
find_library(CoreServicesLib CoreServices)
find_library(CoreFoundationLib CoreFoundation)
find_library(objcLib objc)
message("LIB: ${FoundationLib}")
message("LIB: ${CoreServicesLib}")
message("LIB: ${CoreFoundationLib}")
message("LIB: ${objcLib}")
target_link_libraries (mantis stdc++ "-framework Foundation")
target_link_libraries (mantis stdc++ "-framework CoreServices")
# target_link_libraries (mantis stdc++ "-framework CoreFoundation")
# target_link_libraries (mantis stdc++ objc)
endif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
if (GPERF_TOOLS MATCHES "ON")
target_link_libraries (mantis ${PROFILER_LIBRARY})
target_link_libraries (mantis ${TMALLOC_LIBRARY})
endif (GPERF_TOOLS MATCHES "ON")
CrashReport.txt
I suspect the issue is related to the framework entries in our CMakeLists.txt file. I was originally seeing some log4cxx initialization items in the back trace which also crashed due to jump to null pointer. When I moved it to the end of the list the crash only showed the boot loader items before the jump to 0. If I move the log4cxx entry just ahead of the framework entries the back trace shows the initialization calls again. Not sure if there is a recommended way of adding these frameworks.
target_link_libraries (mantis log4cxx)
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
target_link_libraries (mantis
"-framework Foundation"
"-framework CoreServices")
endif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
if (GPERF_TOOLS MATCHES "ON")
target_link_libraries (mantis ${PROFILER_LIBRARY})
target_link_libraries (mantis ${TMALLOC_LIBRARY})
endif (GPERF_TOOLS MATCHES "ON")
Thanks Quinn, it is a command line application (a threaded service) which requires some arguments. The minimal argument (--version) also results in a crash. Attached a crash report from such a call (could not attach .ips file directly so copied console to txt file and attached).
CrashReport.txt
int main(int argc, char* argv[]) {
IGNORE_WARNINGS_ASIO;
if (2 == argc && 0 == strcmp("--version", argv[1])) {
printVersion();
return 0;
} else if (3 != argc) {
printUsage();
return 1;
}