This is an archive of the discontinued LLVM Phabricator instance.

Use "%zd" format specifier for printing number of testcases executed.
ClosedPublic

Authored by Dor1s on Feb 14 2017, 7:42 AM.

Details

Summary

This helps to avoid signed integer overflow after running a fast fuzz target for several hours, e.g.:

<...>
Done -1097903291 runs in 54001 second(s)

Diff Detail

Repository
rL LLVM

Event Timeline

Dor1s created this revision.Feb 14 2017, 7:42 AM

It seems reasonable to use %zu everywhere for size_t values, if you like it.

kcc edited edge metadata.Feb 14 2017, 11:30 AM

This has come up before...
First, is this 32-bit or 64-bit?
I bet this is 32-bit-only -- you would need to run at 10^14 exec/s to overflow a 64-bit int in 54001 seconds.

If we want to fix *anything* in 32-bit we should first have a buildbot for 32-bit.
Right now libFuzzer is effectively not tested on 32-bit at all (although I've heard people using it)

Now, this won't be a correct fix for 32-bit because it still will overflow, just 2x later, and become very small, but now the stats will be even more confusing.

The real fix would be to use int64_t for any counter like this.
But we should not even try such fixes before we have a 32-bit bot (for which I have no immediate plans).

Dor1s added a comment.EditedFeb 14 2017, 12:41 PM

Thanks for taking a look! I totally agree with you, but actually this is x64:

$ cat size_t.cpp 
#include <stdio.h>

int main() {
  size_t s = 1024 * 1024 * 1024 + 3;
  //s *= 1234;
  s *= 1024 * 1024 * 1024;
  s *= 8;
  printf("size: %d\n", sizeof(s));
  printf("s %%d: %d\n", s);
  printf("s %%lu: %lu\n", s);
  printf("s %%zd: %zd\n", s);
  printf("s %%zu: %zu\n", s);
  return 0;
}

$ clang size_t.cpp -o size_t
size_t.cpp:8:24: warning: format specifies type 'int' but the argument has type 'unsigned long' [-Wformat]
  printf("size: %d\n", sizeof(s));
                ~~     ^~~~~~~~~
                %lu
size_t.cpp:9:25: warning: format specifies type 'int' but the argument has type 'size_t' (aka 'unsigned long') [-Wformat]
  printf("s %%d: %d\n", s);
                 ~~     ^
                 %lu
2 warnings generated.

$ file size_t
size_t: ELF 64-bit LSB  executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=14496bd9d5a4f5121db0374c359cbdc851eae3f7, not stripped

$ ./size_t 
size: 8
s %d: 0
s %lu: 9223372062624579584
s %zd: -9223372011084972032
s %zu: 9223372062624579584

Due to that, it's not that hard to generate more than 2^31 inputs over several hours:

>>> (2 ** 31) / 54000
39768

%zd would be fine as well, as it is up to 2**63, but for lib/Fuzzer/FuzzerDriver.cpp, I believe %zu or %zd is better than existing %d.

kcc added a comment.Feb 14 2017, 12:48 PM

ah, I missed the first part of the change.
Clearly, %d => %zd is good. (in "Done %d runs in...")

Dor1s updated this revision to Diff 88419.Feb 14 2017, 12:56 PM
Dor1s retitled this revision from Use "%zu" format specifier for printing number of testcases executed. to Use "%zd" format specifier for printing number of testcases executed..
kcc accepted this revision.Feb 14 2017, 1:01 PM

LGTM

This revision is now accepted and ready to land.Feb 14 2017, 1:01 PM
kcc closed this revision.Feb 14 2017, 2:26 PM
This revision was automatically updated to reflect the committed changes.