0

So, I'm malloc()ating a variable, something like this in a function in C:

char * foo;
foo = (char *)malloc(32 * sizeof(char) +1);

// some irrelevant (to the variable) code

function2(&foo);
free(foo);

And then, I copy a string into foo in function2():

void function2(char ** foo)
{
    // Some more (presumably) irrelevant code

    strcpy(*foo, "asdf");
}

This is part of a much bigger project (a compiler). I wasn't able to reproduce this problem in a standalone C program, but stripping many of the variable dependencies, the above code seems ok.

My problem is, that the call to strcpy causes a segfault 95% of the times (undefined behaviour the rest).

Following the execution with gdb, I found that, up to this moment I can print foo and see an empty string:

(gdb) s
1445        // line of code right before call to strcpy()
(gdb) print *foo 
$18 = 0x6064c0 ""
(gdb) s
1455        strcpy(*foo, "asdf");
(gdb)

However, right before strcpy() is called, print *foo gets me a $19 = 0x2a00000002 <error: Cannot access memory at address 0x2a00000002> and right after, most of the timesstrcpy() will throw the SegFault, or the string will be corrupted and cause the next strcpy() to throw the SegFault. Corruption is also random, as sometimes the pointer address will be intact (with gibberish characters), but sometimes 0x0. The program may, occasionally, mess with other strings too, right at that point.

What causes that? Is *foo supposed to be freed before the call? Probably not. Could some other piece of code mess with its memory?

The strings seem to be properly allocated. I also tried with calloc(), allocating right before the strcpy() call, different buffer sizes, copying "\0"s and copying from other buffers. Printing *foo, right after strcpy(), sometimes prints random gibberish, sometimes exactly what I expect it, and sometimes nothing at all.

EDIT #1:

I was only able to quantify it to this:

Removing the strcpy() call in function2(), I see on gdb that the *foo variable has an address and value ("" @ 0x606420), but as soon as the function call returns, the pointer in the main function, points to 0x0 and that makes the next call to strcpy() SegFault.

Trying to emulate the problematic function2() doesn't work. The code in function2(), while extensive, does not touch, at any moment, the parameter(after removing strcpy(), of course).

ShadoWalkeR
  • 123
  • 1
  • 8
  • 2
    Please show a minimal compilable example of this. You're doing something wrong somewhere else, the bug is not in the code here. Also make sure you've included stdlib.h, – nos Apr 18 '15 at 23:29
  • @nos I would. But I'd have to send you half the compiler. Eliminating ALL of `*foo`'s dependencies brings us to this code here. I'll try to add an Edit, with simpler code. stdlib.h is included, as well as string.h. The program compiles with no warnings with `-Wall`. – ShadoWalkeR Apr 18 '15 at 23:39
  • 1
    Probably not related to your problem, but note that you should NOT cast the return value of `malloc()`. See http://stackoverflow.com/a/605858/3488231 – user12205 Apr 18 '15 at 23:40
  • 3
    If you have a problem, please post a complete compilable sample that demonstrates the problem. One pointer and one function is not too much to ask. But your code is *"something like this"* and omits code that you think is "irrelevant" even though you don't know what the problem is. – Weather Vane Apr 18 '15 at 23:48
  • 5
    (Irrelevant code) is corrupting the stack/heap. Compile with -O0 -g and use valgrind or similar runtime analyzer. – user3125367 Apr 19 '15 at 00:03
  • @user3125367 Interesting. I'll try that. I'll edit if I find anything. – ShadoWalkeR Apr 19 '15 at 00:22
  • Your bug is likely stack or heap corruption elsewhere in your code. On Linux, go run [Valgrind](http://valgrind.org/info/tools.html) using its memcheck tool. On Windows, you can use [AppVerifier](https://msdn.microsoft.com/en-us/library/windows/desktop/dd371695%28v=vs.85%29.aspx) to find similar bugs. – selbie Apr 19 '15 at 00:25
  • @selbie Yes, it probably is. I used Valgrind's memcheck, fixed a couple of issues with some pointers, the problem is still there. Valgrind shows `Use of uninitialised data` and `invalid read of size 1` which are effects of the pointer = `0x0`, and then the SIGSEGV. I'm not exactly familiar with valgrind. Is there any way I could find what is causing that pointer to equal 0x0? – ShadoWalkeR Apr 19 '15 at 01:31
  • If `valgrind` says you're reading through a zero pointer, aka NULL, then there are two main possibilities. (1) At the time when you make that call to your `function2()`, the value in `*foo` is a null pointer, and you need to look at the code between the `malloc()` and the call to work out what's going astray, or (2) the code inside `function2()` is causing the pointer to be nullified. Clearly, adding `fprintf(stderr, "-->> %s: *foo = %p\n", __func__, *foo);` would help you distinguish between (1) and (2). Or you can put a breakpoint on the function in the debugger and print the value on entry. – Jonathan Leffler Apr 19 '15 at 02:25
  • You can add more similar print operations between the point where you last find that `*foo` is not null and when it turns up as null. Did the irrelevant code after the `malloc()` include a check that `malloc()` succeeded? If not, you should add one, and handle failure appropriately. – Jonathan Leffler Apr 19 '15 at 02:26
  • 1
    I found what was wrong. While the code was good, I used an older version header file for some of the functions, were `function2()`s old prototype was without parameters, as opposed to it's definition. Found out because, `gcc` was silent with a `char * (32)` as a parameter instead of `char **` – ShadoWalkeR Apr 19 '15 at 03:28
  • @ShadoWalkeR Post your own answer and accept it to complete this post. – chux - Reinstate Monica Apr 19 '15 at 13:09
  • 1
    Empty arglist means default argument widths will be applied. Passed &foo and accepted char** are the same types. No char vs int, int vs long or similar incompatibilities. Are you sure old-style declaration was an actual issue? – user3125367 Apr 19 '15 at 16:41
  • @user3125367 I thought the same about OP's solution and would like to see OP post the solution. – chux - Reinstate Monica Apr 19 '15 at 18:33

0 Answers0