URL class SigSegv


#1

This happens when i try to use the URL class and read the stream (either as XML or String). Don’t really know what i’m doing wrong…
The whole thing is a one-liner

return (URL (updateUrl).withParameter("revision", String(ctrlrRevision)).withParameter("osname", getOsIdea()).withParameter("osbits", getOsBitIdea()).readEntireXmlStream());

but it fails

Program received signal SIGSEGV, Segmentation fault.
0x0807c6a7 in juce::Atomic<int>::operator++ (this=0x829e4e3) at /home/atom/devel/juce/juce_amalgamated.h:2412
2412		return (Type) __sync_add_and_fetch (&value, 1);
(gdb) backtrace
#0  0x0807c6a7 in juce::Atomic<int>::operator++ (this=0x829e4e3) at /home/atom/devel/juce/juce_amalgamated.h:2412
#1  0x0831bce5 in juce::StringHolder::retain (text=...) at /home/atom/devel/juce/amalgamation/../src/text/juce_String.cpp:156
#2  0x082b8129 in String (this=0x8abc050, other=...) at /home/atom/devel/juce/amalgamation/../src/text/juce_String.cpp:243
#3  0x083236d3 in juce::Array<juce::String, juce::DummyCriticalSection>::add (this=0xbfffe384, newElement=...)
    at /home/atom/devel/juce/amalgamation/../src/core/../io/files/../../containers/juce_Array.h:337
#4  0x082bd9fc in juce::StringArray::add (this=0xbfffe384, newString=...) at /home/atom/devel/juce/amalgamation/../src/text/juce_StringArray.cpp:134
#5  0x082bef06 in juce::StringPairArray::set (this=0xbfffe370, key=..., value=...) at /home/atom/devel/juce/amalgamation/../src/text/juce_StringPairArray.cpp:97
#6  0x082b1b27 in juce::URL::withParameter (this=0xbfffe3f8, parameterName=..., parameterValue=...) at /home/atom/devel/juce/amalgamation/../src/io/network/juce_URL.cpp:344
#7  0x0816afec in CtrlrAbout::getUpdateData (updateUrl=...) at ../../Source/UIComponents/CtrlrAbout.cpp:247
#8  0x0816adc6 in CtrlrAbout::buttonClicked (this=0x8ac3488, buttonThatWasClicked=0x8ad9230) at ../../Source/UIComponents/CtrlrAbout.cpp:202
#9  0x08515de5 in void juce::ListenerList<juce::Button::Listener, juce::Array<juce::Button::Listener*, juce::DummyCriticalSection> >::callChecked<juce::Component::BailOutChecker, juce::Button*>(juce::Component::BailOutChecker const&, void (juce::Button::Listener::*)(juce::Button*), juce::TypeHelpers::ParameterType<juce::Button*>::type) ()
#10 0x08452ca3 in juce::Button::sendClickMessage (this=0x8ad9230, modifiers=...) at /home/atom/devel/juce/amalgamation/../src/gui/components/buttons/juce_Button.cpp:384
#11 0x08452a6c in juce::Button::internalClickCallback (this=0x8ad9230, modifiers=...) at /home/atom/devel/juce/amalgamation/../src/gui/components/buttons/juce_Button.cpp:325
#12 0x08452f8f in juce::Button::mouseUp (this=0x8ad9230, e=...) at /home/atom/devel/juce/amalgamation/../src/gui/components/buttons/juce_Button.cpp:440
#13 0x0844bf1d in juce::Component::internalMouseUp (this=0x8ad9230, source=..., relativePos=..., time=..., oldModifiers=...)

#2

Ah…

It’s seg-faulting because it’s trying to do an atomic operation on some unaligned memory - notice that the Atomic object’s address is 0x829e4e3.

That must be because ‘new’ isn’t producing an aligned block, but I’m a little surprised by that! On other platforms it certainly seems to always be 4-byte aligned. How about trying this, in juce_String.cpp:

static const CharPointerType createUninitialisedBytes (const size_t numBytes) { StringHolder* const s = reinterpret_cast <StringHolder*> (new int [(sizeof (StringHolder) - sizeof (CharType) + sizeof (int) - 1 + numBytes) / sizeof (int)]);

…could be that because it was doing a ‘new char […’, gcc was assuming that it’d be ok to return a non-aligned block from some kind of specialised small-block pool or something. Hopefully asking it for an array of ints will make it realise that it should align the result.


#3

didn’t help, i changed

static const CharPointerType createUninitialisedBytes (const size_t numBytes)
    {
        // StringHolder* const s = reinterpret_cast <StringHolder*> (new char [sizeof (StringHolder) - sizeof (CharType) + numBytes]);
        StringHolder* const s = reinterpret_cast <StringHolder*> (new int [(sizeof (StringHolder) - sizeof (CharType) + sizeof (int) - 1 + numBytes) / sizeof (int)]);
        s->refCount.value = 0;
        s->allocatedNumBytes = numBytes;
        return CharPointerType (s->text);
    }

and the backtrace is (you can see the line numbers moved +1 so the change is there:

Program received signal SIGSEGV, Segmentation fault.
0x0807c6a7 in juce::Atomic<int>::operator++ (this=0x829e4e3) at /home/atom/devel/juce/juce_amalgamated.h:2412
2412		return (Type) __sync_add_and_fetch (&value, 1);
(gdb) backtrace
#0  0x0807c6a7 in juce::Atomic<int>::operator++ (this=0x829e4e3) at /home/atom/devel/juce/juce_amalgamated.h:2412
#1  0x0831bceb in juce::StringHolder::retain (text=...) at /home/atom/devel/juce/amalgamation/../src/text/juce_String.cpp:157
#2  0x082b8129 in String (this=0x8ab2730, other=...) at /home/atom/devel/juce/amalgamation/../src/text/juce_String.cpp:244
#3  0x083236d9 in juce::Array<juce::String, juce::DummyCriticalSection>::add (this=0xbfffef64, newElement=...)
    at /home/atom/devel/juce/amalgamation/../src/core/../io/files/../../containers/juce_Array.h:337
#4  0x082bd9fc in juce::StringArray::add (this=0xbfffef64, newString=...) at /home/atom/devel/juce/amalgamation/../src/text/juce_StringArray.cpp:134
#5  0x082bef06 in juce::StringPairArray::set (this=0xbfffef50, key=..., value=...) at /home/atom/devel/juce/amalgamation/../src/text/juce_StringPairArray.cpp:97
#6  0x082b1b27 in juce::URL::withParameter (this=0xbfffefd8, parameterName=..., parameterValue=...) at /home/atom/devel/juce/amalgamation/../src/io/network/juce_URL.cpp:344
#7  0x0816afec in CtrlrAbout::getUpdateData (updateUrl=...) at ../../Source/UIComponents/CtrlrAbout.cpp:247
#8  0x0820b01e in CtrlrMenu::timerCallback (this=0x8a9f9b8) at ../../Source/UIComponents/CtrlrMenu.cpp:502
#9  0x083bebf6 in juce::InternalTimerThread::callTimers (this=0x8a7b2d0) at /home/atom/devel/juce/amalgamation/../src/events/juce_Timer.cpp:138
#10 0x083bed1b in juce::InternalTimerThread::handleMessage (this=0x8a7b2d0) at /home/atom/devel/juce/amalgamation/../src/events/juce_Timer.cpp:154
#11 0x0837313b in juce::MessageManager::deliverMessage (this=0x8a1db40, message=0x8a7b650) at /home/atom/devel/juce/amalgamation/../src/events/juce_MessageManager.cpp:117
#12 0x085b9440 in juce::InternalMessageQueue::dispatchNextInternalMessage (this=0x8a1dba0) at /home/atom/devel/juce/amalgamation/../src/native/linux/juce_linux_Messaging.cpp:231
#13 0x085b8ee5 in juce::InternalMessageQueue::dispatchNextEvent (this=0x8a1dba0) at /home/atom/devel/juce/amalgamation/../src/native/linux/juce_linux_Messaging.cpp:101
#14 0x085aee21 in juce::MessageManager::dispatchNextMessageOnSystemQueue (returnIfNoPendingMessages=false) at /home/atom/devel/juce/amalgamation/../src/native/linux/juce_linux_Messaging.cpp:456
#15 0x08373389 in juce::MessageManager::runDispatchLoopUntil (this=0x8a1db40, millisecondsToRunFor=-1) at /home/atom/devel/juce/amalgamation/../src/events/juce_MessageManager.cpp:149
#16 0x0837326e in juce::MessageManager::runDispatchLoop (this=0x8a1db40) at /home/atom/devel/juce/amalgamation/../src/events/juce_MessageManager.cpp:129
#17 0x0833824f in juce::JUCEApplication::main (commandLine=...) at /home/atom/devel/juce/amalgamation/../src/application/juce_Application.cpp:230
#18 0x08338428 in juce::JUCEApplication::main (argc=1, argv=0xbffff4b4) at /home/atom/devel/juce/amalgamation/../src/application/juce_Application.cpp:264
#19 0x0808bd74 in main (argc=1, argv=0xbffff4b4) at ../../Source/Application/StandaloneWrapper/CtrlrStandaloneApplication.cpp:38

i did a complete clean and re-built the whole thing. Weird thing is the Introjucer works with it’s update feature, i add some GET paramters to the URL and that might be different (the StringPairArray seems to be involved here so i’m guessing that’s where the parameters are kept)


#4

Wow, so the allocator is returning un-aligned arrays of ints…?? That’s a pretty poor job that the compiler’s doing, as it could have a huge performance hit, because on some CPUs, accessing each int will burn extra cycles when they’re not aligned.

Ok… try it with malloc:

static const CharPointerType createUninitialisedBytes (const size_t numBytes) { StringHolder* const s = reinterpret_cast <StringHolder*> (juce_malloc (sizeof (StringHolder) - sizeof (CharType) + numBytes)); jassert ((((pointer_sized_int) s) & 3) == 0);

and you’ll also need:

static inline void release (StringHolder* const b) throw() { if (--(b->refCount) == -1 && b != &empty) juce_free (b);

I added an assertion in there too, so any unaligned addresses should get caught immediately…


#5

still nothing, same error.


#6

no, no, no… I think I may have been getting side-tracked here…

Are you sure you’re not just doing something silly? In your original code:

…are you sure the return values of those “getOSBitIdea” things are valid? They’re not returning dangling references are they? Try it with some hard-coded strings in there.


#7

well yes as usual you are correct, it was my fault (a missed a #ifdef and the compiler did not warn me about not returning anything from a function). I’m sorry for bugging you with that.

There is something about URL::launchInDefaultBrowser() when i call it the browser opens but my application catches a SIGSTOP and i can’t do anything about it, i tried
debugging it but this does not happen under GDB only when launched without the debugger:

atom@ubuntu-x32:~/devel/ctrlr/Builds/Linux$ ../../Bin/Debug/Ctrlr_Standalon
ERROR: X returned BadMatch (invalid parameter attributes) for operation X_ConfigureWindow
ERROR: X returned BadMatch (invalid parameter attributes) for operation X_ConfigureWindow
ERROR: X returned BadMatch (invalid parameter attributes) for operation X_ConfigureWindow
ERROR: X returned BadMatch (invalid parameter attributes) for operation X_ConfigureWindow
ERROR: X returned BadMatch (invalid parameter attributes) for operation X_ConfigureWindow
ERROR: X returned BadMatch (invalid parameter attributes) for operation X_ConfigureWindow
ERROR: X returned BadMatch (invalid parameter attributes) for operation X_ConfigureWindow

[1]+  Stopped                 ../../Bin/Debug/Ctrlr_Standalone

i tried doing “fg” but that does not seem to help, there is a “defunct” sh process that’s a child of my process and the app is not responding

1544  1548  1548  1548 pts/0     3340 Ss    1000   0:00  \_ bash
 1548  3340  3340  1548 pts/0     3340 tl+   1000   0:29  |   \_ ../../Bin/Debug/Ctrlr_Standalone
 3340  3342  3342  3342 ?           -1 Zs    1000   0:00  |       \_ [sh] <defunct>

#8

sorry, not at all sure what’s going on there… Maybe it’s the browser process that’s blowing up?


#9

hard to say, can’t really debug it so i don’t know where the signal is comming from, it’s not a big thing i’ll deal with it.

once again sorry for the stupid bug report, i’ll try to triple check everything now.