Question

I'm getting

*** glibc detected *** malloc(): memory corruption

type errors. These are particularly difficult to debug in my case because

  1. Cross-compile environment, no valgrind
  2. libc is built without debug information, so loading a core dump into cross-gdb doesn't yield much
  3. The root filesystem is quite fragile, trying to replace glibc with a rebuilt copy causes massive breakage
  4. The application causing these errors started life as a vendor-provided C sample with malloc/free all over the place. I've added my own code that uses C++ smart pointers for its own allocation, but there are still a lot of legacy dumb pointers.

The errors also occur when I use #if to remove the code I added, although the reports come at a different place (early if my code is not present, at application exit if my code is present). That's not particularly unusual; heap layout problems are notoriously sensitive to memory layout.

I consider it likely that the original example code had a "benign" overrun somewhere, which stomps something important after I made modifications. It's also possible that some of the code I removed from the example initialized a pointer that's still being used somewhere. Or nothing important is being overwritten, but enabling debug info with -g causes more issues to be reported.

To make matters worse, the example is multi-threaded and makes calls to a complex vendor library also of dubious quality.

I'd like to localize the memory corruption. Is there any way to call the glibc heap metadata consistency check manually, instead of waiting for the next call to malloc()?


FWIW the bug was not in code I wrote, and I do believe in public shaming (and some poor soul working on the same thing may save a day by finding this), so here goes. From ilclient_utils.c in at least one of the Texas Instruments OpenMAX samples:

  pAppDataPtr->capILComp->outPortParams =
    malloc (sizeof (IL_CLIENT_OUTPORT_PARAMS) *
            pAppDataPtr->capILComp->numOutport);

  memset (pAppDataPtr->capILComp->outPortParams, 0x0,
          sizeof (IL_CLIENT_OUTPORT_PARAMS) *
          pAppDataPtr->capILComp->numOutport);

  pAppDataPtr->deiILComp->inPortParams =
    malloc (sizeof (IL_CLIENT_INPORT_PARAMS) *
            pAppDataPtr->deiILComp->numInport);

  memset (pAppDataPtr->deiILComp->inPortParams, 0x0,
          sizeof (IL_CLIENT_INPORT_PARAMS));

  pAppDataPtr->deiILComp->outPortParams =
    malloc (sizeof (IL_CLIENT_INPORT_PARAMS) *
            pAppDataPtr->deiILComp->numOutport);
  memset (pAppDataPtr->deiILComp->outPortParams, 0x0,
          pAppDataPtr->deiILComp->numOutport *
          sizeof (IL_CLIENT_OUTPORT_PARAMS));

  pAppDataPtr->encILComp->inPortParams =
    malloc (sizeof (IL_CLIENT_INPORT_PARAMS) *
            pAppDataPtr->encILComp->numInport);
  memset (pAppDataPtr->encILComp->inPortParams, 0x0,
          sizeof (IL_CLIENT_INPORT_PARAMS));

  pAppDataPtr->encILComp->outPortParams =
    malloc (sizeof (IL_CLIENT_INPORT_PARAMS) *
            pAppDataPtr->encILComp->numOutport);
  memset (pAppDataPtr->encILComp->outPortParams, 0x0,
          sizeof (IL_CLIENT_OUTPORT_PARAMS));

  pAppDataPtr->disILComp->inPortParams =
    malloc (sizeof (IL_CLIENT_INPORT_PARAMS) *
            pAppDataPtr->disILComp->numInport);
  memset (pAppDataPtr->disILComp->inPortParams, 0x0,
          sizeof (IL_CLIENT_INPORT_PARAMS));

Note that two of the above memory allocations use sizeof (IL_CLIENT_INPORT_PARAMS) but should have used sizeof (IL_CLIENT_OUTPORT_PARAMS). Long live C++ and typesafe new []!


There's a mandatory notice attached to that code:

/*
 *  Copyright (c) 2010-2011, Texas Instruments Incorporated
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *  *  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *  *  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *  *  Neither the name of Texas Instruments Incorporated nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 *  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 *  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 *  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 *  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 *  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *  Contact information for paper mail:
 *  Texas Instruments
 *  Post Office Box 655303
 *  Dallas, Texas 75265
 *  Contact information:
 *  http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
 *  DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
 *  ============================================================================
 *
 */
Was it helpful?

Solution

It looks like one way is

#include <mcheck.h>

mcheck_check_all();

The documentation isn't very detailed, but it seems that this mcheck.h is the glibc built-in checking that's already running during allocations.

OTHER TIPS

enabling debug info with -g causes more issues to be reported.

That is not how glibc heap corruption detection works.

Is there any way to call the glibc heap metadata consistency check manually

Yes: http://www.gnu.org/software/libc/manual/html_node/Heap-Consistency-Checking.html See also MALLOC_CHECK_ environment variable description.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top