- // If we're out of memory, this will throw std::bad_alloc
- current_chunk_ = new uint8_t[chunk_size_];
+ try {
+ // If we're out of memory, allocating a chunk will throw
+ // std::bad_alloc. To give the application some usable memory
+ // to work with in case chunk allocation fails, we allocate
+ // extra memory and throw it away if it all succeeded.
+ // This way, memory allocation will fail early enough to let
+ // PV remain alive. Otherwise, PV will crash in a random
+ // memory-allocating part of the application.
+ current_chunk_ = new uint8_t[chunk_size_ + 7]; /* FIXME +7 is workaround for #1284 */
+
+ const int dummy_size = 2 * chunk_size_;
+ auto dummy_chunk = new uint8_t[dummy_size];
+ memset(dummy_chunk, 0xFF, dummy_size);
+ delete[] dummy_chunk;
+ } catch (bad_alloc&) {
+ delete[] current_chunk_; // The new may have succeeded
+ current_chunk_ = nullptr;
+ throw;
+ }
+