简体   繁体   中英

simple shell in c - valgrind shows memorry leaks for sort command

I'm writing a simple shell in C that should support up to 2 pipes (I know that the implement for n pipes is shorter, but for some reason this is the specific request).

When checking for memory leaks with valgrind, I have no issues unless I'm using the sort command, for eg for "ls | sort" outputs the following message:

==4903== HEAP SUMMARY:
==4903==     in use at exit: 760 bytes in 17 blocks
==4903==   total heap usage: 65 allocs, 48 frees, 8,533,744 bytes allocated
==4903== 
==4903== 8 bytes in 1 blocks are definitely lost in loss record 1 of 6
==4903==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4903==    by 0x11ACFC: ??? (in /usr/bin/sort)
==4903==    by 0x10D72A: ??? (in /usr/bin/sort)
==4903==    by 0x48AE0B2: (below main) (libc-start.c:308)
==4903== 
==4903== 32 bytes in 1 blocks are indirectly lost in loss record 2 of 6
==4903==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4903==    by 0x11ACFC: ??? (in /usr/bin/sort)
==4903==    by 0x1166F6: ??? (in /usr/bin/sort)
==4903==    by 0x10D860: ??? (in /usr/bin/sort)
==4903==    by 0x48AE0B2: (below main) (libc-start.c:308)
==4903== 
==4903== 48 bytes in 12 blocks are still reachable in loss record 3 of 6
==4903==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4903==    by 0x11ACFC: ??? (in /usr/bin/sort)
==4903==    by 0x10C122: ??? (in /usr/bin/sort)
==4903==    by 0x48AE0B2: (below main) (libc-start.c:308)
==4903== 
==4903== 128 bytes in 1 blocks are still reachable in loss record 4 of 6
==4903==    at 0x483B723: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4903==    by 0x483E017: realloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4903==    by 0x11AD69: ??? (in /usr/bin/sort)
==4903==    by 0x10F0F2: ??? (in /usr/bin/sort)
==4903==    by 0x10DA99: ??? (in /usr/bin/sort)
==4903==    by 0x48AE0B2: (below main) (libc-start.c:308)
==4903== 
==4903== 512 bytes in 1 blocks are indirectly lost in loss record 5 of 6
==4903==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4903==    by 0x11ACFC: ??? (in /usr/bin/sort)
==4903==    by 0x10D89D: ??? (in /usr/bin/sort)
==4903==    by 0x48AE0B2: (below main) (libc-start.c:308)
==4903== 
==4903== 576 (32 direct, 544 indirect) bytes in 1 blocks are definitely lost in loss record 6 of 6
==4903==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4903==    by 0x11ACFC: ??? (in /usr/bin/sort)
==4903==    by 0x1166C7: ??? (in /usr/bin/sort)
==4903==    by 0x10D860: ??? (in /usr/bin/sort)
==4903==    by 0x48AE0B2: (below main) (libc-start.c:308)
==4903== 
==4903== LEAK SUMMARY:
==4903==    definitely lost: 40 bytes in 2 blocks
==4903==    indirectly lost: 544 bytes in 2 blocks
==4903==      possibly lost: 0 bytes in 0 blocks
==4903==    still reachable: 176 bytes in 13 blocks
==4903==         suppressed: 0 bytes in 0 blocks
==4903== 
==4903== For lists of detected and suppressed errors, rerun with: -s
==4903== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)

The above is the output after valgrind runs the sort , after valgrind runs ls the leak summary is:

==4904== LEAK SUMMARY:
==4904==    definitely lost: 0 bytes in 0 blocks
==4904==    indirectly lost: 0 bytes in 0 blocks
==4904==      possibly lost: 0 bytes in 0 blocks
==4904==    still reachable: 20,381 bytes in 9 blocks
==4904==         suppressed: 0 bytes in 0 blocks
==4904== 
==4904== For lists of detected and suppressed errors, rerun with: -s
==4904== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

which I can live with.

I've tried few different commands, with or without pipes - and again, the sort is the only one causing leaks.

When I'm exiting the program, valgrind outputs that there is no errors nor memory leaks but it's probably due to the exit(0) call at the end.

My questions are

  1. Could it be a valgrind issue with sort ?
  2. How can I debug this further more?

I double checked each free call in my program, and looked for similar problems on the web but couldn't find anything.

(The code will be updated if necessary)

UPDATE

Thanks to Bodo 's answer I found that my systems (Linux Mint 20 under VMware 16) sort does cause, or at least presents in valgrind, a memory leak. I used the ls | valgrind sort ls | valgrind sort suggestion in order to figure it out.

valgrind output:

==2966== HEAP SUMMARY:
==2966==     in use at exit: 760 bytes in 17 blocks
==2966==   total heap usage: 65 allocs, 48 frees, 8,533,744 bytes allocated
==2966== 
==2966== LEAK SUMMARY:
==2966==    definitely lost: 40 bytes in 2 blocks
==2966==    indirectly lost: 544 bytes in 2 blocks
==2966==      possibly lost: 0 bytes in 0 blocks
==2966==    still reachable: 176 bytes in 13 blocks
==2966==         suppressed: 0 bytes in 0 blocks

Yes, valgrind can report an issue in the /usr/bin/sort program.

Your shell probably uses fork to create a process (or processes) for the command(s) to be executed and then calls some exec.. function to execute the specified program. When the exec function is successful, the process no longer runs code of your shell but code of the other program.

If you instruct valgrind to check child processes, it will continue to trace the programs executed by your shell, so it will also report possible errors in these programs. Of course these errors are not related to your shell.

To confirm this you can compare the results of similar command lines, eg ls | sort ls | sort vs. ls | cat ls | cat .


Another way to confirm this would be to run sort with valgrind independently from your simple shell. You could try

ls | valgrind sort

If the mixed output of valgrind and the program you want to check is confusing, you could use valgrind 's option --log-file=<filename> option to redirect its output to a file.


As mentioned in Jabberwocky 's comment, to avoid checking any unrelated programs you can create your own (fake) programs that are free from memory leaks and memory access errors. To check for errors in your shell implementation it is not necessary that your replacement for sort actually sorts the lines. It is only important that it does not produce any errors/warnings from valgrind and maybe that it behaves similar to sort in a way that it reads data from stdin and writes data to stdout , optionally with a delay.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM