|
From: Josef W. <Jos...@gm...> - 2011-03-04 14:42:27
|
Hi Christian,
On Friday 04 March 2011, Christian Borntraeger wrote:
> I had problems with callgrind on s390 from the beginning:
> Callgrind: jumps.c:164 (new_jcc): Assertion '(0 <= jmp) && (jmp <= from->bb->cjmp_count)' failed.
> ==39793== at 0x4010209D4: report_and_quit (m_libcassert.c:209)
> ==39793== by 0x401020BCB: vgPlain_assert_fail (m_libcassert.c:283)
> ==39793== by 0x401011159: vgCallgrind_get_jcc (jumps.c:164)
> ==39793== by 0x401003D49: vgCallgrind_push_call_stack (callstack.c:217)
> ==39793== by 0x4010024F3: vgCallgrind_setup_bbcc (bbcc.c:844)
> ==39793== by 0x40394E5C7: ???
> [...]
>
> The last fixes, together with the new assert (and some printf debugging)
> finally pointed me to a potential problem. In our ld startup code we always
> triggered the following case:
>
> if (!skip && CLG_(current_state).nonskipped) {
> /* a call from skipped to nonskipped */
> CLG_(current_state).bbcc = CLG_(current_state).nonskipped;
> }
>
> This changes the current bbcc, but does not adopt the passed value.
Yes. I obviously forgot about updating "passed" at all when adjusting
the source of a call. There are multiple cases for when this is adjusted:
* unwinding happens to resync the shadow stack with the real SP. This is
usually triggered by a longjmp. Before 3.6.1, I fixed this to do a return
instead of a call, so "passed" will not be used at all.
* we have a jump among different functions/shared libs. As jumps are not
possible for call graphs, I either do a regular call, and when leaving the
called function, there will be 2 returns in a row. Or I do a return/call
pair instead of the jump. This behaviour can be configured, and I do a
return/call pair if this is in the symbol resolution of the runtime linker;
the jump then happens in the PLT trampoline code. Just today morning, I fixed
the updating of "passed" for that case.
* your patch: if the user wants a function to be invisible in the call graph, to
avoid false cycles (typically dispatcher functions). Here, the call site shown
is the first parent frame which is visible - the "nonskipped".
> What do you think about the following fix? It makes s390x pass a callgrind
> tests.If ok, please apply.
Cool.
> Index: src/callgrind/bbcc.c
> ===================================================================
> --- src/callgrind/bbcc.c (revision 1021)
> +++ src/callgrind/bbcc.c (working copy)
> @@ -841,6 +841,7 @@
> if (!skip && CLG_(current_state).nonskipped) {
> /* a call from skipped to nonskipped */
> CLG_(current_state).bbcc = CLG_(current_state).nonskipped;
> + passed = CLG_(current_state).bbcc->bb->cjmp_count;
"passed" should be the jump number in the source BB where the call
happened. You always set it to the last jump appearing in the BB;
but that does not have to be always the case. The correct jump number
here is actually stored on the shadow stack...
But as quick workaround, the patch is fine. I have to put it on my
TODO list for the correct solution.
Thanks,
Josef
> }
> CLG_(push_call_stack)(CLG_(current_state).bbcc, passed,
> bbcc, sp, skip);
>
>
|