Segementation fault with .so file

I am trying to make dynamic ui function.
so, I made a file with .so type to add a window component in a tabwindow.
basically, it is working well before I click the tab. It means that constructor and painting & resize function calling was working.
but, when I clicked the tab, I got segmentation fault.

then, I cut off some part in callee class to figure out where the problem happend.
// Test1_Button->setBounds (324, 196, 150, 24);
// Test2_Button->setBounds (324, 236, 150, 24);

It works.
so, it looks like that the sub component painting function makes the segmentation fault, but I can’t understand why it happend for only dynamic loading case.

do you have any idea ?

/* Caller Class */

//[Constructor] You can add your own custom stuff here..
String fileName(T("libIProperty.so"));
File ipControl(fileName);
if(ipControl.exists() == true )
{
    ipControlHandle = Process::loadDynamicLibrary(fileName);
    // load the symbols
    createFunction = (create_t *)Process::getProcedureEntryPoint (ipControlHandle,String(T("create")));
    destroyFunction = (destroy_t *)Process::getProcedureEntryPoint (ipControlHandle,String(T("destroy")));

    iProperty= createFunction();
    tabbedComponent->addTab (T("IP Control"), Colours::lightgrey, iProperty, true);
}
//[/Constructor]


//[Destructor_pre]. You can add your own custom destruction code here..
String fileName(T("libIProperty.so"));
File ipControl(fileName);
if(ipControl.exists() == true )
{
    destroyFunction(iProperty);
    Process::freeDynamicLibrary (ipControlHandle);
}
//[/Destructor_pre]

================================
/* Callee Class */
XNexus_XTE_IProperty::XNexus_XTE_IProperty ()
: Test1_Button (0),
Test2_Button (0)
{
addAndMakeVisible (Test1_Button = new TextButton (T(“Test1_Button”)));
Test1_Button->setButtonText (T(“Intelligent Property”));
Test1_Button->addButtonListener (this);

addAndMakeVisible (Test2_Button = new TextButton (T("Test2_Button")));
Test2_Button->setButtonText (T("Plug & Play Test"));
Test2_Button->addButtonListener (this);

setSize (992, 600);

}

XNexus_XTE_IProperty::~XNexus_XTE_IProperty()
{
deleteAndZero (Test1_Button);
deleteAndZero (Test2_Button);
}

void XNexus_XTE_IProperty::paint (Graphics& g)
{
g.fillAll (Colours::white);
}

void XNexus_XTE_IProperty::resized()
{
Test1_Button->setBounds (324, 196, 150, 24);
Test2_Button->setBounds (324, 236, 150, 24);
}

void XNexus_XTE_IProperty::buttonClicked (Button* buttonThatWasClicked)
{
if (buttonThatWasClicked == Test1_Button)
{
}
else if (buttonThatWasClicked == Test2_Button)
{
}
}

extern “C” XNexus_XTE_IProperty* create() {
return new XNexus_XTE_IProperty;
}

extern “C” void destroy(XNexus_XTE_IProperty* p) {
delete p;
}

Probably something nasty like cross-linking of the functions in the two modules, or different allocators clashing or something like that…

My compiling option and linking option is very simple like following to make application and to make shared library.
I use Cygwin environment.
In order to make shared library, I just copied same option and modified that based on Cygwin User Manual to make .so file.
Futhermore, If I link the file in one static application, it is fine.

[Main Application]
CFLAGS += (CPPFLAGS) -O2 CXXFLAGS := (CFLAGS)
LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -mwindows -lpthread -ljuce -ldl
(OUTDIR)/(TARGET): (OBJECTS) (LDDEPS) (RESOURCES) @(CXX) -o @ (OBJECTS) (LDFLAGS) (RESOURCES)

[Shared Library]
CFLAGS += (CPPFLAGS) -O2 CXXFLAGS := (CFLAGS)
LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -mwindows -lpthread -ljuce
(OUTDIR)/(TARGET): (OBJECTS) (LDDEPS) (RESOURCES) @(CXX) -shared -fPIC -o @ (OBJECTS) (LDFLAGS) (RESOURCES)

I was talking about dynamic linking. And allocators are always a problem when you’re using dynamic libraries.

Run your process under GDB (gdb path/to/process.exe), and when it segfault, get a back trace
(The GDB command for the trace is “bt”, you can walk up and down the trace with “up” and “down” command, “list” gives you the source code around the bug).

BTW, why don’t you use VS2005, DevC++ or CodeBlocks under windows ?
You’ll be able to debug more easily with true IDE.

I found the reason.

  1. Application try to use static juce library and another dynimic library which was built with juce library together.
    so, I have to build Juce library .so file and build another library based on .so juce library.

while I was investigating this problem, I found strange thing in Cygwin linker. I have tried to make new(another) .so file with libjuce.so file, but the linker always try to find libjuc.dll file.

and why I don’t use DEV C++ or some IDE environment is that it dos’nt support some basic Unix API like “gettimeofday” and when I link -mwindows option to make Win32 Application in compiling, GDB doesn’t work corretly at all.

so, whatever I use IDE evironment or not, the situation is same to me, then I use the simplest way. Just console environment.

when I open the tab, and click close button to quite application, I got segmentation fualt. the problem happens in red code.
but, if I close application in the other tab, it is ok.

what is different ?

XNexus_XTE::XNexus_XTE ()
: tabbedComponent (0)
{
addAndMakeVisible (tabbedComponent = new TabbedComponent (TabbedButtonBar::TabsAtTop));
tabbedComponent->setTabBarDepth (30);
tabbedComponent->addTab (T(“DeInterlacer”), Colours::lightgrey, new XNexus_XTE_Deinterlacer(), true);
tabbedComponent->addTab (T(“Edge Enhancement”), Colours::lightgrey, new XNexus_XTE_EdgeEnhancement(), true);
tabbedComponent->addTab (T(“Noise Reduction”), Colours::lightgrey, new XNexus_XTE_NoiseReduction(), true);
tabbedComponent->addTab (T(“DNC3”), Colours::lightgrey, new XNexus_XTE_DNC3(), true);
tabbedComponent->setCurrentTabIndex (3);

setSize (1000, 632);

//[Constructor] You can add your own custom stuff here..
String fileName(T("libIProperty.dll"));
File ipControl(fileName);
if(ipControl.exists() == true )
{
    ipControlHandle = Process::loadDynamicLibrary(fileName);
    // load the symbols
    createFunction = (create_t *)Process::getProcedureEntryPoint (ipControlHandle,String(T("create")));
    destroyFunction = (destroy_t *)Process::getProcedureEntryPoint (ipControlHandle,String(T("destroy")));

    iProperty= createFunction();
    tabbedComponent->addTab (T("IP Control"), Colours::lightgrey, iProperty, true);
}
//[/Constructor]

}

XNexus_XTE::~XNexus_XTE()
{
//[Destructor_pre]. You can add your own custom destruction code here…
String fileName(T(“libIProperty.dll”));
File ipControl(fileName);
if(ipControl.exists() == true )
{
if(iProperty) destroyFunction(iProperty);
if(ipControlHandle) Process::freeDynamicLibrary (ipControlHandle);
}
//[/Destructor_pre]

[color=red] deleteAndZero (tabbedComponent);[/color]
//[Destructor]. You can add your own custom destruction code here…
//[/Destructor]
}

Like I’ve already suggested twice, you’ve probably got an allocator clash - where an object allocated in one module is getting deleted by the allocator in another module.

So, How to solve the problem ?

use a debugger.

or write out to the console each time delete or create is called on a class.

You need to actually link juce as a DLL rather than statically linking it into each module. It’s a PITA, which is why I try to avoid dynamic libraries.

It does sound like you’re making it unbelievably hard for yourself in every possible way… Just write a normal exe in Visual Studio, and everything just works like a dream!