I have an unexpected behavior with a basic Valgrind tool. For each Put statement of a basic block, I register a dirty helper using unsafeIRDirty_0_N. The problem is that the dirty helper is called more times than expected, e.g. there are 5 Put statements in a basic block but the dirty helper is called 13 times. I need to use dirty helpers in my tool but I am stuck for now, any help would be very appreciated.

Here is the code:

unsigned int g_Put_cnt; // the number of Put statements in the basic block
unsigned int g_helper_Put_cnt; // the number of times helper_Put() was
called

static VG_REGPARM(0) void helper_print_counters()
{
    VG_(printf)("g_Put_cnt: %d - g_helper_Put_cnt: %d (%d)\n", g_Put_cnt,
g_helper_Put_cnt, g_helper_Put_cnt-g_Put_cnt);
}

static VG_REGPARM(0) void helper_Put()
{
    g_helper_Put_cnt++;
}

static
IRSB* fz_instrument ( VgCallbackClosure* closure,
                      IRSB* sb_in,
                      VexGuestLayout* layout,
                      VexGuestExtents* vge,
                      IRType gWordTy, IRType hWordTy )
{
    IRSB* sb_out;
    Int i;

    if (gWordTy != hWordTy) {
        /* We don't currently support this case. */
        VG_(tool_panic)("host/guest word size mismatch");
    }

    /* Set up sb_out */
    sb_out = deepCopyIRSBExceptStmts(sb_in);

    // Copy verbatim any IR preamble preceding the first IMark
    i = 0;
    while (i < sb_in->stmts_used && sb_in->stmts[i]->tag != Ist_IMark) {
        addStmtToIRSB(sb_out, sb_in->stmts[i]);
        i++;
    }

    g_Put_cnt = 0;
    g_helper_Put_cnt = 0;

    for (/*use current i*/; i < sb_in->stmts_used; i++)
    {
        IRStmt* st = sb_in->stmts[i];
        IRDirty* di;

        if (!st)
            continue;

        switch (st->tag)
        {
            case Ist_Put:
                di = unsafeIRDirty_0_N(0,
                                       "helper_Put",
                                       VG_(fnptr_to_fnentry)(&helper_Put),
                                       mkIRExprVec_0());
                addStmtToIRSB(sb_out, IRStmt_Dirty(di));

                g_Put_cnt++;
                break;
        }

        addStmtToIRSB(sb_out, st);
    }

    IRDirty* di = unsafeIRDirty_0_N(0, "helper_print_counters",
VG_(fnptr_to_fnentry)(&helper_print_counters), mkIRExprVec_0());
    addStmtToIRSB(sb_out, IRStmt_Dirty(di));

    return sb_out;
}

And the output:

g_Put_cnt: 22 - g_helper_Put_cnt: 22 (0)
g_Put_cnt: 21 - g_helper_Put_cnt: 21 (0)
g_Put_cnt: 8 - g_helper_Put_cnt: 8 (0)
g_Put_cnt: 5 - g_helper_Put_cnt: 13 (8)
g_Put_cnt: 5 - g_helper_Put_cnt: 18 (13)
g_Put_cnt: 6 - g_helper_Put_cnt: 6 (0)
g_Put_cnt: 6 - g_helper_Put_cnt: 6 (0)
g_Put_cnt: 9 - g_helper_Put_cnt: 9 (0)
g_Put_cnt: 9 - g_helper_Put_cnt: 22 (13)
g_Put_cnt: 9 - g_helper_Put_cnt: 35 (26)
g_Put_cnt: 9 - g_helper_Put_cnt: 48 (39)
g_Put_cnt: 9 - g_helper_Put_cnt: 61 (52)
g_Put_cnt: 9 - g_helper_Put_cnt: 74 (65)
g_Put_cnt: 9 - g_helper_Put_cnt: 87 (78)
g_Put_cnt: 9 - g_helper_Put_cnt: 100 (91)
g_Put_cnt: 9 - g_helper_Put_cnt: 113 (104)
g_Put_cnt: 9 - g_helper_Put_cnt: 126 (117)
g_Put_cnt: 9 - g_helper_Put_cnt: 139 (130)
g_Put_cnt: 9 - g_helper_Put_cnt: 152 (143)
g_Put_cnt: 9 - g_helper_Put_cnt: 157 (148)
...

Thank you in advance.

有帮助吗?

解决方案

I got the answer on Valgrind mailing list:

http://sourceforge.net/mailarchive/message.php?msg_id=31488717

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top