0

I'd like to use boost::iostreams to compress log files, and hope that the logs are stored successfully in all cases. Can I reset an object of boost::filtering_stream class automatically when a program is aborted by assertion failures?

#include <boost/iostreams/device/file.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/iostreams/filtering_stream.hpp>

namespace io = boost::iostreams;

int main() {
  io::filtering_ostream out;
  out.push(io::gzip_compressor());
  out.push(io::file_sink("my_file.txt.gz"));

  for (auto i = 0; i < 100; ++i) {
    if (i > 50) {
      // Can I flush the stream without explicitly calling
      // filtering_ostream::reset()?
      // out.reset();
      assert(false);
    }
    out << i << '\n';
  }
}
Han
  • 625
  • 2
  • 7
  • 25

1 Answers1

0

On failure, assert invokes abort (https://en.cppreference.com/w/cpp/utility/program/abort), which skips stack unwinding, so destructors are not called. That effectively leaves you with the option to add a signal handler for SIGABRT. That will probably become very messy though, because you'd have to entangle these signals with logging, which will probably be fragile.

As alternative, I'd put the rationale for this particular requirement up for discussion. Assertions are used to verify internal state, if they detect anything wrong, there is little left but to terminate and perhaps use a debugger to make a post-mortem inspection. Requiring any particular behaviour like e.g. flushing logs seems to be overkill.

Maybe, there are other alternatives as well. If you use IPC to forward the info for logging, you could implement the compression in a separate process. If your program is aborted due to assertion failure, the logs would remain intact.

Ulrich Eckhardt
  • 16,572
  • 3
  • 28
  • 55