[C] #XK3 Getting a "double free or corruption (out)" error

Link to my GitHub repo

This is the output I’m getting:

[tester::#XK3] Running tests for Stage #XK3 (Pipelines - Multi-command pipelines)
[tester::#XK3] [setup] export PATH=/tmp/blueberry/raspberry/pineapple:$PATH
[tester::#XK3] [setup] echo -e "mango\nblueberry\npineapple\npear\norange" > "/tmp/dog/file-73"
[tester::#XK3] Running ./your_program.sh
[your-program] $ cat /tmp/dog/file-73 | head -n 3 | wc
[your-program]        3       3      26
[tester::#XK3] ✓ Received expected output
[tester::#XK3] [setup] echo -n "orange" > "/tmp/pig/f-37"
[tester::#XK3] [setup] echo -n "grape" > "/tmp/pig/f-14"
[tester::#XK3] [setup] echo -n "pineapple" > "/tmp/pig/f-39"
[tester::#XK3] [setup] echo -n "mango" > "/tmp/pig/f-20"
[tester::#XK3] [setup] echo -n "banana" > "/tmp/pig/f-77"
[tester::#XK3] [setup] echo -n "pear" > "/tmp/pig/f-79"
[your-program] $ ls /tmp/pig | tail -n 5 | head -n 3 | grep "f-39"
[your-program] f-39
[your-program] double free or corruption (out)
[tester::#XK3] ^ Expected prompt ("$ ") but received "double free or corruption (out)"
[tester::#XK3] Assertion failed.
[tester::#XK3] Test failed

After taking a break from this challenge and coming back a day later, the error went away. I was able to complete the rest of the stages, but this error is now intermittently coming back and I’m not sure what is causing it.

K another update:

I ran the program through Valgrind and it helped me diagnose the issue and solve it. I’ll give a quick summary in case anyone else has a similar issue.

I followed Valgrind’s Quick Start Guide. Here is the error Valgrind gave me after running my program with it:

==9875== Invalid write of size 8
==9875==    at 0x10AA26: add_cmd_args (cmd_arg_parser.c:71)
==9875==    by 0x10D815: main (main.c:33)
==9875==  Address 0x4b0a0f0 is 0 bytes after a block of size 80 alloc'd
==9875==    at 0x484D953: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==9875==    by 0x10A74E: create_args_obj (cmd_arg_parser.c:16)
==9875==    by 0x10D7B2: main (main.c:25)

I created a struct to hold the arguments I parsed from the command-line (create_args_obj), but I set the initial size of the args array to hold 10 arguments:

Args *ao = (Args *)malloc(sizeof(Args));
ao->size = 0;
ao->capacity = 10;
ao->args = (char **)calloc(ao->capacity, sizeof(char *));

In add_cmd_args, I wasn’t doing a bounds-check to make sure that ao→size wasn’t about to reach the capacity, and if so, resize ao→args. As a result, when my program tried parsing the following line from the test:

ls /tmp/pig | tail -n 5 | head -n 3 | grep "f-39"
 |     |    |   |   | | |  |    | | |  |     |
 |     |    |   |   | | |  |    | | |  |     |
 *     *    *   *   * * *  *    * * |  |     *
 1     2    3   4   5 6 7  8    9 10 \  *    13
                                      *  12
                                      11  

it was parsing more than 10 arguments without resizing ao→args and would corrupt memory by writing out-of-bounds. I added the following bounds-check to add_cmd_args:

if (ao->size + 1 >= ao->capacity) {
      expand_args_array(ao);
    }
ao->args[ao->size++] = received_arg;

and it worked out.

2 Likes

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.