Crash with #include "AppConfig.h" + JUCE_CHECK_MEMORY_LEAKS

Discussion and support for general JUCE issues

Crash with #include "AppConfig.h" + JUCE_CHECK_MEMORY_LEAKS

Postby TheVinn » Thu Mar 29, 2012 2:12 am

When this line in juce_AudioDeviceManager.cpp executes:

AudioDeviceManager::setAudioDeviceSetup()
Code: Select all
currentSetup = newSetup;


I get a corrupted heap when the BigIntegers get assigned. I'm guessing this might have something to do with JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS? I'm running Visual Studio 2010. When I switch to "Multithreaded Debug" (to use the CRT debug heap) the problem disappears. The problem does not exist in my debug build. In an effort to narrow this problem down I have turned off optimizations in my Release build, and I still get the problem.

I've been trying to track this down for days now and I'm having no luck whatsoever. It happened when I moved to the modules branch. Any ideas?

UPDATED POST TITLE to reflect new information.
Last edited by TheVinn on Thu Mar 29, 2012 11:42 pm, edited 2 times in total.
Open Source: LayerEffects, VFLib, SimpleDJ, DSP Filters, LuaBridge, JUCE, FreeType, TagLib
"This isn't a big project, it shouldn't take long." - Jules
User avatar
TheVinn
JUCE UberWeenie
 
Posts: 2976
Joined: Sat Aug 29, 2009 11:31 am
Location: Marina del Rey, California

Re: Memory corruption in AudioDeviceSetup assignment

Postby TheVinn » Thu Mar 29, 2012 3:49 am

I tried defining JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS to 0 instead of 1 in the appropriate Juce header and it didn't resolve the issue.
Open Source: LayerEffects, VFLib, SimpleDJ, DSP Filters, LuaBridge, JUCE, FreeType, TagLib
"This isn't a big project, it shouldn't take long." - Jules
User avatar
TheVinn
JUCE UberWeenie
 
Posts: 2976
Joined: Sat Aug 29, 2009 11:31 am
Location: Marina del Rey, California

Re: Memory corruption in AudioDeviceSetup assignment

Postby jfitzpat » Thu Mar 29, 2012 5:22 am

I just updated to tip and rebuilt a few things and don't see the problem here (VC2010, 32 and 64 bit builds). Can you point to a simple case that has the problem?
User avatar
jfitzpat
JUCE UberWeenie
 
Posts: 251
Joined: Tue Jan 10, 2012 6:29 am
Location: Glendale, California

Re: Memory corruption in AudioDeviceSetup assignment

Postby TheVinn » Thu Mar 29, 2012 6:26 am

jfitzpat wrote:I just updated to tip and rebuilt a few things and don't see the problem here (VC2010, 32 and 64 bit builds). Can you point to a simple case that has the problem?


I cannot. I've been trying to track it down for many hours to no avail. It only happens with the non-debug C Runtime. I turned off optimizations and it still happens. AudioDeviceManager::currentSetup constructs normally but when the constructor returns the inputDeviceName and outputDeviceName get invalid pointers. I will spend more time tomorrow.
Open Source: LayerEffects, VFLib, SimpleDJ, DSP Filters, LuaBridge, JUCE, FreeType, TagLib
"This isn't a big project, it shouldn't take long." - Jules
User avatar
TheVinn
JUCE UberWeenie
 
Posts: 2976
Joined: Sat Aug 29, 2009 11:31 am
Location: Marina del Rey, California

Re: Memory corruption in AudioDeviceSetup assignment

Postby jules » Thu Mar 29, 2012 9:23 am

Can't see any obvious mistakes in there.. And if there were, I'd expect things like the cryptography classes to explode, since they make heavy use of BigInteger shuffling.

Those "corrupted heap" messages normally pop up on the next allocator call AFTER the memory gets corrupted, so maybe the real culprit is something that happened just before the BigInteger copy?
User avatar
jules
Fearless Leader
 
Posts: 17216
Joined: Mon Sep 06, 2004 9:03 am
Location: London, UK

Re: Memory corruption in AudioDeviceSetup assignment

Postby jfitzpat » Thu Mar 29, 2012 4:29 pm

TheVinn wrote:I've been trying to track it down for many hours to no avail.


I had one of those Friday and Saturday. Not fun. Sorry!
User avatar
jfitzpat
JUCE UberWeenie
 
Posts: 251
Joined: Tue Jan 10, 2012 6:29 am
Location: Glendale, California

Re: Memory corruption in AudioDeviceSetup assignment

Postby jules » Thu Mar 29, 2012 4:45 pm

jfitzpat wrote:
TheVinn wrote:I've been trying to track it down for many hours to no avail.


I had one of those Friday and Saturday. Not fun. Sorry!


I'm in the middle of one myself, involving random crashes in Android and no way to get a stack trace out of the damn thing. :x
User avatar
jules
Fearless Leader
 
Posts: 17216
Joined: Mon Sep 06, 2004 9:03 am
Location: London, UK

Re: Memory corruption in AudioDeviceSetup assignment

Postby TheVinn » Thu Mar 29, 2012 4:53 pm

Just a guess but I think it might have something to do with statically linking with boost and a mismatch in the CRT debug heap versus the normal heap...
Open Source: LayerEffects, VFLib, SimpleDJ, DSP Filters, LuaBridge, JUCE, FreeType, TagLib
"This isn't a big project, it shouldn't take long." - Jules
User avatar
TheVinn
JUCE UberWeenie
 
Posts: 2976
Joined: Sat Aug 29, 2009 11:31 am
Location: Marina del Rey, California

Re: Memory corruption in AudioDeviceSetup assignment

Postby TheVinn » Thu Mar 29, 2012 8:03 pm

Okay after a lot of work I have managed to comment out everything except the user interface in my application. So no AudioDeviceManager, etc... and I still get a heap corruption bringing up a mostly empty window with a simple menubar. This is what I know so far:

- Heap gets corrupted when running the non-debug C Runtime

- Happens with optimizations turned off or on in the build

- Doesn't happen if I don't bring up the main window

- Happens even when all audio / application logic is turned off

- Does not happen with the debug C Runtime
Open Source: LayerEffects, VFLib, SimpleDJ, DSP Filters, LuaBridge, JUCE, FreeType, TagLib
"This isn't a big project, it shouldn't take long." - Jules
User avatar
TheVinn
JUCE UberWeenie
 
Posts: 2976
Joined: Sat Aug 29, 2009 11:31 am
Location: Marina del Rey, California

Re: Memory corruption in AudioDeviceSetup assignment

Postby TheVinn » Thu Mar 29, 2012 10:43 pm

I have boiled it down to this simple app:

Code: Select all
// Copyright (C) 2008 by One Guy Group, Inc., All rights reserved worldwide.

#include "modules/juce_core/juce_core.h"
#include "modules/juce_gui_basics/juce_gui_basics.h"
#include "modules/juce_data_structures/juce_data_structures.h"
#include "modules/juce_events/juce_events.h"
#include "modules/juce_graphics/juce_graphics.h"
#include "modules/juce_video/juce_video.h"
#include "modules/juce_opengl/juce_opengl.h"
#include "modules/juce_audio_basics/juce_audio_basics.h"
#include "modules/juce_audio_formats/juce_audio_formats.h"
#include "modules/juce_audio_processors/juce_audio_processors.h"
#include "modules/juce_audio_devices/juce_audio_devices.h"
#include "modules/juce_cryptography/juce_cryptography.h"
#include "modules/juce_gui_extra/juce_gui_extra.h"
#include "modules/juce_audio_utils/juce_audio_utils.h"

using namespace juce;

#include "MainApp.h"

static const String APPNAME("CrashTestDummy");
static const String APPVERSION("1.0.0 Pre-release");
static const String OKTEXT("OK");

MainApp* MainApp::s_app = 0;

MainApp::MainApp()
{
  jassert( !s_app );

  s_app = this;

  // NEVER do anything in here that could involve any Juce function being called
  // - leave all your startup tasks until the initialise() method.
}

MainApp::~MainApp()
{
  // Your shutdown() method should already have done all the things necessary to
  // clean up this app object, so you should never need to put anything in
  // the destructor.

  // Making any Juce calls in here could be very dangerous...

  s_app = 0;
}

void MainApp::initialise (String const&)
{
  bool shouldRun = true;

  if (shouldRun)
  {
    JUCE_TRY
    {
     Component* w = new DocumentWindow (
      "Crash Test",
      Colours::azure,
      DocumentWindow::allButtons,
      true);

     w->setVisible (true);
    }
    JUCE_CATCH_EXCEPTION
  }

  if (!shouldRun)
  {
    JUCEApplication::quit();
  }
}

void MainApp::shutdown()
{
}

const String MainApp::getApplicationName()
{
    return APPNAME;
}

const String MainApp::getApplicationVersion()
{
    return APPVERSION;
}

bool MainApp::moreThanOneInstanceAllowed()
{
  // Have to allow multiples so we can show bullet-proof
  // alert windows via launching a second process.
  return true;
}

void MainApp::anotherInstanceStarted (const String& commandLine)
{
}

START_JUCE_APPLICATION (MainApp)


I sent it to a friend of mine and when he builds it and runs, it doesn't corrupt. Still searching.
Open Source: LayerEffects, VFLib, SimpleDJ, DSP Filters, LuaBridge, JUCE, FreeType, TagLib
"This isn't a big project, it shouldn't take long." - Jules
User avatar
TheVinn
JUCE UberWeenie
 
Posts: 2976
Joined: Sat Aug 29, 2009 11:31 am
Location: Marina del Rey, California

Re: Memory corruption in AudioDeviceSetup assignment

Postby jfitzpat » Thu Mar 29, 2012 10:47 pm

I'll try to build it in a bit.
User avatar
jfitzpat
JUCE UberWeenie
 
Posts: 251
Joined: Tue Jan 10, 2012 6:29 am
Location: Glendale, California

Re: Memory corruption in AudioDeviceSetup assignment

Postby TheVinn » Thu Mar 29, 2012 10:55 pm

jfitzpat wrote:I'll try to build it in a bit.


Not necessary...I'm tracking it down. Besides, if you build it, it won't corrupt. It seems my machine is producing executables that are different from everyone else...no joke. I'm doing some md5/SHA testing now. I'm guessing that my SSD has a failed sector somewhere.
Open Source: LayerEffects, VFLib, SimpleDJ, DSP Filters, LuaBridge, JUCE, FreeType, TagLib
"This isn't a big project, it shouldn't take long." - Jules
User avatar
TheVinn
JUCE UberWeenie
 
Posts: 2976
Joined: Sat Aug 29, 2009 11:31 am
Location: Marina del Rey, California

Re: Memory corruption in AudioDeviceSetup assignment

Postby TheVinn » Thu Mar 29, 2012 11:36 pm

Okay this is what I have so far:

AppConfig.h
Code: Select all
/*

    IMPORTANT! This file is auto-generated each time you save your
    project - if you alter its contents, your changes may be overwritten!

    If you want to change any of these values, use the Introjucer to do so,
    rather than editing this file directly!

    Any commented-out settings will assume their default values.

*/

#ifndef __JUCE_APPCONFIG_IVABE4__
#define __JUCE_APPCONFIG_IVABE4__

#define JUCE_CHECK_MEMORY_LEAKS 1

//==============================================================================
// VF: These seem to be unused
#define JUCE_MODULE_AVAILABLE_juce_audio_basics          1
#define JUCE_MODULE_AVAILABLE_juce_audio_devices         1
#define JUCE_MODULE_AVAILABLE_juce_audio_formats         1
#define JUCE_MODULE_AVAILABLE_juce_audio_processors      1
#define JUCE_MODULE_AVAILABLE_juce_core                  1
#define JUCE_MODULE_AVAILABLE_juce_cryptography          1
#define JUCE_MODULE_AVAILABLE_juce_data_structures       1
#define JUCE_MODULE_AVAILABLE_juce_events                1
#define JUCE_MODULE_AVAILABLE_juce_graphics              1
#define JUCE_MODULE_AVAILABLE_juce_gui_basics            1
#define JUCE_MODULE_AVAILABLE_juce_gui_extra             1
#define JUCE_MODULE_AVAILABLE_juce_opengl                1
#define JUCE_MODULE_AVAILABLE_juce_video                 1

//==============================================================================
// juce_audio_devices flags:

#ifndef JUCE_ASIO
#define JUCE_ASIO 1
#endif

#ifndef JUCE_WASAPI
#define JUCE_WASAPI 1
#endif

#ifndef JUCE_DIRECTSOUND
#define JUCE_DIRECTSOUND 1
#endif

#ifndef JUCE_ALSA
#define JUCE_ALSA 1
#endif

#ifndef JUCE_JACK
#define JUCE_JACK 1
#endif

#ifndef JUCE_USE_CDREADER
//#define JUCE_USE_CDREADER
#endif

#ifndef    JUCE_USE_CDBURNER
//#define JUCE_USE_CDBURNER
#endif

//==============================================================================
// juce_audio_formats flags:

#ifndef JUCE_USE_FLAC
#define JUCE_USE_FLAC 1
#endif

#ifndef JUCE_USE_OGGVORBIS
#define JUCE_USE_OGGVORBIS 1
#endif

#ifndef JUCE_USE_MP3AUDIOFORMAT
#define JUCE_USE_MP3AUDIOFORMAT 0
#endif

//==============================================================================
// juce_audio_processors flags:

#ifndef JUCE_PLUGINHOST_VST
#define JUCE_PLUGINHOST_VST 1
#endif

#ifndef JUCE_PLUGINHOST_AU
#define JUCE_PLUGINHOST_AU 1
#endif

//==============================================================================
// juce_core flags:

#ifndef    JUCE_FORCE_DEBUG
//#define JUCE_FORCE_DEBUG
#endif

#ifndef    JUCE_LOG_ASSERTIONS
//#define JUCE_LOG_ASSERTIONS
#endif

#ifndef    JUCE_CHECK_MEMORY_LEAKS
//#define JUCE_CHECK_MEMORY_LEAKS
#endif

#ifndef JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES
#define JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES 1
#endif

//==============================================================================
// juce_graphics flags:

#ifndef    JUCE_USE_COREIMAGE_LOADER
//#define JUCE_USE_COREIMAGE_LOADER
#endif

#ifndef    JUCE_USE_DIRECTWRITE
//#define JUCE_USE_DIRECTWRITE
#endif

//==============================================================================
// juce_gui_basics flags:

#ifndef    JUCE_ENABLE_REPAINT_DEBUGGING
//#define JUCE_ENABLE_REPAINT_DEBUGGING
#endif

#ifndef    JUCE_USE_XSHM
//#define JUCE_USE_XSHM
#endif

#ifndef    JUCE_USE_XRENDER
//#define JUCE_USE_XRENDER
#endif

#ifndef    JUCE_USE_XCURSOR
//#define JUCE_USE_XCURSOR
#endif

//==============================================================================
// juce_gui_extra flags:

#ifndef    JUCE_WEB_BROWSER
//#define JUCE_WEB_BROWSER
#endif

//==============================================================================
// juce_video flags:

#ifndef    JUCE_DIRECTSHOW
//#define JUCE_DIRECTSHOW
#endif

#ifndef    JUCE_MEDIAFOUNDATION
//#define JUCE_MEDIAFOUNDATION
#endif

#ifndef    JUCE_QUICKTIME
//#define JUCE_QUICKTIME
#endif

#ifndef    JUCE_USE_CAMERA
//#define JUCE_USE_CAMERA
#endif

#endif


MainApp.cpp
Code: Select all
// Copyright (C) 2008 by One Guy Group, Inc., All rights reserved worldwide.

// Un-comment to fix crash
//#include "AppConfig.h"

#include "modules/juce_core/juce_core.h"
#include "modules/juce_gui_basics/juce_gui_basics.h"
#include "modules/juce_data_structures/juce_data_structures.h"
#include "modules/juce_events/juce_events.h"
#include "modules/juce_graphics/juce_graphics.h"
#include "modules/juce_video/juce_video.h"
#include "modules/juce_opengl/juce_opengl.h"
#include "modules/juce_audio_basics/juce_audio_basics.h"
#include "modules/juce_audio_formats/juce_audio_formats.h"
#include "modules/juce_audio_processors/juce_audio_processors.h"
#include "modules/juce_audio_devices/juce_audio_devices.h"
#include "modules/juce_cryptography/juce_cryptography.h"
#include "modules/juce_gui_extra/juce_gui_extra.h"
#include "modules/juce_audio_utils/juce_audio_utils.h"

using namespace juce;

#include "MainApp.h"

static const String APPNAME("CrashTestDummy");
static const String APPVERSION("1.0.0 Pre-release");
static const String OKTEXT("OK");

class MainWindow : public DocumentWindow
{
public:
  MainWindow () : DocumentWindow (
   "Crash Test",
   Colours::azure,
   DocumentWindow::allButtons,
   true
   )
  {
  }

  void closeButtonPressed ()
  {
   JUCEApplication::getInstance()->systemRequestedQuit();
   delete this;
  }
};

MainApp* MainApp::s_app = 0;

MainApp::MainApp()
{
  jassert( !s_app );

  s_app = this;

  // NEVER do anything in here that could involve any Juce function being called
  // - leave all your startup tasks until the initialise() method.
}

MainApp::~MainApp()
{
  // Your shutdown() method should already have done all the things necessary to
  // clean up this app object, so you should never need to put anything in
  // the destructor.

  // Making any Juce calls in here could be very dangerous...

  s_app = 0;
}

void MainApp::initialise (String const&)
{
  bool shouldRun = true;

  if (shouldRun)
  {
    JUCE_TRY
    {
     Component* w = new MainWindow;

     w->setVisible (true);
    }
    JUCE_CATCH_EXCEPTION
  }

  if (!shouldRun)
  {
    JUCEApplication::quit();
  }
}

void MainApp::shutdown()
{
}

const String MainApp::getApplicationName()
{
    return APPNAME;
}

const String MainApp::getApplicationVersion()
{
    return APPVERSION;
}

bool MainApp::moreThanOneInstanceAllowed()
{
  // Have to allow multiples so we can show bullet-proof
  // alert windows via launching a second process.
  return true;
}

void MainApp::anotherInstanceStarted (const String& commandLine)
{
}

START_JUCE_APPLICATION (MainApp)


This application corrupts the heap in Release (but not in Debug). Uncommenting the #include "AppConfig.h" from MainApp.cpp makes the problem go away.

Also, deleting everything in AppConfig.h makes the problem go away as well.
Open Source: LayerEffects, VFLib, SimpleDJ, DSP Filters, LuaBridge, JUCE, FreeType, TagLib
"This isn't a big project, it shouldn't take long." - Jules
User avatar
TheVinn
JUCE UberWeenie
 
Posts: 2976
Joined: Sat Aug 29, 2009 11:31 am
Location: Marina del Rey, California

Re: Crash related to #include "AppConfig.h"

Postby TheVinn » Thu Mar 29, 2012 11:39 pm

Alright this is the problem.

AppConfig.h
Code: Select all
...
#define JUCE_CHECK_MEMORY_LEAKS 1
...


SourceFile.cpp
Code: Select all
#include "AppConfig.h"
#include "modules/juce_core/juce_core.h"


If AppConfig.h defines JUCE_CHECK_MEMORY_LEAKS to 1 but AppConfig.h is not included in source files that include Juce module headers, it causes corrupted heaps when running with the non-debug C Runtime. This was a pain in the ass to track down.
Open Source: LayerEffects, VFLib, SimpleDJ, DSP Filters, LuaBridge, JUCE, FreeType, TagLib
"This isn't a big project, it shouldn't take long." - Jules
User avatar
TheVinn
JUCE UberWeenie
 
Posts: 2976
Joined: Sat Aug 29, 2009 11:31 am
Location: Marina del Rey, California

Re: Crash with #include "AppConfig.h" + JUCE_CHECK_MEMORY_LE

Postby cpr » Fri Mar 30, 2012 12:26 am

Ouch! I'be been bit by that type of thing before, ie. conditional compilation in header file, condition setting different in different source files which include said header.. :(
User avatar
cpr
JUCE UberWeenie
 
Posts: 131
Joined: Fri Apr 25, 2008 11:49 pm

Next

Return to General JUCE discussion

Who is online

Users browsing this forum: No registered users and 0 guests