ilya-biryukov added inline comments.

================
Comment at: clangd/Trace.cpp:87
+
+static Tracer* T = nullptr;
+} // namespace
----------------
sammccall wrote:
> ilya-biryukov wrote:
> > Maybe use `unique_ptr<Tracer>` (or even `llvm::Optional<Tracer>`)? 
> > Otherwise we leak memory and don't flush the stream if users of tracing API 
> > forget to call `stop()`. (I think I'm on the same page with @ioeric here  
> > about forgetting a call to `stop()`).
> >  
> > Having a static global of non-pod type is a no-go, but we could use static 
> > local variables:
> > 
> > ```
> > llvm::Optional<Tracer>& getTracerInstance() {
> >  static llvm::Optional<Tracer> Tracer;
> >  return Tracer;
> > }
> > ```
> So Eric's solution of a scoped object that would be owned by main() makes 
> sense to me, and I'm happy to add it (though personally not sure it carries 
> its weight).
> 
> However I don't understand *your* suggestion :-)
> > Having a static global of non-pod type is a no-go, but we could use static 
> > local variables:
> >     llvm::Optional<Tracer>& getTracerInstance() {
> >       static llvm::Optional<Tracer> Tracer;
> >       return Tracer;
> >     }
> So it's not global, which means we're not calling Optional() on startup, 
> which would actually be totally safe (I guess the constructor should be 
> marked as `constexpr`).
> 
> But we *are* calling `~Optional()` and therefore `~Tracer()` at shutdown. And 
> maybe `~Tracer()` calls something that logs, and llvm::errs() has already 
> been destroyed... *this* is why avoid static objects, right?
> 
> > Otherwise we leak memory and don't flush the stream if users of tracing API 
> > forget to call stop()
> The intended time to call `stop()` is at the end of the program. If you 
> forget to call it, we won't be leaking memory :-) We indeed won't flush the 
> stream, but that wouldn't be safe (see above).
> 
> The other option is the user is calling `start()` and `stop()` multiple 
> times, and they call `start()` twice without stopping. We already assert on 
> this, and anyone who doesn't reproducibly hit that assert is well into racy 
> UB-land (logging methods may be called concurrently with each other, but 
> everything else must be synchronized).
> 
> Overall I'm not really seeing what scenario we can detect and safely do 
> something about.
Forget what I said, you're right. Tracer has state, can be reconfigured 
multiple times and there's no guarantee our references won't be dangling on 
destruction of `Tracer`.

I do think Eric's solution is good, though. For all the same reasons why RAII 
is good.


https://reviews.llvm.org/D39086



_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to