1

I've been testing DynamoRio and minblox to do coverage analysis, and I've got a question, when I run a the bbcount sample on ping.exe (not passing parameters) several times, I get different count of basic blocks and I'm not changing anything.

The same happens with bbcoverage/minblox, I get different traces, for example with 100 runs, I get only 44 traces that are exactly the same, the others are quite different (extra/missing blocks).

I also tried with this trivial program:

int main(int argc, char* argv[]) {
    return 0;
}

The bbcount still produces different outputs, it may change less but it still does:

Instrumentation results:
     14075 basic block executions
       528 basic blocks needed flag saving
      1109 basic blocks did not

Instrumentation results:
     14075 basic block executions
       529 basic blocks needed flag saving
      1108 basic blocks did not

Instrumentation results:
     14159 basic block executions
       529 basic blocks needed flag saving
      1108 basic blocks did not

Is this behavior expected? I'm testing on Windows with ASLR disabled (using EMET).

1

This behaviour is expected.

For ping, the execution trace largely depends on the network at any given run. If one ping succeeds in 0.1 ms there is no guarantee that the next will also succeed within the same time.

Ping uses non-blocking IO to receive datagrams over the network. This means it will make repeated tries before bailing out. Correspondingly, you would get different execution traces for those runs.

For reference, here is the relevant source snippet of ping taken from ReactOS.

/* Expect to receive ICMP echo reply */
FD_ZERO(&Fds);
FD_SET(IcmpSock, &Fds);
Timeval.tv_sec  = Timeout / 1000;
Timeval.tv_usec = Timeout % 1000;

do {
    Status = select(0, &Fds, NULL, NULL, &Timeval);
    if ((Status != SOCKET_ERROR) && (Status != 0))
    {
        Length = sizeof(From);
        Status = recvfrom(IcmpSock, Buffer, Size, 0, &From, &Length);

#ifndef NDEBUG
        printf("Received packet\n");
        DisplayBuffer(Buffer, Status);
        printf("\n");
#endif /* !NDEBUG */
    }
    else
        LostCount++;
    if (Status == SOCKET_ERROR)
    {
        if (WSAGetLastError() != WSAETIMEDOUT)
        {
            FormatOutput(IDS_COULD_NOT_RECV, WSAGetLastError());
            GlobalFree(Buffer);
            return FALSE;
        }
        Status = 0;
    }

    if (Status == 0)
    {
        FormatOutput(IDS_REQUEST_TIMEOUT);
        GlobalFree(Buffer);
        return TRUE;
    }

} while (!DecodeResponse(Buffer, Status, (PSOCKADDR_IN)&From));
| improve this answer | |
  • It doesn't matter which program you try. I verified myself that even for completely deterministic non trivial programs (i.e., "ls"), the number of executed basic blocks varies from execution to execution, with the very same inputs. Indeed, in a fuzzer I wrote using code coverage data, to get a measure of executed basic blocks I get the average between 10 runs instead of only one execution because I know I cannot trust the results of just one execution. – joxeankoret Nov 11 '15 at 10:54
  • That's what I meant, thanks @joxeankoret. I was running ping.exe without parameters, so the actual networking code shouldn't have been called at all. I also tried it with a trivial program and the bb count was different too, I'll update my post with the example code I used and bbcount output. – fms Nov 11 '15 at 14:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.