Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalid free() on exit (32-bit build under valgrind) #10982

Closed
garrison opened this issue Apr 24, 2015 · 10 comments · Fixed by #11422
Closed

Invalid free() on exit (32-bit build under valgrind) #10982

garrison opened this issue Apr 24, 2015 · 10 comments · Fixed by #11422
Labels
system:32-bit Affects only 32-bit systems

Comments

@garrison
Copy link
Member

It seems that julia attempts to call free(0xffffffff) on exit when built for 32 bits:

$ valgrind --smc-check=all-non-file ./julia -e ""
==25616== Memcheck, a memory error detector
==25616== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==25616== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==25616== Command: ./julia -e 
==25616== 
==25616== Invalid free() / delete / delete[] / realloc()
==25616==    at 0x402A3A8: free (vg_replace_malloc.c:473)
==25616==    by 0x52ADBF4: __libc_freeres (in /lib/i386-linux-gnu/i686/cmov/libc-2.19.so)
==25616==    by 0x4023536: _vgnU_freeres (vg_preloaded.c:63)
==25616==    by 0x521CA5D: _Exit (_exit.S:29)
==25616==  Address 0xffffffff is not stack'd, malloc'd or (recently) free'd
==25616== 
==25616== 
==25616== HEAP SUMMARY:
==25616==     in use at exit: 42,884,254 bytes in 346,643 blocks
==25616==   total heap usage: 428,248 allocs, 81,606 frees, 58,625,310 bytes allocated
==25616== 
==25616== LEAK SUMMARY:
==25616==    definitely lost: 872 bytes in 4 blocks
==25616==    indirectly lost: 2,048 bytes in 1 blocks
==25616==      possibly lost: 293,182 bytes in 8,349 blocks
==25616==    still reachable: 42,588,152 bytes in 338,289 blocks
==25616==         suppressed: 0 bytes in 0 blocks
==25616== Rerun with --leak-check=full to see details of leaked memory
==25616== 
==25616== For counts of detected and suppressed errors, rerun with: -v
==25616== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

Make.user is as follows:

CFLAGS = -DMEMDEBUG
ARCH = i686

In fact, I can reproduce this both with and without MEMDEBUG. I am running Debian jessie (64 bits).

@pao
Copy link
Member

pao commented Apr 24, 2015

It would be nice if the stack trace actually pointed somewhere outside libc and libgcc.

@garrison
Copy link
Member Author

@pao, naturally :)

I can also reproduce if I modify ui/repl.c to contain only int main() { return 0; }, so I expect this may be an issue with something we are linking against (which may or may not be libjulia). I also tried compiling some trivial programs with similarish CFLAGS (but without linking to anything julia-related), and was unable to reproduce this warning.

I will try to bisect this when I get a chance.

@JeffBezanson JeffBezanson added the system:32-bit Affects only 32-bit systems label Apr 24, 2015
@garrison
Copy link
Member Author

This seems to be at least as old as v0.3.0. At some point I was unable to go back further in time because gcc-4.9 and older versions of pcre do not cooperate, and my gcc-4.8 is not set up to do multilib correctly at the moment.

@tkelman
Copy link
Contributor

tkelman commented Apr 25, 2015

Does the patch from #7511 help?

@garrison
Copy link
Member Author

I managed to get my gcc-4.8 multiarch environment working, so I'll just use that unless I have further issues.

@garrison
Copy link
Member Author

OK, my multiarch environment had a difficult time compiling older versions, so I decided to try a different type of "bisect".

I set ui/repl.c to contain only int main() { return 0; }, which gave me freedom to adjust the linker flags at will and see what happened.

Here's the original link command:

g++ -march=i686 -m32 -pipe -fPIC -fno-rtti   -O3 -ggdb3 -falign-functions -momit-leaf-frame-pointer -I/home/garrison/julia32/src -I/home/garrison/julia32/src/support -I/home/garrison/julia32/usr/include -Wall -Wno-strict-aliasing -fno-omit-frame-pointer repl.o -o /home/garrison/julia32/usr/bin/julia -L/home/garrison/julia32/usr/lib/julia -L/home/garrison/julia32/usr/lib -L/home/garrison/julia32/usr/lib -Wl,-Bdynamic  -Wl,--no-whole-archive -ldl -lrt -lpthread -Wl,--export-dynamic -Wl,--no-whole-archive /home/garrison/julia32/usr/lib/libunwind-generic.a /home/garrison/julia32/usr/lib/libunwind.a -Wl,--version-script=/home/garrison/julia32/src/julia.expmap  -Wl,-rpath,'$ORIGIN/../lib/julia' -Wl,-rpath,'$ORIGIN/../lib' -Wl,-z,origin

If I remove -Wl,--version-script=/home/garrison/julia32/src/julia.expmap, the "invalid free" goes away.

@garrison
Copy link
Member Author

garrison commented May 1, 2015

Turns out, __libc_freeres is a clean-up handler that is only called when a program is running under valgrind. It's certainly possible that this invalid read could be a benign problem with some underlying piece of infrastructure, though it does seem strange that libc would be holding on to a pointer to 0xffffffff for some internal use.

@garrison
Copy link
Member Author

Adding _IO_stdin_used to julia.expmap fixes the problem. Go figure.

@tkelman
Copy link
Contributor

tkelman commented May 22, 2015

Would that hurt anything to add everywhere?

@Keno
Copy link
Member

Keno commented May 22, 2015

No, that should be fine.

tkelman added a commit that referenced this issue May 24, 2015
mbauman pushed a commit to mbauman/julia that referenced this issue Jun 6, 2015
tkelman added a commit to tkelman/julia that referenced this issue Jun 6, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
system:32-bit Affects only 32-bit systems
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants