Juce Demo hangs when trying to open a file in code editor

I just checked out the latest Juce tip on Ubuntu 12.10 and the Juce Demo hangs when one tries to open a file in the code editor. The assert is:

JUCE Assertion failure in …/…/…/…/modules/juce_core/files/juce_File.cpp, line 149

Got a stack trace handy?

Why do I always forget to post these…

(gdb) run
Starting program: /home/rory/Sourcecode/juce/extras/JuceDemo/Builds/Linux/build/JuceDemo 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
JUCE v2.0.27
JUCE Assertion failure in ../../../../modules/juce_core/files/juce_File.cpp, line 149

Program received signal SIGTRAP, Trace/breakpoint trap.
0x00007ffff5edb707 in kill () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) bt
#0  0x00007ffff5edb707 in kill () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x000000000055e54f in juce::File::parseAbsolutePath (p=...)
    at ../../../../modules/juce_core/files/juce_File.cpp:149
#2  0x000000000055df3b in juce::File::File (this=0x7fffffffd950, 
    fullPathName=...) at ../../../../modules/juce_core/files/juce_File.cpp:27
#3  0x000000000067d98f in juce::LinuxFontFileIterator::next (
    at ../../../../modules/juce_graphics/native/juce_linux_Fonts.cpp:115
#4  0x000000000067da05 in juce::LinuxFontFileIterator::next (
    at ../../../../modules/juce_graphics/native/juce_linux_Fonts.cpp:116
#5  0x000000000067da05 in juce::LinuxFontFileIterator::next (
    at ../../../../modules/juce_graphics/native/juce_linux_Fonts.cpp:116
#6  0x000000000067dd6d in juce::FTTypefaceList::FTTypefaceList (this=0xed2f10)
    at ../../../../modules/juce_graphics/native/juce_linux_Fonts.cpp:138
#7  0x000000000067e539 in juce::FTTypefaceList::getInstance ()
    at ../../../../modules/juce_graphics/native/juce_linux_Fonts.cpp:263
#8  0x000000000067f3eb in juce::DefaultFontNames::getDefaultSansSerifFontName
    () at ../../../../modules/juce_graphics/native/juce_linux_Fonts.cpp:514
#9  0x000000000067f12f in juce::DefaultFontNames::DefaultFontNames (
    this=0xeb8120 <juce::Font::getDefaultTypefaceForFont(juce::Font const&)::defaultNames>)
---Type <return> to continue, or q <return> to quit---
    at ../../../../modules/juce_graphics/native/juce_linux_Fonts.cpp:483
#10 0x000000000066f7ac in juce::Font::getDefaultTypefaceForFont (font=...)
    at ../../../../modules/juce_graphics/native/juce_linux_Fonts.cpp:546
#11 0x000000000070a7b4 in juce::LookAndFeel::getTypefaceForFont (
    this=0xeccc50, font=...)
    at ../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.cpp:277
#12 0x000000000070a0c0 in juce::LookAndFeelHelpers::getTypefaceForFontFromLookAndFeel (font=...)
    at ../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.cpp:58
#13 0x000000000067b0dc in juce::TypefaceCache::findTypefaceFor (this=0xed2cc0, 
    font=...) at ../../../../modules/juce_graphics/fonts/juce_Font.cpp:112
#14 0x0000000000668e23 in juce::Font::getTypeface (this=0x7fffffffde40)
    at ../../../../modules/juce_graphics/fonts/juce_Font.cpp:402
#15 0x00000000006698d7 in juce::Font::getStringWidthFloat (
    this=0x7fffffffde40, text=...)
    at ../../../../modules/juce_graphics/fonts/juce_Font.cpp:635
#16 0x00000000006698ab in juce::Font::getStringWidth (this=0x7fffffffde40, 
    text=...) at ../../../../modules/juce_graphics/fonts/juce_Font.cpp:630
#17 0x000000000070f9aa in juce::LookAndFeel::getMenuBarItemWidth (
    this=0xeccc50, menuBar=..., itemIndex=0, itemText=...)
    at ../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.cpp:1142
#18 0x000000000071cdb9 in juce::MenuBarComponent::resized (this=0xed2a50)
---Type <return> to continue, or q <return> to quit---
    at ../../../../modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp:108
#19 0x000000000071dc7f in juce::MenuBarComponent::menuBarItemsChanged (
    at ../../../../modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp:317
#20 0x000000000071ca70 in juce::MenuBarComponent::setModel (this=0xed2a50, 
    at ../../../../modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp:63
#21 0x000000000071c727 in juce::MenuBarComponent::MenuBarComponent (
    this=0xed2a50, model_=0xecff80)
    at ../../../../modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp:36
#22 0x000000000074caef in juce::DocumentWindow::setMenuBar (this=0xec9220, 
    newMenuBarModel=0xecff80, newMenuBarHeight=0)
    at ../../../../modules/juce_gui_basics/windows/juce_DocumentWindow.cpp:135
#23 0x000000000040b27b in MainDemoWindow::MainDemoWindow (this=0xec9220)
    at ../../Source/MainDemoWindow.cpp:628
#24 0x0000000000409fa6 in JUCEDemoApplication::JUCEDemoApplication (
    this=0xec91f0) at ../../Source/ApplicationStartup.cpp:36
#25 0x0000000000409cb8 in juce_CreateApplication ()
    at ../../Source/ApplicationStartup.cpp:161
#26 0x00000000007560bb in juce::JUCEApplication::main ()
    at ../../../../modules/juce_gui_basics/application/juce_Application.cpp:233
#27 0x00000000007563b6 in juce::JUCEApplication::main (argc=1, 
---Type <return> to continue, or q <return> to quit---
    at ../../../../modules/juce_gui_basics/application/juce_Application.cpp:297
#28 0x0000000000409d03 in main (argc=1, argv=0x7fffffffe198)
    at ../../Source/ApplicationStartup.cpp:161

I have reproduced this in Ubuntu 12.10. It is most likely caused by an extra item in the fonts.conf XML file, specifying a XDG-prefix to central font directories.

I will have time to fix this tomorrow and post a patch unless someone else has already taken on the problem.

Thanks, I’ll check in a fix shortly.

Thanks Jules. Works fine now.

Jules, if I understand correctly what you checked in, it avoids the problem by prepending CWD to any non-absolute paths in fonts.conf, there by avoiding the assertion?

In addition to that, it might be useful to address the root cause of the assertion.

Ubuntu 12.10 has a fonts.conf that includes an XML dir item like this:

That’s described in http://freedesktop.org/software/fontconfig/fontconfig-user.html:


This element contains a directory name which will be scanned for font files to include in the set of available fonts. If ‘prefix’ is set to “xdg”, the value in the XDG_DATA_HOME environment variable will be added as the path prefix. please see XDG Base Directory Specification for more details. [/quote]

From: http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html

So, it’s not supposed to be prepended by CWD.

Maybe something along the lines of: (complete file attached also)

[code]diff --git a/modules/juce_graphics/native/juce_linux_Fonts.cpp b/modules/juce_graphics/native/juce_linux_Fonts.cpp
index 47c0860…19f9f8c 100644
— a/modules/juce_graphics/native/juce_linux_Fonts.cpp
+++ b/modules/juce_graphics/native/juce_linux_Fonts.cpp
@@ -89,7 +89,21 @@ public:
forEachXmlChildElementWithTagName (*fontsInfo, e, “dir”)

  •                fontDirs.add (e->getAllSubText().trim());
  •                const String fontPath (e->getAllSubText().trim());
  •                if (e->getStringAttribute ("prefix") == "xdg" && fontPath.isNotEmpty())
  •                {
  •                    String xdgDataHome (CharPointer_UTF8 (getenv ("XDG_DATA_HOME")));
  •                    if (xdgDataHome.trim().isEmpty())
  •                        xdgDataHome = "~/.local/share";
  •                    fontDirs.add (File (xdgDataHome).getChildFile (fontPath).getFullPathName());
  •                }
  •                else
  •                {
  •                    fontDirs.add (fontPath);
  •                }

@@ -97,6 +111,7 @@ public:
if (fontDirs.size() == 0)
fontDirs.add ("/usr/X11R6/lib/X11/fonts");

  •    fontDirs.removeDuplicates (false);
       fontDirs.removeEmptyStrings (true);


Good research there, yes I did just patch the symptoms not the cause… Thanks, I’ll look at this when I get a moment.

Just to confirm that this is now checked in and solved, thank you Jules!

The code editor demo causes the following assertion on Arch Linux when one tries to open a file:

JUCE Assertion failure in ../../JuceLibraryCode/modules/juce_core/files/juce_File.cpp, line 149

Program received signal SIGTRAP, Trace/breakpoint trap.
0x00007ffff53be6c7 in kill () from /usr/lib/libc.so.6
(gdb) disassemble 0x7ffff53be6c7
Dump of assembler code for function kill:
0x00007ffff53be6c0 <+0>: mov $0x3e,%eax
0x00007ffff53be6c5 <+5>: syscall
=> 0x00007ffff53be6c7 <+7>: cmp $0xfffffffffffff001,%rax
0x00007ffff53be6cd <+13>: jae 0x7ffff53be6d0 <kill+16>
0x00007ffff53be6cf <+15>: retq
0x00007ffff53be6d0 <+16>: mov 0x36f759(%rip),%rcx # 0x7ffff572de30
0x00007ffff53be6d7 <+23>: neg %eax
0x00007ffff53be6d9 <+25>: mov %eax,%fs:(%rcx)
0x00007ffff53be6dc <+28>: or $0xffffffffffffffff,%rax
0x00007ffff53be6e0 <+32>: retq
End of assembler dump.

Any ideas? I don't run Arch Linux, it's a user that reported it.

Well, it's warning you that you're trying to open a partial pathname. Presumably because you've typed a partial pathname in the filename box?

Anyway, it's only a demo, but I'll see what I can do to avoid that.

I am that troublesome guy.

Why not http://www.manpagez.com/man/3/realpath/ ??

Well, File already does a lot of that stuff, but you're missing the point. The issue that this assertion is complaining about is that if you try to create a File object from something like "foo/bar", you're not giving it any clues about what that path is supposed to be relative to. The CWD? The path of the exe? Some other random path..? The File class has no way of knowing what you meant.

So when you're creating a file from a string, then unless your string definitely contains an absolute path, you should always start from an absolute path. E.g. File::getCurrentWorkingDirectory().getChildFile (someString) or File ("/myabsolutepath").getChildFile (someString)

I'm aware of how much the File class does to reduce problems like this, which is why I flagged it. This happens as soon as one selects a file from the open file dialogue and hits Ok. I have to reiterate, it works fine for me on my Xubuntu distro which is why I hadn't noticed it before. Anyway, I'll just use your above suggestion from now on. Problem solved.