2trill2spill
2trill2spill

Reputation: 1383

passing pointer to function corrupts pointer

I'm passing a pointer to a typedef struct to a function that is suppose to set up the typedef struct for use. The struct is already malloced before it is passed to the function. Upon accessing the struct within the function I receive EXC_BAD_ACCESS. The thing I don't understand is, the value of the typedef struct called pool is valid in the previous function, but as soon as it's passed it's not valid. This can be seen in the backtrace below. While researching the problem I've seen similar problems but those were due to passing a copy of the variable to the function instead of a pointer, or because the variable was a local variable and it went out of scope when the function exited. I don't believe these are the problems because the function that declared and malloced pool has not exited yet, and I am passing a pointer to pool not a copy of pool. So how come pool becomes NULL after passing it to initNamePool?

Backtrace, here you can see that pool was valid in "initResourcePool" and "initPools" but not "initNamePool"

(lldb) thread backtrace
* thread #1: tid = 0x53998, 0x000000010000325b sysfuzz`initNamePool(pool=0x0000000000000000) + 27 at namePool.c:201, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x4020)
  * frame #0: 0x000000010000325b sysfuzz`initNamePool(pool=0x0000000000000000) + 27 at namePool.c:201
    frame #1: 0x0000000100002cf5 sysfuzz`initPools(pool=0x00000001003eafe0) + 37 at pool.c:51
    frame #2: 0x0000000100002c80 sysfuzz`initResourcePool(pool=0x00000001003eafe0) + 48 at pool.c:87
    frame #3: 0x0000000100001830 sysfuzz`initSysFuzz(data=0x00000001003d4fd0) + 48 at interactor.c:19
    frame #4: 0x00000001000017ba sysfuzz`initAndRunSysFuzz + 58 at interactor.c:103
    frame #5: 0x0000000100001599 sysfuzz`main + 25 at start.c:12
    frame #6: 0x00007fff956395c9 libdyld.dylib`start + 1
    frame #7: 0x00007fff956395c9 libdyld.dylib`start + 1

The Definition of data->pool->nPool and getDirName

static int getDirName(char **dir, namePool *pool)
{
    poolArgs *args;

    args = (poolArgs *) malloc(sizeof(poolArgs));
    if(args == NULL)
    {
        return -1;
    }

    launchSynch(pool->serialQueue, gdn, &args);

    dir = args->dir;

    free(args);

    return 0;
}

typedef struct namePool namePool;

struct namePool
{
    char *fileNameIndex[1025];
    char *dirNameIndex[1025];
    queue serialQueue;

    int (*getFileName)(char **, namePool *);
    int (*getDirName)(char **, namePool *);
    int (*fillPool)(namePool *);
    int (*drainPool)(namePool *);
    bool isPoolDrained;
};

Here we declare data which is a typedef struct that holds pool. Both get malloced in "initFuzzData".

int initAndRunSysFuzz()
{
    /* Declarations. */
    int rtrn;
    fuzzData *data;

    data = initFuzzData();
    if(data == NULL)
    {
        return -1;
    }

    rtrn = initSysFuzz(data);
    if(rtrn < 0)
    {
        cleanUpFuzzData(data);
        return -1;
    }

    ...
}

fuzzData *initFuzzData()
{
    fuzzData *data;

    data = (fuzzData *) malloc(sizeof(fuzzData));
    if(data == NULL)
    {
        return NULL;
    }

    data->pool = (resourcePool *) malloc(sizeof(resourcePool));
    if(data->pool == NULL)
    {
        return NULL;
    }

    data->pool->nPool = (namePool *) malloc(sizeof(namePool));
    if(data->pool->nPool == NULL)
    {
        return NULL;
    }

    ...
}

After we malloc data and data->pool and we pass data to "initSysFuzz"

static int initSysFuzz(fuzzData *data)
{

    int rtrn;

    rtrn = initResourcePool(data->pool);
    if(rtrn < 0)
    {
        return -1;
    }

    ...
}

"initSysFuzz" calls "initResourcePool"

int initResourcePool(resourcePool *pool)
{

    int rtrn;

    rtrn = initPools(pool);
    if(rtrn < 0)
    {
        printf("Can't Init Pools\n");
        return -1;
    }
    ...
}

Which in turn calls "initPools"

static int initPools(resourcePool *pool)
{
    int rtrn;

    rtrn = initNamePool(pool->nPool);
    if(rtrn < 0)
    {
        printf("Can't init name pool\n");
        return -1;
    }

    ....
}

And here is where it crashes, on the first line of "initNamePool", pool->getDirName = &getDirName; .

int initNamePool(namePool *pool)
{
    pool->getDirName = &getDirName;

...

}

Upvotes: 0

Views: 190

Answers (1)

Armali
Armali

Reputation: 19395

I found it by printing the addresses, I had malloced pool twice in initFuzzData. – 2trill2spill

Upvotes: 1

Related Questions