understanding double free errors

Hi Experts,

I am trying to understand how to analyze a double free error. I have the following simple code.  When it crashed, I collected the core dump.

#include <stdio.h>
#include <stdlib.h>


void doubleFree()
{
	char *p = (char *)malloc(1);
	free(p);

	free(p);
}


int main(int argc, char **argv)
{

	doubleFree();

	return 0;
}

Open in new window


When I loaded the core dump into GDB, I have the followings.  I am wondering why gdb was not able to find symbols for frame 2 and 3.  

(gdb) bt
#0  0x0103c75c in SyncCtl () from libc.so.3
#1  0x0102cc58 in rename (old=<optimized out>, new=0xff604 "
    at /builds/Trunk-Worldbuild/latest/svn/lib/c/ansi/rename
#2  0x4143535e in ?? ()
#3  0x4143535e in ?? ()
Backtrace stopped: previous frame identical to this frame (c
(gdb) info registers
r0             0x0      0
r1             0x11be09f        18604191
r2             0x1      1
r3             0x6      6
r4             0x0      0
r5             0x0      0
r6             0x107f53c        17298748
r7             0x1077d80        17268096
r8             0x10778c4        17266884
r9             0x103120 1061152
r10            0x430    1072
r11            0xff604  1046020
r12            0x1a     26
sp             0xff544  0xff544
lr             0x102cc58        16960600
pc             0x103c75c        0x103c75c <SyncCtl+8>
cpsr           0x60000010       1610612752
(gdb) info sharedlibrary
From        To          Syms Read   Shared Object Library
                        No          libmq.so.1
                        No          libnspinoverride.so
                        No          libmmapoverride.so
                        No          libbps.so.1
0x01000000  0x01080330  Yes         libc.so.3
                        No          libscreen.so.1
0x7800a000  0x7800f0f0  Yes         libpps.so.1
0x78050000  0x78076d1c  Yes         libm.so.2
ambuliAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Duncan RoeSoftware DeveloperCommented:
You would do much better to gdb your little program, and analyse the backtrace &c. when it gets the signal.
The output you posted does not look like your program at all. Supposing your program is called myprog and it dumps the file core (use ls -ltr to verify this - it may dump core.pid), then you need to either
gdb myprog core

Open in new window

or
gdb myprog
core core

Open in new window

Actually, looking again at the output you posted, I really think you must have happened on a really old core file. I don't remember libc.so.3 but I still have libc.so.4 (last updated 1995). libc.so.6 has been current since before the turn of the century.
Have another go and see how you get on - Good Luck!
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Duncan RoeSoftware DeveloperCommented:
I think modern libc recognises double-free and raises a signal. Older libc would simply trash the storage arena, but you wouldn't get a signal until (could be much) later in the program when another malloc() trips up on the mess.
0
tampnicCommented:
Easiest way to avoid double-free problems is to assign any pointer to NULL just after the allocation is free'd - freeing a NULL pointer is a no-op and shouldn't cause an error when the second attempt is made.

This leaves you with the scenario where you still have a logical error in the code, as you would usually be expecting the pointer to be pointing to something when you free it, but at least it won't terminate the program unexpectedly. I usually wrap a free call inside a null check anyway.

Something like:

void doubleFree()
{
	char *p = (char *)malloc(1);
	/* more code */
	free(p);
	p = NULL;
	/* more code */
	if ( p != NULL ) {
		free(p);
	} else {
		logmessage("Attempt to free a null pointer in doubleFree etc etc");
	}
}

Open in new window


Cheers,
  Chris
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C

From novice to tech pro — start learning today.