Browse Source
Attempt to log before terminating if prevector allocation fails
pull/4/head
Jack Grigg
6 years ago
No known key found for this signature in database
GPG Key ID: 665DBCD284F7DAFF
4 changed files with
21 additions and
16 deletions
-
src/init.cpp
-
src/prevector.h
-
src/util.cpp
-
src/util.h
|
|
@ -723,20 +723,6 @@ bool AppInitServers(boost::thread_group& threadGroup) |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
[[noreturn]] static void new_handler_terminate() |
|
|
|
{ |
|
|
|
// Rather than throwing std::bad-alloc if allocation fails, terminate
|
|
|
|
// immediately to (try to) avoid chain corruption.
|
|
|
|
// Since LogPrintf may itself allocate memory, set the handler directly
|
|
|
|
// to terminate first.
|
|
|
|
std::set_new_handler(std::terminate); |
|
|
|
fputs("Error: Out of memory. Terminating.\n", stderr); |
|
|
|
LogPrintf("Error: Out of memory. Terminating.\n"); |
|
|
|
|
|
|
|
// The log was successful, terminate now.
|
|
|
|
std::terminate(); |
|
|
|
}; |
|
|
|
|
|
|
|
/** Initialize bitcoin.
|
|
|
|
* @pre Parameters should be parsed and config file should be read. |
|
|
|
*/ |
|
|
|
|
|
@ -1,6 +1,8 @@ |
|
|
|
#ifndef _BITCOIN_PREVECTOR_H_ |
|
|
|
#define _BITCOIN_PREVECTOR_H_ |
|
|
|
|
|
|
|
#include <util.h> |
|
|
|
|
|
|
|
#include <assert.h> |
|
|
|
#include <stdlib.h> |
|
|
|
#include <stdint.h> |
|
|
@ -171,11 +173,11 @@ private: |
|
|
|
success. These should instead use an allocator or new/delete so that handlers |
|
|
|
are called as necessary, but performance would be slightly degraded by doing so. */ |
|
|
|
_union.indirect = static_cast<char*>(realloc(_union.indirect, ((size_t)sizeof(T)) * new_capacity)); |
|
|
|
assert(_union.indirect); |
|
|
|
if (!_union.indirect) { new_handler_terminate(); } |
|
|
|
_union.capacity = new_capacity; |
|
|
|
} else { |
|
|
|
char* new_indirect = static_cast<char*>(malloc(((size_t)sizeof(T)) * new_capacity)); |
|
|
|
assert(new_indirect); |
|
|
|
if (!new_indirect) { new_handler_terminate(); } |
|
|
|
T* src = direct_ptr(0); |
|
|
|
T* dst = reinterpret_cast<T*>(new_indirect); |
|
|
|
memcpy(dst, src, size() * sizeof(T)); |
|
|
|
|
|
@ -17,6 +17,7 @@ |
|
|
|
#include "utiltime.h" |
|
|
|
|
|
|
|
#include <stdarg.h> |
|
|
|
#include <stdio.h> |
|
|
|
|
|
|
|
#if (defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)) |
|
|
|
#include <pthread.h> |
|
|
@ -179,6 +180,20 @@ static FILE* fileout = NULL; |
|
|
|
static boost::mutex* mutexDebugLog = NULL; |
|
|
|
static list<string> *vMsgsBeforeOpenLog; |
|
|
|
|
|
|
|
[[noreturn]] void new_handler_terminate() |
|
|
|
{ |
|
|
|
// Rather than throwing std::bad-alloc if allocation fails, terminate
|
|
|
|
// immediately to (try to) avoid chain corruption.
|
|
|
|
// Since LogPrintf may itself allocate memory, set the handler directly
|
|
|
|
// to terminate first.
|
|
|
|
std::set_new_handler(std::terminate); |
|
|
|
fputs("Error: Out of memory. Terminating.\n", stderr); |
|
|
|
LogPrintf("Error: Out of memory. Terminating.\n"); |
|
|
|
|
|
|
|
// The log was successful, terminate now.
|
|
|
|
std::terminate(); |
|
|
|
}; |
|
|
|
|
|
|
|
static int FileWriteStr(const std::string &str, FILE *fp) |
|
|
|
{ |
|
|
|
return fwrite(str.data(), 1, str.size(), fp); |
|
|
|
|
|
@ -53,6 +53,8 @@ extern bool fLogIPs; |
|
|
|
extern std::atomic<bool> fReopenDebugLog; |
|
|
|
extern CTranslationInterface translationInterface; |
|
|
|
|
|
|
|
[[noreturn]] extern void new_handler_terminate(); |
|
|
|
|
|
|
|
/**
|
|
|
|
* Translation function: Call Translate signal on UI interface, which returns a boost::optional result. |
|
|
|
* If no translation slot is registered, nothing is returned, and simply return the input. |
|
|
|