0

First of all, I'm running in C on a Windows 32 bit system compiled with Visual Studio 2008. I'm running in debug mode. My code essentially is this:

execvp( *argv, argv );

Where argv has three entries and looks like this:

argv[0] = "pgserv";
argv[1] = "pgserv";
argv[2] = NULL;

Yes, I am aware that that calls the pgserv application with pgserv as an argument, but that works fine from the command line and is sort of an artifact of the framework this is a part of.

Anyway, when this line is hit, it triggers this assert in dbgheap.c/_free_dbg_nolock()

_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));

Top of the call stack:

hub.exe!_free_dbg_nolock(void * pUserData=0x024c1408, int nBlockUse=1)  Line 1323 + 0x54 bytes  C++
hub.exe!_free_dbg(void * pUserData=0x024c1408, int nBlockUse=1)  Line 1258 + 0xd bytes  C++
hub.exe!free(void * pUserData=0x024c1408)  Line 49 + 0xb bytes  C++
hub.exe!_execve(const char * name=0x02523a10, const char * const * argv=0x02514e38, const char * const * envp=0x00000000)  Line 322 + 0x8 bytes C
hub.exe!_execvpe(const char * filename=0x02523a10, const char * const * argvector=0x02514e38, const char * const * envptr=0x00000000)  Line 87 + 0xc bytes  C
hub.exe!_execvp(const char * filename=0x02523a10, const char * const * argvector=0x02514e38)  Line 47 + 0xd bytes   C
hub.exe!execmd(char * cmd=0x02523a10)  Line 25 + 0xf bytes  C

I'm completely at a loss as to why I'd be getting this assert here as I believe I'm calling execvp() correctly and this code is called quite frequently with differing argv's successfully. Any ideas/help as to what my problem is? Thanks.

Morinar
  • 3,460
  • 8
  • 40
  • 58
  • It looks like you're not null terminating your `argv` array. Or is that just left out of your example? – Carl Norum Aug 18 '10 at 21:08
  • I am, it's left out in the example. Updating question. – Morinar Aug 18 '10 at 21:11
  • @Morinar - Just a bit too late. – Kevin Vermeer Aug 18 '10 at 21:19
  • 3
    Heap corruption elsewhere? When did `0x024c1408` (the block being free'd) get allocated in your application? It doesn't seem to have anything to do with the arguments to execvp. – Aidan Cully Aug 18 '10 at 21:19
  • Heap corruption does seem to be a likely culprit. I can't fathom why `execvp` would be freeing any resources that you allocated. That suggests that it must be resources that it allocates internally, which in turn suggests that the problem is a corrupted heap, not an error on the allocation itself. – torak Aug 18 '10 at 21:28
  • Good advice, I'll poke around some more. – Morinar Aug 18 '10 at 21:31
  • You mention "exactly two entries". Does the array really have 2 or do you mean it has 3 entries? Because you're assigning to the 3rd slot with that NULL terminator. – bstpierre Aug 18 '10 at 22:16
  • It's three, I just forgot to mention the NULL in the original question. ARGV is allocated correctly and structured as it should be. It's created by calling code we've been using for 20+ years. – Morinar Aug 18 '10 at 22:18
  • I think that if you `malloc` and then `free` a memory block immediately prior to calling `execvp` it should confirm whether or not there is heap corruption. Either that or I believe there is a heap check function. – torak Aug 18 '10 at 23:52

2 Answers2

2

A failure in free typically means one of two things: either you're trying to free a pointer that you didn't obtain from malloc (or that you've already freed), or the heap has become corrupted. Since the free is coming from the system library, odds are that your code has corrupted the heap earlier, and the memory allocation system has only just noticed.

Since you're already in a debugger, look what object was shortly before 0x024c1408. You probably overflowed a buffer there. (Of course, you may already have freed the offending object before calling execvp, in which case the bug could be hard to track down.)

Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
  • `0x024c1408` was allocated in `_execve()` and the bytes right before aren't anything obvious. Back another 10 or so appears to be also allocated by `_execve()` (it's the first permutation of pgserv + exension). Not sure that tells me much of anything... – Morinar Aug 18 '10 at 21:49
  • @Morinar: also check near `pHead` (from the failed assert), maybe the corrupted data structure is not around the argument of `free` but some other place where `free` or `_free_dbg` looks. If this still fails, try tools mentioned at http://stackoverflow.com/questions/413477 or other similar questions. – Gilles 'SO- stop being evil' Aug 18 '10 at 21:56
  • No idea what is going on here, but I eventually figured out that I was "doing it wrong" in relationship to our framework. I'd give you the details, but they are VERY specific to our app. Something still seems amiss here though, and it probably is heap corruption. Going to accept this. – Morinar Aug 18 '10 at 22:42
0

Is argv properly null terminated? From the docs, "The array of pointers must be terminated by a NULL pointer":

const char* args[] =  {"pgserv", "pgserv", NULL};

then call it with

execvp(args[0], args)

When you call it with only the first two parameters defined, ask yourself, "How can execvp determine the end of the list of strings?" The answer is that it looks for two NULLs in a row, which you're not providing.

Kevin Vermeer
  • 2,736
  • 2
  • 27
  • 38