4fa3d371f8a70bb89e7f6bdf95011c05b3dbc7d4 |
|
21-Jul-2013 |
philippe <philippe@a5019735-40e9-0310-863c-91ae7b9d1cf9> |
fix 321960 pthread_create() then alloca() causing invalid stack write errors Problem created by a discrepancy between the initial main stack anon segment, and the main stack registered in m_stacks.c Looking at some tracing; we see that there are two pages of stack: --9078:2:main tell tool about 0ffefff000-0fff000fff rw- The stack between the base and the current sp is marked as not accessible: --9078:2:main mark stack inaccessible 0ffefff000-0fff0004bf This is matching the aspacemgr view: --9078:1:aspacem 22: RSVN 0ffe801000-0ffeffefff 8380416 ----- SmUpper --9078:1:aspacem 23: anon 0ffefff000-0fff000fff 8192 rw--- (all the above is normal/as expected) However, the main stack is registered in m_stacks.c as having only one page: --9078:2:stacks register 0xFFF000000-0xFFF000FFF as stack 0 When the main stack is grown, m_stacks.c is informed by m_signals.c that the stack is grown. This is done by trapping the signal 11 when a not mapped page is accessed. However, the 2nd page does not cause a signal (as it is mapped). So, m_stacks.c still believes the main has one page stack. This then gives problems in the tracking of the SP and current_stack in m_stacks.c. Only one page was registered for the main stack, as the registration was done with values computed before possibly adding a page needed for the ABI redzone. The fix is to properly register the main stack with the size of the stack segment, once all aspects have been taken into account. With the fix, the stack is registered as: --31501:2:stacks register 0xFFEFFF000-0xFFF000FFF as stack 0 Another possible fix would be to always register the main stack with the full size of the aspacemgr stack segment (i.e. the anon+RSVN above) (idea is that this is similar to non main threads, for which the full thread stack is registered from the beginning, even if not fully used yet). The first fix was preferred, assuming it is better to keep registering the main stack "physical" size (and not its maximal size). Test memcheck/tests/thread_alloca added, based on reproducer done by Daniel Stodden. The bug might be triggered or not depending on the initial value of the SP, which is influenced by the size of the "env". So, the test execs itself, growing each time the environment. This has given a reasonable chance/way to reproduce the bug on Ubuntu 12 and on a Debian 6. (tested on amd64/Ubuntu 12 and Debian 6 x86/fedora12 ppc64/fedora18 Note that while investigating this bug, another strange thing was seen: thread stacks are registered in m_stacks.c but are never unregistered. It is not very clear that it is needed or not to unregister them: thread stack segments are not freed when a thread terminates : when a thread slot is re-used, its thread stack will also be re-used. (Is that good for address space mgt ? A process that has created many temporary threads will have the thread stacks lost forever ???). git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13467 a5019735-40e9-0310-863c-91ae7b9d1cf9
/external/valgrind/memcheck/tests/thread_alloca.c
|