Bug 256043 - massif (update_stack_stats): Assertion 'stacks_szB >= -stack_szB_delta' failed.
Summary: massif (update_stack_stats): Assertion 'stacks_szB >= -stack_szB_delta' failed.
Status: REPORTED
Alias: None
Product: valgrind
Classification: Developer tools
Component: massif (show other bugs)
Version: unspecified
Platform: Debian unstable Linux
: NOR normal
Target Milestone: ---
Assignee: Nicholas Nethercote
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-11-04 12:58 UTC by Christian Borntraeger
Modified: 2011-01-18 09:31 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In:


Attachments
testcase (391 bytes, text/x-csrc)
2010-11-04 12:58 UTC, Christian Borntraeger
Details
possible fix for x86 (895 bytes, patch)
2011-01-18 09:31 UTC, Christian Borntraeger
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Christian Borntraeger 2010-11-04 12:58:22 UTC
Created attachment 53126 [details]
testcase

Version:           unspecified
OS:                Linux

The attached test case triggers the following assertion failure with
--tool=massif --stacks=yes :

Massif: ms_main.c:1926 (update_stack_stats): Assertion 'stacks_szB >= -stack_szB_delta' failed.
==13802==    at 0x38006C05: report_and_quit (m_libcassert.c:191)
==13802==    by 0x38006DD7: vgPlain_assert_fail (m_libcassert.c:265)
==13802==    by 0x38000E24: update_stack_stats (ms_main.c:1926)
==13802==    by 0x3800398A: die_mem_stack (ms_main.c:1949)
==13802==    by 0x38019B53: vgPlain_unknown_SP_update (m_stacks.c:322)
==13802==    by 0x4FFB8FE: ???

The problem happens, if m_sigframe creates a signal frame, but the user code returns with longjmp.
Turns out that there is a real problem in the code:
m_sigframe will increase the stack size by
sizeof(frame) + ALIGNMENT done by VG_ROUNDDN:

[...]
   esp -= sizeof(*frame);
   esp = VG_ROUNDDN(esp, 16);
   frame = (struct rt_sigframe *)esp;

   if (!extend(tst, esp, sizeof(*frame)))
      return esp_top_of_frame;
[...]

but extend will announce only sizeof(frame):
static Bool extend ( ThreadState *tst, Addr addr, SizeT size )
{
[...]
   VG_TRACK( new_mem_stack_signal, addr - VG_STACK_REDZONE_SZB,
             size + VG_STACK_REDZONE_SZB, tid );



longjump does restore the full SP change (which will be tracked by the SP change), leading to a miscounted stack size.

On s390x I was able to fix this, by something like

+   vg_assert((sizeof(*frame) & 7) == 0);
+   vg_assert((sp & 7) == 0);
 
    sp -= sizeof(*frame);
-   sp = VG_ROUNDDN(sp, 8);

Since the we know that the stack pointer is always 8 byte aligned.
Dont know if x86 might use the same method.

Reproducible: Always
Comment 1 Christian Borntraeger 2010-11-04 13:18:11 UTC
For completeness: Problem was originally reported by Stefan Wild during system test of valgrind for s390x.
Comment 2 Christian Borntraeger 2011-01-18 09:31:36 UTC
Created attachment 56155 [details]
possible fix for x86

Here is a possible fix for x86.It solves testcase problem.