Summary: | Enhance valgrind to supress unfreed stderr. | ||
---|---|---|---|
Product: | [Developer tools] valgrind | Reporter: | Carlos O'Donell <carlos> |
Component: | general | Assignee: | Julian Seward <jseward> |
Status: | REPORTED --- | ||
Severity: | wishlist | CC: | mark, tom |
Priority: | NOR | ||
Version: | 3.15 SVN | ||
Target Milestone: | --- | ||
Platform: | Fedora RPMs | ||
OS: | Linux | ||
See Also: | https://sourceware.org/bugzilla/show_bug.cgi?id=26022 | ||
Latest Commit: | Version Fixed In: | ||
Sentry Crash Report: |
Description
Carlos O'Donell
2020-05-22 20:05:48 UTC
Which process shutdown steps do you expect to run during or after __libc_freeres is called? __libc_freeres as used by valgrind should be the last "user code" running, no other threads should be scheduled. It is called after all user threads are "dead". And after __libc_freeres has ran only the valgrind (tool) code will run (which doesn't use glibc code). So at least from the perspective of valgrind __libc_freeres can release all resources. (In reply to Mark Wielaard from comment #1) > Which process shutdown steps do you expect to run during or after > __libc_freeres is called? Any detached thread may write to the stream until the kernel kills the task. > __libc_freeres as used by valgrind should be the last "user code" running, > no other threads should be scheduled. It is called after all user threads > are "dead". And after __libc_freeres has ran only the valgrind (tool) code > will run (which doesn't use glibc code). How do you wait for detached threads? > So at least from the perspective of valgrind __libc_freeres can release all > resources. So from your perspective at this point, even detached threads, can expect to have the streams shutdown? (In reply to Carlos O'Donell from comment #2) > (In reply to Mark Wielaard from comment #1) > > Which process shutdown steps do you expect to run during or after > > __libc_freeres is called? > > Any detached thread may write to the stream until the kernel kills the task. > > > __libc_freeres as used by valgrind should be the last "user code" running, > > no other threads should be scheduled. It is called after all user threads > > are "dead". And after __libc_freeres has ran only the valgrind (tool) code > > will run (which doesn't use glibc code). > > How do you wait for detached threads? > > > So at least from the perspective of valgrind __libc_freeres can release all > > resources. > > So from your perspective at this point, even detached threads, can expect to > have the streams shutdown? What is a "detached thread" according to you? There is no concept of detached threads in valgrind, all threads are under control of valgrind and valgrind makes sure that only one (kernel) thread is scheduled to run at any one time. See https://valgrind.org/docs/manual/manual-core.html#manual-core.pthreads A detached thread in pthreads is one that is no longer being supervised and which will vanish when it completes rather than waiting to be reaped (joined in pthreads terminology) by another thread. The situation under valgrind is as you say rather different though in that even if pthreads has forgotten about the thread valgrind hasn't. (In reply to Mark Wielaard from comment #3) > What is a "detached thread" according to you? There is no concept of > detached threads in valgrind, all threads are under control of valgrind and > valgrind makes sure that only one (kernel) thread is scheduled to run at any > one time. See > https://valgrind.org/docs/manual/manual-core.html#manual-core.pthreads If you use ptrace under the hood to stop a pthread detached thread, and therefore terminate it, then yes, there will be nothing else using the streams. If that's the case, and we feel comfortable with that as a position then I can flip this back to glibc and discuss *always* shutting down streams via __libc_freeres regardless of their state? (In reply to Carlos O'Donell from comment #5) > (In reply to Mark Wielaard from comment #3) > > What is a "detached thread" according to you? There is no concept of > > detached threads in valgrind, all threads are under control of valgrind and > > valgrind makes sure that only one (kernel) thread is scheduled to run at any > > one time. See > > https://valgrind.org/docs/manual/manual-core.html#manual-core.pthreads > > If you use ptrace under the hood to stop a pthread detached thread, and > therefore terminate it, then yes, there will be nothing else using the > streams. > > If that's the case, and we feel comfortable with that as a position then I > can flip this back to glibc and discuss *always* shutting down streams via > __libc_freeres regardless of their state? Even if we did enhance glibc, there is a need for all existing distributions that have unbuffered stderr which won't be freed by __libc_freeres(). (In reply to Carlos O'Donell from comment #5) > (In reply to Mark Wielaard from comment #3) > > What is a "detached thread" according to you? There is no concept of > > detached threads in valgrind, all threads are under control of valgrind and > > valgrind makes sure that only one (kernel) thread is scheduled to run at any > > one time. See > > https://valgrind.org/docs/manual/manual-core.html#manual-core.pthreads > > If you use ptrace under the hood to stop a pthread detached thread, and > therefore terminate it, then yes, there will be nothing else using the > streams. > > If that's the case, and we feel comfortable with that as a position then I > can flip this back to glibc and discuss *always* shutting down streams via > __libc_freeres regardless of their state? We don't use ptrace under the hood, we control all kernel threads. From the perspective of glibc valgrind provides the kernel interface. Valgrind core doesn't use glibc itself. From the perspective of valgrind glibc is just like any other code the process executes. With some exceptions, we intercept some glibc functions, most specifically __libc_freeres. That function is called after the process exits (from glibc's perspective). We should probably make sure there are no other users of __libc_freeres, or if there are, that they use it in the same way. So it seems a good idea to put this back to glibc. (In reply to Mark Wielaard from comment #7) > (In reply to Carlos O'Donell from comment #5) > > (In reply to Mark Wielaard from comment #3) > > > What is a "detached thread" according to you? There is no concept of > > > detached threads in valgrind, all threads are under control of valgrind and > > > valgrind makes sure that only one (kernel) thread is scheduled to run at any > > > one time. See > > > https://valgrind.org/docs/manual/manual-core.html#manual-core.pthreads > > > > If you use ptrace under the hood to stop a pthread detached thread, and > > therefore terminate it, then yes, there will be nothing else using the > > streams. > > > > If that's the case, and we feel comfortable with that as a position then I > > can flip this back to glibc and discuss *always* shutting down streams via > > __libc_freeres regardless of their state? > > We don't use ptrace under the hood, we control all kernel threads. From the > perspective of glibc valgrind provides the kernel interface. Valgrind core > doesn't use glibc itself. From the perspective of valgrind glibc is just > like any other code the process executes. With some exceptions, we intercept > some glibc functions, most specifically __libc_freeres. That function is > called after the process exits (from glibc's perspective). We should > probably make sure there are no other users of __libc_freeres, or if there > are, that they use it in the same way. So it seems a good idea to put this > back to glibc. There are other users of __libc_freeres(), particularly mtrace, which frees everything in a destructors, but that problably makes such code incompatible with valgrind and that's OK. Let me note, that even if we fix it in glibc, that is to say that we decree that all streams, buffered or unbuffered, are freed, there is going to be old glibc's and applications that use stderr (unbuffered) and allocate a buffer (possibly a 20 year old glibc bug) that is not freed. I leave it up to you to decide if you want to supress an unfreed stderr that will always show up when using stderr. I'll see about fixing it in glibc. |