Strange endless loop in release mode


#1

In my machine at work, starting the application in release mode hangs before doing anything interesting:

template <typename Type>
inline Type Atomic<Type>::exchange (const Type newValue) throw()
{
  #if JUCE_ATOMICS_ANDROID
    return castFrom32Bit (__atomic_swap (castTo32Bit (newValue), (volatile int*) &value));
  #elif JUCE_ATOMICS_MAC || JUCE_ATOMICS_GCC
    Type currentVal = value;
stuck here >>>    while (! compareAndSetBool (newValue, currentVal)) { currentVal = value; }
    return currentVal;
  #elif JUCE_ATOMICS_WINDOWS
    return sizeof (Type) == 4 ? castFrom32Bit ((int32) juce_InterlockedExchange ((volatile long*) &value, (long) castTo32Bit (newValue)))
                              : castFrom64Bit ((int64) juce_InterlockedExchange64 ((volatile __int64*) &value, (__int64) castTo64Bit (newValue)));
  #endif
}
0	exchange	juce_Atomic.h	267	0x80cfe3b	
1	atomicSwap	juce_CharPointer_UTF8.h	565	0x80cfe3b	
2	juce::String::operator=	juce_String.cpp	254	0x80cfe3b	
3	juce::XmlDocument::getDocumentElement	juce_XmlDocument.cpp	120	0x8156587	
4	juce::XmlDocument::parse	juce_XmlDocument.cpp	57	0x81568fe	
5	juce::FreeTypeInterface::FreeTypeInterface()		0	0x8446eb2	
6	getInstance	juce_linux_Fonts.cpp	451	0x84300ac	
7	linux_getDefaultSansSerifFontName	juce_linux_Fonts.cpp	543	0x84300ac	
8	juce::Font::getPlatformDefaultFontNames	juce_linux_Fonts.cpp	567	0x84300ac	
9	juce::LookAndFeel::LookAndFeel	juce_LookAndFeel.cpp	304	0x832f050	
10	juce::LookAndFeel::setDefaultLookAndFeel	juce_LookAndFeel.cpp	368	0x834b77a	
11	juce::initialiseJuce_GUI	juce_Initialisation.cpp	121	0x80e3522	
12	ScopedJuceInitialiser_GUI	juce_Initialisation.h	122	0x81ec82d	
13	juce::JUCEApplication::main	juce_Application.cpp	217	0x81ec82d	
14	juce::JUCEApplication::main	juce_Application.cpp	264	0x81ecac5	
15	main	Application.cpp	142	0x804f37c	

#2

That’s really peculiar…! Is there anything strange about the target machine? It looks like the gcc built-in __sync_bool_compare_and_swap function would have to fail for it to get stuck in a loop there…?


#3

Nothing particular, the machine works quite good nevertheless.

gcc version is 4.3.3, glibc is 2.11.2, probably i should try to upgrade both ?


#4

No, gcc 4.3 should be fine. Any idea what the two values are that it’s trying to exchange?


#5

It’s trying to make a string out of this:

XmlElement* XmlDocument::getDocumentElement (const bool onlyReadOuterDocumentElement)
{
    String textToParse (originalText);

    if (textToParse.isEmpty() && inputSource != 0)
    {
        ScopedPointer <InputStream> in (inputSource->createInputStream());

        if (in != 0)
        {
            MemoryOutputStream data;
            data.writeFromInputStream (*in, onlyReadOuterDocumentElement ? 8192 : -1);
>>>            textToParse = data.toString();

With memory block data as follows:

<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<!-- /etc/fonts/fonts.conf file to configure system font access -->
<fontconfig>

<!--
	DO NOT EDIT THIS FILE.
	IT WILL BE REPLACED WHEN FONTCONFIG IS UPDATED.
	LOCAL CHANGES BELONG IN 'local.conf'.

	The intent of this standard configuration file is to be adequate for
	most environments.  If you have a reasonably normal environment and
	have found problems with this configuration, they are probably
	things that others will also want fixed.  Please submit any
	problems to the fontconfig bugzilla system located at fontconfig.org

	Note that the normal 'make install' procedure for fontconfig is to
	replace any existing fonts.conf file with the new version.  Place
	any local customizations in local.conf which this file references.

	Keith Packard
-->

<!-- Font directory list -->

	<dir>/usr/share/fonts</dir>
	<dir>/usr/local/share/fonts</dir>
	<dir>~/.fonts</dir>

<!--
  Accept deprecated 'mono' alias, replacing it with 'monospace'
-->
	<match target="pattern">
		<test qual="any" name="family">
			<string>mono</string>
		</test>
		<edit name="family" mode="assign">
			<string>monospace</string>
		</edit>
	</match>

<!--
  Accept alternate 'sans serif' spelling, replacing it with 'sans-serif'
-->
	<match target="pattern">
		<test qual="any" name="family">
			<string>sans serif</string>
		</test>
		<edit name="family" mode="assign">
			<string>sans-serif</string>
		</edit>
	</match>

<!--
  Accept deprecated 'sans' alias, replacing it with 'sans-serif'
-->
	<match target="pattern">
		<test qual="any" name="family">
			<string>sans</string>
		</test>
		<edit name="family" mode="assign">
			<string>sans-serif</string>
		</edit>
	</match>

<!--
  Load local system customization file
-->
	<include ignore_missing="yes">conf.d</include>

<!-- Font cache directory list -->

	<cachedir>/var/cache/fontconfig</cachedir>
	<cachedir>~/.fontconfig</cachedir>

	<config>
<!--
  These are the default Unicode chars that are expected to be blank
  in fonts.  All other blank chars are assumed to be broken and
  won't appear in the resulting charsets
 -->
		<blank>
			<int>0x0020</int>	<!-- SPACE -->
			<int>0x00A0</int>	<!-- NO-BREAK SPACE -->
			<int>0x00AD</int>	<!-- SOFT HYPHEN -->
			<int>0x034F</int>	<!-- COMBINING GRAPHEME JOINER -->
			<int>0x0600</int>	<!-- ARABIC NUMBER SIGN -->
			<int>0x0601</int>	<!-- ARABIC SIGN SANAH -->
			<int>0x0602</int>	<!-- ARABIC FOOTNOTE MARKER -->
			<int>0x0603</int>	<!-- ARABIC SIGN SAFHA -->
			<int>0x06DD</int>	<!-- ARABIC END OF AYAH -->
			<int>0x070F</int>	<!-- SYRIAC ABBREVIATION MARK -->
			<int>0x115F</int>	<!-- HANGUL CHOSEONG FILLER -->
			<int>0x1160</int>	<!-- HANGUL JUNGSEONG FILLER -->
			<int>0x1680</int>	<!-- OGHAM SPACE MARK -->
			<int>0x17B4</int>	<!-- KHMER VOWEL INHERENT AQ -->
			<int>0x17B5</int>	<!-- KHMER VOWEL INHERENT AA -->
			<int>0x180E</int>	<!-- MONGOLIAN VOWEL SEPARATOR -->
			<int>0x2000</int>	<!-- EN QUAD -->
			<int>0x2001</int>	<!-- EM QUAD -->
			<int>0x2002</int>	<!-- EN SPACE -->
			<int>0x2003</int>	<!-- EM SPACE -->
			<int>0x2004</int>	<!-- THREE-PER-EM SPACE -->
			<int>0x2005</int>	<!-- FOUR-PER-EM SPACE -->
			<int>0x2006</int>	<!-- SIX-PER-EM SPACE -->
			<int>0x2007</int>	<!-- FIGURE SPACE -->
			<int>0x2008</int>	<!-- PUNCTUATION SPACE -->
			<int>0x2009</int>	<!-- THIN SPACE -->
			<int>0x200A</int>	<!-- HAIR SPACE -->
			<int>0x200B</int>	<!-- ZERO WIDTH SPACE -->
			<int>0x200C</int>	<!-- ZERO WIDTH NON-JOINER -->
			<int>0x200D</int>	<!-- ZERO WIDTH JOINER -->
			<int>0x200E</int>	<!-- LEFT-TO-RIGHT MARK -->
			<int>0x200F</int>	<!-- RIGHT-TO-LEFT MARK -->
			<int>0x2028</int>	<!-- LINE SEPARATOR -->
			<int>0x2029</int>	<!-- PARAGRAPH SEPARATOR -->
			<int>0x202A</int>	<!-- LEFT-TO-RIGHT EMBEDDING -->
			<int>0x202B</int>	<!-- RIGHT-TO-LEFT EMBEDDING -->
			<int>0x202C</int>	<!-- POP DIRECTIONAL FORMATTING -->
			<int>0x202D</int>	<!-- LEFT-TO-RIGHT OVERRIDE -->
			<int>0x202E</int>	<!-- RIGHT-TO-LEFT OVERRIDE -->
			<int>0x202F</int>	<!-- NARROW NO-BREAK SPACE -->
			<int>0x205F</int>	<!-- MEDIUM MATHEMATICAL SPACE -->
			<int>0x2060</int>	<!-- WORD JOINER -->
			<int>0x2061</int>	<!-- FUNCTION APPLICATION -->
			<int>0x2062</int>	<!-- INVISIBLE TIMES -->
			<int>0x2063</int>	<!-- INVISIBLE SEPARATOR -->
			<int>0x206A</int>	<!-- INHIBIT SYMMETRIC SWAPPING -->
			<int>0x206B</int>	<!-- ACTIVATE SYMMETRIC SWAPPING -->
			<int>0x206C</int>	<!-- INHIBIT ARABIC FORM SHAPING -->
			<int>0x206D</int>	<!-- ACTIVATE ARABIC FORM SHAPING -->
			<int>0x206E</int>	<!-- NATIONAL DIGIT SHAPES -->
			<int>0x206F</int>	<!-- NOMINAL DIGIT SHAPES -->
			<int>0x2800</int>	<!-- BRAILLE PATTERN BLANK -->
			<int>0x3000</int>	<!-- IDEOGRAPHIC SPACE -->
			<int>0x3164</int>	<!-- HANGUL FILLER -->
			<int>0xFEFF</int>	<!-- ZERO WIDTH NO-BREAK SPACE -->
			<int>0xFFA0</int>	<!-- HALFWIDTH HANGUL FILLER -->
			<int>0xFFF9</int>	<!-- INTERLINEAR ANNOTATION ANCHOR -->
			<int>0xFFFA</int>	<!-- INTERLINEAR ANNOTATION SEPARATOR -->
			<int>0xFFFB</int>	<!-- INTERLINEAR ANNOTATION TERMINATOR -->
		</blank>
<!--
  Rescan configuration every 30 seconds when FcFontSetList is called
 -->
		<rescan>
			<int>30</int>
		</rescan>
	</config>

</fontconfig>

in the assignment, it tries to swap that string with an empty string with *data initialized to ‘\0’


#6

None of that’s really relevant, I just meant the two pointers that were being passed into atomic::exchange method. Not that it matters much - it should work anyway. Very odd, because it’s such a simple operation that there’s not really much to go wrong. I guess that it might be worth updating gcc, just in case it was a compiler bug, I can’t really think of any other suggestions…


#7

…mkay thanx !


#8

Something related, but this time with the same application compiled in release mode as VST plugin.

Program received signal SIGABRT, Aborted.
0xffffe424 in __kernel_vsyscall ()
(gdb) bt
#0  0xffffe424 in __kernel_vsyscall ()
#1  0x4f184b20 in raise () from /lib/libc.so.6
#2  0x4f186368 in abort () from /lib/libc.so.6
#3  0x4f1c0f0d in ?? () from /lib/libc.so.6
#4  0x4f1c6e34 in ?? () from /lib/libc.so.6
#5  0x4f1c86c3 in ?? () from /lib/libc.so.6
#6  0x4f1cb6bd in free () from /lib/libc.so.6
#7  0x4f80da27 in operator delete(void*) () from /usr/lib/gcc/i686-pc-linux-gnu/4.3.3/libstdc++.so.6
#8  0x4f80da73 in operator delete[](void*) () from /usr/lib/gcc/i686-pc-linux-gnu/4.3.3/libstdc++.so.6
#9  0xa37c56f6 in release (this=0xafffe368, __in_chrg=<value optimized out>) at src/juce/../../../../libraries/juce/amalgamation/../src/text/juce_String.cpp:162
#10 release (this=0xafffe368, __in_chrg=<value optimized out>) at src/juce/../../../../libraries/juce/amalgamation/../src/text/juce_String.cpp:167
#11 juce::String::~String (this=0xafffe368, __in_chrg=<value optimized out>) at src/juce/../../../../libraries/juce/amalgamation/../src/text/juce_String.cpp:237
#12 0xa3760097 in SharedMessageThread (audioMaster=0x8195be8 <vstMaster(AEffect*, long, long, long, void*, float)>) at ../../libraries/juce/extras/audio plugins/wrapper/VST/juce_VST_Wrapper.cpp:252
#13 getInstance (audioMaster=0x8195be8 <vstMaster(AEffect*, long, long, long, void*, float)>) at ../../libraries/juce/extras/audio plugins/wrapper/VST/juce_VST_Wrapper.cpp:279
#14 VSTPluginMain (audioMaster=0x8195be8 <vstMaster(AEffect*, long, long, long, void*, float)>) at ../../libraries/juce/extras/audio plugins/wrapper/VST/juce_VST_Wrapper.cpp:1482
#15 0xa376025d in main_plugin (audioMaster=0x8195be8 <vstMaster(AEffect*, long, long, long, void*, float)>) at ../../libraries/juce/extras/audio plugins/wrapper/VST/juce_VST_Wrapper.cpp:1490
...

i have to say, the transition to the new String class is all but painless, and producing very unsatisfactory and different results in every kind of compiler/distro combination i’ve tried my applications.


#9

Really? It’s been rock-solid in every environment that I’ve tried it in… But the thing you’re seeing above doesn’t look like a String problem to me, it’s more like something else going wrong with atomic ops. Is there a way you could try running the atomic ops unit-tests that are defined in juce_Initialisation.cpp ?


#10

The tests passes correctly in standalone (debug) and plugin (debug). But i’m unable to see any unit test output in release (standalone + plugin) cause it freeze:

Program received signal SIGINT, Interrupt.

#0  exchange (this=0x9fabdf8, other=...) at src/juce/../../../../libraries/juce/amalgamation/../src/core/../text/../memory/juce_Atomic.h:267
#1  atomicSwap (this=0x9fabdf8, other=...) at src/juce/../../../../libraries/juce/amalgamation/../src/core/../text/juce_CharPointer_UTF8.h:565
#2  juce::String::operator= (this=0x9fabdf8, other=...) at src/juce/../../../../libraries/juce/amalgamation/../src/text/juce_String.cpp:254
#3  0xa368efec in juce::UnitTestRunner::beginNewTest (this=0xafffe348, test=0xa38ff384, subCategory=...) at src/juce/../../../../libraries/juce/amalgamation/../src/utilities/juce_UnitTest.cpp:145
#4  0xa368f25f in juce::UnitTest::beginTest (this=0xa38ff384, testName=...) at src/juce/../../../../libraries/juce/amalgamation/../src/utilities/juce_UnitTest.cpp:72
#5  0xa3884aeb in AtomicTests::runTest() () from binaries/equalizer/Release/libzzz.so
#6  0xa367bc90 in juce::UnitTest::performTest (this=0xa38ff384, runner_=0xafffe348) at src/juce/../../../../libraries/juce/amalgamation/../src/utilities/juce_UnitTest.cpp:61
#7  0xa36da92f in juce::UnitTestRunner::runTests (this=0xafffe348, tests=..., assertOnFailure_=true) at src/juce/../../../../libraries/juce/amalgamation/../src/utilities/juce_UnitTest.cpp:117
#8  0xa36daa08 in juce::UnitTestRunner::runAllTests (this=0xafffe348, assertOnFailure_=28) at src/juce/../../../../libraries/juce/amalgamation/../src/utilities/juce_UnitTest.cpp:130
#9  0xa387e5a5 in main_plugin (audioMaster=0x8195be8 <vstMaster(AEffect*, long, long, long, void*, float)>) at ../../libraries/juce/extras/audio plugins/wrapper/VST/juce_VST_Wrapper.cpp:1592

Don’t know what to try more, lately i’ve been experiencing a lot of problems in the library that pisses me off, never had so many problems in years of development…

I should try to lower the optimizations in release, and see if anything change (now compiling with -O2)


#11

After compiling with -O1 in release mode i’ve got this, which is even more fun !!

Program received signal SIGSEGV, Segmentation fault.

0x0821e398 in operator= (this=0x8337fd0) at src/juce/../../../../libraries/juce/amalgamation/../src/gui/components/../graphics/effects/../../graphics/contexts/../../../memory/juce_ScopedPointer.h:124
124	            delete oldObject;
(gdb) bt
#0  0x0821e398 in operator= (this=0x8337fd0)
    at src/juce/../../../../libraries/juce/amalgamation/../src/gui/components/../graphics/effects/../../graphics/contexts/../../../memory/juce_ScopedPointer.h:124
#1  juce::DocumentWindow::lookAndFeelChanged (this=0x8337fd0) at src/juce/../../../../libraries/juce/amalgamation/../src/gui/components/windows/juce_DocumentWindow.cpp:328
#2  0x081b4bd1 in juce::DocumentWindow::setTitleBarButtonsRequired (this=0x8337fd0, requiredButtons_=5, positionTitleBarButtonsOnLeft_=false)
    at src/juce/../../../../libraries/juce/amalgamation/../src/gui/components/windows/juce_DocumentWindow.cpp:133
#3  0x082a9da3 in StandaloneFilterWindow::StandaloneFilterWindow (this=0x8337fd0, title=..., backgroundColour=...)
    at ../../libraries/juce/extras/audio plugins/wrapper/Standalone/juce_StandaloneFilterWindow.cpp:44
#4  0x082aad0e in Application::initialise (this=0x8336280, commandLine=...) at src/FuckingApplication.cpp:68
#5  0x08151cad in juce::JUCEApplication::initialiseApp (this=0x8336280, commandLine=...) at src/juce/../../../../libraries/juce/amalgamation/../src/application/juce_Application.cpp:171
#6  0x08151cf6 in juce::JUCEApplication::main (commandLine=...) at src/juce/../../../../libraries/juce/amalgamation/../src/application/juce_Application.cpp:224
#7  0x08151e6e in juce::JUCEApplication::main (argc=1, argv=0xafffed64) at src/juce/../../../../libraries/juce/amalgamation/../src/application/juce_Application.cpp:264
#8  0x082aa888 in main (argc=137497708, argv=0x82c744c) at src/Application.cpp:143

i’m totally lost now.


#12

I’m sorry! It’s strange, because in my experience, the library’s now far more stable than it’s ever been!

All your problems are to do with optimised atomic ops, but I’ve no idea why gcc would f*ck it up like that (my main environment is also gcc, which should behave exactly the same, despite being on a mac). What’s your machine/distro/etc?


#13

FWIW I just tried an -O3 build of the juce demo on ubuntu, and it’s absolutely fine. That was with gcc4.5


#14

I had this when I had forgotten to put the same preprocessor definition between the juce lib and the code itself (-DLINUX=1 -D_LINUX=1 -DDEBUG=1 -D_DEBUG=1)

@Jules, maybe if would be interesting to save the compile flags + date in the binary itself so it’s possible to check this anytime for bug reporting, add this in the Makefile:

BUILD_NUMBER_FILE=build-number.txt
CFLAGS_FILE=cflags.txt
BUILD_NUMBER_LDFLAGS= -Xlinker --defsym -Xlinker __BUILD_DATE=$$(date +'%Y%m%d') -Xlinker --defsym -Xlinker __BUILD_NUMBER=$$(cat $(BUILD_NUMBER_FILE)) -Xlinker --defsym -Xlinker __CFLAGS=$$(cat $(CFLAGS_FILE))


all: $(OUTPUT)

// Increment the build number automatically anytime any obj changes
$(BUILD_NUMBER_FILE): $(OBJ)
        @if ! test -f $(BUILD_NUMBER_FILE); then echo 0 > $(BUILD_NUMBER_FILE); fi
        @echo $$(($$(cat $(BUILD_NUMBER_FILE)) + 1)) > $(BUILD_NUMBER_FILE)
        @echo $(CFLAGS) $(CXXFLAGS) > cflags.txt


// In any CPP file that's compiled
#ifdef JUCE_GCC
extern char __BUILD_DATE;
extern char __BUILD_NUMBER;
extern char __CFLAGS;
printf("Juce build date: %u\nJuce build number: %u\nJuce compile flags: %s\n", (unsigned long) &__BUILD_DATE, (unsigned long) &__BUILD_NUMBER, (const char*)__CFLAGS);
#endif

#15

[quote=“X-Ryl669”]I had this when I had forgotten to put the same preprocessor definition between the juce lib and the code itself (-DLINUX=1 -D_LINUX=1 -DDEBUG=1 -D_DEBUG=1)
[/quote]

thanx, but i actually use the juce library as amalgamated include, so it gets the same compilation flags as the other source files.

still digging into this…


#16

Ok, then, another idea:
If you’re using the last Introjucer, the option “Include Juce as splitted files” in fact does an #include “path/to/juce/amalgamated1.cpp” and others
I had issue too when I realized the introjucer was not picking the right “path/to/juce” for those files (I have multiple copies of Juce on my computer).


#17

[quote=“X-Ryl669”]Ok, then, another idea:
If you’re using the last Introjucer, the option “Include Juce as splitted files” in fact does an #include “path/to/juce/amalgamated1.cpp” and others
I had issue too when I realized the introjucer was not picking the right “path/to/juce” for those files (I have multiple copies of Juce on my computer).[/quote]

it seems strange, not using introjucer at all, and double checked the paths, everythings is where it’'s meant to be. btw, atom also is experiencing __sync_add_and_fetch atomics problems in another part of the library, so i’m starting to think something is going wrong with atomics…


#18

yeah and my project is Introjucer generated, i did not add any compiler flags (added two preprocessor definitions LUA_USE_LINUX and JUCE_LINUX) and that’s it.


#19

Try this then:

// Add a global lock here
CriticalSection atomicSection;
 
template <>
class Atomic
{
[...]
    // In any operation, take the lock and perform the atomic operation 
    operator ++ () { ScopedLock scope(atomicSection); ++value; }
[...]

#20

i think at this point CriticalSection does not exist yet

atom@ubuntu-x32:~/devel/ctrlr/Builds/Linux$ make -j2
Compiling JuceLibraryCode1.cpp
Compiling JuceLibraryCode2.cpp
In file included from /home/atom/devel/juce/amalgamation/../src/containers/../core/../text/juce_String.h:40,
                 from /home/atom/devel/juce/amalgamation/../src/containers/../core/juce_Logger.h:29,
                 from /home/atom/devel/juce/amalgamation/../src/containers/../core/juce_StandardHeader.h:185,
                 from /home/atom/devel/juce/amalgamation/../src/containers/juce_ValueTree.cpp:26,
                 from /home/atom/devel/juce/amalgamation/juce_amalgamated_template.cpp:156,
                 from /home/atom/devel/juce/amalgamation/juce_amalgamated2.cpp:31,
                 from ../../JuceLibraryCode/JuceLibraryCode2.cpp:16:
/home/atom/devel/juce/amalgamation/../src/containers/../core/../text/../memory/juce_Atomic.h:37: error: ‘CriticalSection’ does not name a type
In file included from /home/atom/devel/juce/amalgamation/../src/core/../text/juce_String.h:40,
                 from /home/atom/devel/juce/amalgamation/../src/core/juce_Logger.h:29,
                 from /home/atom/devel/juce/amalgamation/../src/core/juce_StandardHeader.h:185,
                 from /home/atom/devel/juce/amalgamation/../src/core/juce_FileLogger.cpp:26,
                 from /home/atom/devel/juce/amalgamation/juce_amalgamated_template.cpp:101,
                 from /home/atom/devel/juce/amalgamation/juce_amalgamated1.cpp:31,
                 from ../../JuceLibraryCode/JuceLibraryCode1.cpp:16:
/home/atom/devel/juce/amalgamation/../src/core/../text/../memory/juce_Atomic.h:37: error: ‘CriticalSection’ does not name a type