Strange crash when creating an instance of LocalisedStrings


#1

My app crashes sometimes during startup while creating an instance of LocalisedStrings:


juce::String lang = "en";
juce::String localizedStringsName = "strings-en.txt";
juce::String systemLang = juce::SystemStats::getDisplayLanguage();
if(systemLang.startsWithIgnoreCase("de"))
{
    lang = "de";
    localizedStringsName = "strings-de.txt";
}
juce::File localizedStringsFile = sc::Resources::ResourcePathFromName(localizedStringsName);
juce::MemoryBlock localizedStringsMemory;
if(localizedStringsFile.loadFileAsData(localizedStringsMemory))
{
    localizedStringsContent = juce::String::fromUTF8( (const char *) localizedStringsMemory.getData() );
    juce::LocalisedStrings *currentMappings = new juce::LocalisedStrings(localizedStringsContent, true);
    juce::LocalisedStrings::setCurrentMappings(currentMappings);
}

The crash happens when assigning the currentMappings variable. This is at the very start, there is only the message thread. The strange thing is it crashes randomly, maybe one out of 20 times. Xcode reports:

malloc: *** error for object 0x103024008: incorrect checksum for freed object - object was probably modified after being freed.

*** set a breakpoint in malloc_error_break to debug

Here is the stack track:

Thread 1 Juce Message Thread, Queue : com.apple.main-thread
#0    0x00007fff8db14bd4 in malloc_error_break ()
#1    0x00007fff8db0e5db in szone_error ()
#2    0x00007fff8db14708 in small_malloc_from_free_list ()
#3    0x00007fff8db137c6 in szone_malloc_should_clear ()
#4    0x00007fff8db0a0cc in szone_realloc ()
#5    0x00007fff8db15c71 in malloc_zone_realloc ()
#6    0x00007fff8db163a7 in realloc ()
#7    0x000000010087253e in juce::HeapBlock<juce::String, false>::realloc(unsigned long, unsigned long) at /Users/patrick/Documents/development/sw/JUCE/modules/juce_core/memory/juce_HeapBlock.h:258
#8    0x00000001008724b7 in juce::ArrayAllocationBase<juce::String, juce::DummyCriticalSection>::setAllocatedSize(int) at /Users/patrick/Documents/development/sw/JUCE/modules/juce_core/containers/juce_ArrayAllocationBase.h:89
#9    0x00000001008725f8 in juce::ArrayAllocationBase<juce::String, juce::DummyCriticalSection>::ensureAllocatedSize(int) at /Users/patrick/Documents/development/sw/JUCE/modules/juce_core/containers/juce_ArrayAllocationBase.h:108
#10    0x000000010085ea63 in juce::Array<juce::String, juce::DummyCriticalSection, 0>::add(juce::String const&) at /Users/patrick/Documents/development/sw/JUCE/modules/juce_core/containers/juce_Array.h:389
#11    0x0000000100822b7d in juce::StringArray::add(juce::String const&) at /Users/patrick/Documents/development/sw/JUCE/modules/juce_core/text/juce_StringArray.cpp:133
#12    0x00000001008031e8 in juce::StringPairArray::set(juce::String const&, juce::String const&) at /Users/patrick/Documents/development/sw/JUCE/modules/juce_core/text/juce_StringPairArray.cpp:96
#13    0x000000010082994c in juce::LocalisedStrings::loadFromText(juce::String const&, bool) at /Users/patrick/Documents/development/sw/JUCE/modules/juce_core/text/juce_LocalisedStrings.cpp:136
#14    0x00000001008296d1 in juce::LocalisedStrings::LocalisedStrings(juce::String const&, bool) at /Users/patrick/Documents/development/sw/JUCE/modules/juce_core/text/juce_LocalisedStrings.cpp:31
#15    0x000000010082961c in juce::LocalisedStrings::LocalisedStrings(juce::String const&, bool) at /Users/patrick/Documents/development/sw/JUCE/modules/juce_core/text/juce_LocalisedStrings.cpp:32
#16    0x0000000100002df2 in SonicWebApp::initialise(juce::String const&) at /Users/patrick/Documents/development/sw/trunk/SonicWebJUCE/Shared.cpp:192
#17    0x00000001008c5b25 in juce::JUCEApplicationBase::initialiseApp() at /Users/patrick/Documents/development/sw/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:256
#18    0x0000000100a948a5 in juce::JUCEApplication::initialiseApp() at /Users/patrick/Documents/development/sw/JUCE/modules/juce_gui_basics/application/juce_Application.cpp:88
#19    0x00000001008c589e in juce::JUCEApplicationBase::main() at /Users/patrick/Documents/development/sw/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:229
#20    0x00000001008c56e2 in juce::JUCEApplicationBase::main(int, char const**) at /Users/patrick/Documents/development/sw/JUCE/modules/juce_events/messages/juce_ApplicationBase.cpp:213
#21    0x0000000100002143 in main at /Users/patrick/Documents/development/sw/trunk/SonicWebJUCE/Shared.cpp:844
#22    0x0000000100002024 in start ()

It seems the crash happens in the std::realloc call, when trying to freeing the  data member:

void realloc (const size_t newNumElements, const size_t elementSize = sizeof (ElementType))
{
    data = static_cast <ElementType*> (data == nullptr ? std::malloc (newNumElements * elementSize)
                                                       : std::realloc (data, newNumElements * elementSize));
    throwOnAllocationFailure();
}

I really have no idea what I am doing wrong here. Any help would be very much appreciated.


#2

Can't see any obvious problems in that snippet, but memory errors like that tend to indicate that something has corrupted memory before the place where it actually blows up - the errors just get detected when a subsequent heap operation does some sanity-checking. So it'd be worth looking at whatever code has been run just before this happens..


#3

Hi p4tr3ck, do you know about malloc_history?

Its awesome for seeing what allocated and freed an address.  Basically you set MallocStackLogging to 1 as an environment variable, set a break point on malloc_error_break, then in the terminal(when you break)

 

malloc_history YourProcessName 0x103024008 (or whatever the reported address is)

Scroll down, down, down, to the last entries of ALLOC/FREE, and this will tell you what/who is responsible.


#4

Thanks for your suggestions justin! There is not much code before the snippet. The crash happens very early.

But with your suggestion about malloc_history I found and enabled a few memory debugging aids directly in Xcode and try to reproduce the problem now.

In Xcode 5 these debugging options are part of the scheme. On the diagnostics tab of a scheme you can enable scribble, guard edges, guard malloc and zombie objects: https://developer.apple.com/library/mac/documentation/performance/Conceptual/ManagingMemory/Articles/MallocDebug.html

Hopefully that'll help tracking down the problem.


#5

p4tr3ck THANK YOU!!!! Guard malloc is AWESOME; I found my bug in litterally 5 seconds. Had been looking for 3 days prior to that!


#6

I know this is an old thread, but just wanted to say thanks too ! Guard malloc saved me a lot of time, I enabled it and found the culprit immediately.