[PATCH] D27179: LibFuzzer - Implement timers for Windows and improve synchronization.

Zachary Turner via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 29 11:15:18 PST 2016


zturner added inline comments.


================
Comment at: lib/Fuzzer/FuzzerInternal.h:146-147
   std::atomic<size_t> CurrentUnitSize;
+  bool RunningCB;
+  std::mutex RunningCBMtx;
   uint8_t BaseSha1[kSHA1NumBytes];  // Checksum of the base unit.
----------------
It seems like we could use `std::atomic_bool` here.  Does that not work for some reason?  The only thing I see that is questionable is that in `FuzzerCallback::CrashCallback` we check the value, and then run multiple lines of code before returning.

But on the other hand, in `Fuzzer::ExecuteCallback`, we always set it to true before executing any callback, and false after.  So maybe there is no race condition?

`atomic_bool` is more lightweight than grabbing a full blown mutex, so if we can be sure it's safe, then it seems better.


================
Comment at: lib/Fuzzer/FuzzerUtilWindows.cpp:89-90
+  ~TimerQ() {
+    if (TimerQueue)
+      DeleteTimerQueueEx(TimerQueue, NULL);
+  };
----------------
mpividori wrote:
> zturner wrote:
> > mpividori wrote:
> > > zturner wrote:
> > > > Shouldn't use all delete the timer as well?  You store it locally in `SetTimer` but then let the handle leak.  So every time we call `SetTimer` it will leak a handle.
> > > According to the documentation, the timers which were added to the `TimerQueue` are automatically deleted when deleting the `TimerQueue`.
> > Ahh, I didn't notice that.  But it seems we can still create multiple timers here.  For example if you call the `SetTimer` twice it will add a new timer instead of overwriting the old timer.  Is this desired?  If a user is not supposed to call `SetTimer` twice, then maybe we should add `assert(!TimerQueue)`.  But if it is ok to call `SetTimer` more than once and have subsequent calls overwrite the existing timer value, then we should probably store the `HANDLE` in the class and delete it and recreate on subsequent calls.
> > 
> > Also, one thing I just thought of that might be a problem.  The timer callback is not going to be invoked on the fuzzer thread, but rather a thread in the windows system thread pool.  But I looked at the Alarm callback function and it begins like this:
> > ```
> >   if (!InFuzzingThread()) return;
> > ```
> > 
> > So, I think this check is going to always fail.  If we need to guarantee that alarms happen on the fuzzing thread, we need a different strategy.
> > 
> > What do you think?
> @zturner thanks for your comments.
> + Yes, we can create multiple timers here, but we don't expose the function `SetTimer` any more (I removed that), so the user doesn't have access to it. The Timer instance is only accessed by `SetSignalHandler()` function. Anyway, I can add the changes you proposed.
> Also, the code could be simplified by using a separate thread for the timer instead of using `TimerQueues`. Something like:
> ```
> void TimerThread(int Seconds) {
>   while (1) {
>     sleep(Seconds);
>     AlrmCallback();
>   }
> }
> ```
> I wasn't sure which option is prefered. What do you think? If we consider a separate thread, we could use the same implementation for Posix too, and get rid of SIGALRM.
> 
> + The `if (!InFuzzingThread()) return;` line was removed in these changes. Yes, I adapted the code to handle that situation.
>   Previous implementation assumed that the ALRM signals would be handled by the main thread, which is not necessarily true. In POSIX it is unspecified with thread handle signals.
>   With the changes included in this diff, we can be sure that Alarm callback is executed by a thread different to the main thread in both Posix and Windows implementations:
>  -  In Windows: by a thread from the windows system thread pool.
>  -  In Posix: by a separate thread that waits for SIGALRM signals.
> 
I don't think we need to create a thread for it, using the windows threadpool is more efficient.


Repository:
  rL LLVM

https://reviews.llvm.org/D27179





More information about the llvm-commits mailing list