10

Can't pass valgrind test on pset4 speller (hashtable). The speller works perfectly but, I'm getting this message from valgrind:

==3911== 
==3911== HEAP SUMMARY:
==3911==     in use at exit: 32 bytes in 1 blocks
==3911==   total heap usage: 143,097 allocs, 143,096 frees, 8,023,448 bytes allocated
==3911== 
==3911== LEAK SUMMARY:
==3911==    definitely lost: 0 bytes in 0 blocks
==3911==    indirectly lost: 0 bytes in 0 blocks
==3911==      possibly lost: 0 bytes in 0 blocks
==3911==    still reachable: 32 bytes in 1 blocks
==3911==         suppressed: 0 bytes in 0 blocks
==3911== Reachable blocks (those to which a pointer was found) are not shown.
==3911== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==3911== 
==3911== For counts of detected and suppressed errors, rerun with: -v
==3911== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

I have check the places where I allocate memory 1) creating the hashtables and 2) opening the dictionary, but still there is a block reachable and to check for this I have done the following:

1) I placed a counter right next to malloc when creating the nodes for the hashtable and the counter shows 143091 for the large dictionary. Then I placed a counter within unload() to check how many nodes I free overthere and I get the same number 143091.

2) I checked that the fclose is placed correctly and should be executed without problem.

I just don't know where else to look.

here is my code to dictionary.c

[hid code]

6
  • I reading some old posts from a year ago, where they had a very similar problem and it was a problem with a bug in clang... could have this problem resurfaced? reddit.com/r/cs50/comments/8zdt5e/… – agraffe Jul 11 '19 at 21:16
  • Your code is fine. it does seem to be that clang bug from last year. I'll investigate with the team. – curiouskiwi Jul 11 '19 at 21:27
  • Thanks! @curiouskiwi I was going nuts with this... I'll wait for the fix. thanks for editing/erasing the code... just realized I shouldn't have post it. – agraffe Jul 11 '19 at 21:36
  • I hope it gets fixed soon as I really wanna submit this one – bishoy_smsm Jul 12 '19 at 9:22
  • same thing happening with me ??!! Is it fixed now?? – CeNiEi Jul 13 '19 at 22:16
13

This appears to be a clang bug that we are investigating. Will update once we know more.


UPDATE

We have changed check50 and submit50 so the 32-byte "leak" no longer happens.

We will be updating the Speller distribution Makefile as well. In the meantime, you can edit the Makefile to remove the -fsanitize flags (per Martino's answer below) to prevent the 'leak' when you are testing your own code.

Apologies for any inconvenience!

9
  • I am facing the same problem. Is the bug not fixed yet? – Devashish Sood Jul 14 '19 at 7:34
  • @DevashishSood I don't think so. I am also having the same issue. – Tanvir Ahmed Jul 14 '19 at 10:22
  • I hope it gets fixed soon – bishoy_smsm Jul 14 '19 at 23:49
  • I'm still facing too :( although I spent an entire day staring at my code and almost nothing is wrong ' still reachable: 32 bytes in 1 blocks' – Mohamed Rondoz Jul 15 '19 at 11:49
  • 1
    I made a little investigation on Makefile and found out that the bug appears only with any fsanitize flags in it. Hope this could somehow help. – Anastasy Korobetskaya Jul 15 '19 at 19:14
4

Following the hint by @anastasy-korobetskaya, I have arrived at this workaround. Sadly, it only helps to get rid of the problem in the IDE, not upon submission, but at least it should allow you to test your memory allocs and frees correctly.

Open the file Makefile. It should read:

speller:
    clang -fsanitize=signed-integer-overflow -fsanitize=undefined -ggdb3 -O0 -Qunused-arguments -std=c11 -Wall -Werror -Wextra -Wno-sign-compare -Wno-unused-parameter -Wno-unused-variable -Wshadow -c -o speller.o speller.c
    clang -fsanitize=signed-integer-overflow -fsanitize=undefined -ggdb3 -O0 -Qunused-arguments -std=c11 -Wall -Werror -Wextra -Wno-sign-compare -Wno-unused-parameter -Wno-unused-variable -Wshadow -c -o dictionary.o dictionary.c
    clang -fsanitize=signed-integer-overflow -fsanitize=undefined -ggdb3 -O0 -Qunused-arguments -std=c11 -Wall -Werror -Wextra -Wno-sign-compare -Wno-unused-parameter -Wno-unused-variable -Wshadow -o speller speller.o dictionary.o

Now remove the -fsanitize= parameters from all lines, then save the file. The resulting content should be

speller:
    clang  -ggdb3 -O0 -Qunused-arguments -std=c11 -Wall -Werror -Wextra -Wno-sign-compare -Wno-unused-parameter -Wno-unused-variable -Wshadow -c -o speller.o speller.c
    clang  -ggdb3 -O0 -Qunused-arguments -std=c11 -Wall -Werror -Wextra -Wno-sign-compare -Wno-unused-parameter -Wno-unused-variable -Wshadow -c -o dictionary.o dictionary.c
    clang  -ggdb3 -O0 -Qunused-arguments -std=c11 -Wall -Werror -Wextra -Wno-sign-compare -Wno-unused-parameter -Wno-unused-variable -Wshadow -o speller speller.o dictionary.o

Now recompile your solution by executing make speller. Then rerun it through valgrind. Voila, problem gone.

As said, this should allow you to debug your own code successfully. Warning: The submission will still fail because it will independently recompile the code using the default settings.

UPDATE:

As per staff fix, check50 and submit50 have been patched using the same workaround, so they will now work again. Hope this helps.

1
  • We'll be updating the distro code with this change as well. Thanks for posting the workaround. – curiouskiwi Jul 17 '19 at 20:02
1

I'm having the same problem, working on a speller with a trie. Just spent a few hours chasing it, and managed to isolate the issue by doing the following:

  1. Unzipping a new set of files for pset4 (to a new directory), then compiling (make speller), and executing valgrind --leak-check=full --show-leak-kinds=all ./speller. In this case, the program should just display the message "Usage: speller [dictionary] text" and exit. Yet valgrind shows "in use at exit: 32 bytes in 1 blocks".

  2. In another test, I have created a new file, test.c, containing the "Hello, world". When complied, that too generates the same report by valgrind, stating "still reachable" memory of 1 block and 32 bytes. My source code test.c:

    // Spell-checker mem test
    #include <stdio.h>

    int main(int argc, char *argv[])
    {

        printf("Hello world\n");
        // Success
        return 0;
    }

Valgrind output for ./test:

==16786== Memcheck, a memory error detector
==16786== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==16786== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==16786== Command: ./test
==16786== 
Hello world
==16786== 
==16786== HEAP SUMMARY:
==16786==     in use at exit: 32 bytes in 1 blocks
==16786==   total heap usage: 1 allocs, 0 frees, 32 bytes allocated
==16786== 
==16786== 32 bytes in 1 blocks are still reachable in loss record 1 of 1
==16786==    at 0x4C31B25: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16786==    by 0x5A3D7E4: _dlerror_run (dlerror.c:140)
==16786==    by 0x5A3D165: dlsym (dlsym.c:70)
==16786==    by 0x427E44: __interception::GetRealFunctionAddress(char const*, unsigned long*, unsigned long, unsigned long) (in /home/ubuntu/pset4/test/test)
==16786==    by 0x427DCB: __ubsan::InitializeDeadlySignals() (in /home/ubuntu/pset4/test/test)
==16786==    by 0x427F1C: __libc_csu_init (in /home/ubuntu/pset4/test/test)
==16786==    by 0x5E79B27: (below main) (libc-start.c:266)
==16786== 
==16786== LEAK SUMMARY:
==16786==    definitely lost: 0 bytes in 0 blocks
==16786==    indirectly lost: 0 bytes in 0 blocks
==16786==      possibly lost: 0 bytes in 0 blocks
==16786==    still reachable: 32 bytes in 1 blocks
==16786==         suppressed: 0 bytes in 0 blocks
==16786== 
==16786== For counts of detected and suppressed errors, rerun with: -v
==16786== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Concluding, I don't see how this "leak" could possibly be managed from within my own source code. Even when removing the reference to stdio.h and running an entirely empty main(), valgrind still keeps reporting the same.

Hope this helps. Anyone has any further ideas?

1
  • You're correct that it is not dependent on your code. As my reply said, it's a bug with the version of clang (and its flags) that we are now using. We are working on the best solution. – curiouskiwi Jul 17 '19 at 0:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .