Same basic block being instrumented twice??

25 views
Skip to first unread message

Ao Vak

unread,
Mar 14, 2026, 7:32:13 PM (13 days ago) Mar 14
to DynamoRIO Users


I'm trying to track how many times certain basic blocks are executed by inserting a clean call that increments an array of counters.
But my clean call is being inserted multiple times for the same basic block?
How do I prevent this?

My callback is being registered with drmgr_register_bb_instrumentation_event
My DynamoRIO client code 
|
|
v


static dr_emit_flags_t
event_app_instruction(void* drcontext, void* tag, instrlist_t* bb, instr_t* inst,
    bool for_trace, bool translating, void* user_data)
{
    if (drmgr_is_first_instr(drcontext, inst))
    {
        for (int i = 0; i < MAX_ENTRIES && bbList[i] != NULL; i++)
        {
            if (instr_get_app_pc(inst) == bbList[i])
            {
                // (?) weirdly this is hitting multiple times for the same basic block over the course of the program's lifetime
                dr_printf("first: %p second: %p\n", bbList[i], instr_get_app_pc(inst));

                dr_insert_clean_call(drcontext, bb, inst, incrementCounters, false, 1, OPND_CREATE_INT32(i));
                dr_printf("Found match!\n");
            }
        }
    }

    return DR_EMIT_DEFAULT;
}

Enrico Deiana

unread,
Mar 15, 2026, 7:24:26 PM (12 days ago) Mar 15
to DynamoRIO Users
DynamoRIO definition of basic blocks is different from the classical, static, "compiler" definition of a basic block.
DynamoRIO doesn't know all entry points to a basic block ahead of time, it discovers them as the target application executes, so it might duplicate the tail of a basic block if a later entry point is discovered that targets the middle of a block that was seen previously.
So you might see "duplication" of basic blocks in that sense.

However, don't confuse instrumentation time (when event_app_instruction() is called) and execution time of the target application (when incrementCounters() is called).
DynamoRIO can call event_app_instruction() multiple times for different reasons, but it doesn't mean the target application is executing that basic block multiple times.
So, seeing the result of dr_printf() in event_app_instruction() multiple times doesn't mean the target application is executing a basic block.

Without the complete client code (i.e., how event_app_instruction() is registered and the definition of incrementCounters()), it's hard to say if there are issues with the instrumentation code posted.
Is bbList a global? Is it populated in incrementCounters()? How are you getting the PC there? Where is the actual counter?
Anyway, I'd suggest to look at the example client bbcount, which already counts basic blocks, in order to understand how DynamoRIO operates: https://github.com/DynamoRIO/dynamorio/blob/master/api/samples/bbcount.c

Enrico Deiana

unread,
Mar 16, 2026, 4:36:14 PM (11 days ago) Mar 16
to DynamoRIO Users
Following up on my previous message, if your goal is to robustly track basic block execution counts for program characterization, you might also want to look at DynamoRIO's DrPoints client.
Unlike the simpler bbcount client, DrPoints can handle applications that load and unload libraries.
It identifies basic blocks using module-relative offsets via the drmodtrack library, ensuring that basic block identification remains accurate even if code is reloaded at different memory addresses.
DrPoints focus is to compute Basic Block Vectors (i.e., pairs of <BasicBlock_ID,execution_count>) for workload reduction techniques like simpoints.
You can find the source code for it at: https://github.com/DynamoRIO/dynamorio/blob/master/clients/drpoints/drpoints.cpp
Reply all
Reply to author
Forward
0 new messages