unified out of memory handling (#19717)
* unified out of memory handling * fix windows cleanup and exit
Costa Tsaousis committed
Feb 26, 2025 at 13:58 UTC
4ee0830534942520ff6dada6274795dce6ae64b9
8 files changed
+66
-67
src/daemon/daemon-status-file.c
-1
@@ -56,7 +56,6 @@ static XXH64_hash_t daemon_status_file_hash(DAEMON_STATUS_FILE *ds, const char *
56
buffer_json_member_add_string_or_empty(wb, "fatal_filename", ds->fatal.filename);
57
buffer_json_member_add_string_or_empty(wb, "fatal_errno", ds->fatal.errno_str);
58
buffer_json_member_add_string_or_empty(wb, "fatal_function", ds->fatal.function);
59
- buffer_json_member_add_string_or_empty(wb, "fatal_message", ds->fatal.message);
59
buffer_json_member_add_string_or_empty(wb, "fatal_stack_trace", ds->fatal.stack_trace);
60
buffer_json_member_add_string(wb, "message", msg);
61
buffer_json_member_add_string(wb, "cause", cause);
src/daemon/winsvc.cc
+1
@@ -2,6 +2,7 @@ extern "C" {
2
3
#include "daemon.h"
4
#include "libnetdata/libnetdata.h"
5
+#include "daemon/daemon-shutdown.h"
6
7
int netdata_main(int argc, char *argv[]);
8
void nd_process_signals(void);
src/database/engine/datafile.c
+2
-8
@@ -260,10 +260,7 @@ int create_data_file(struct rrdengine_datafile *datafile)
260
datafile->file = file;
261
__atomic_add_fetch(&ctx->stats.datafile_creations, 1, __ATOMIC_RELAXED);
262
263
- ret = posix_memalignz((void *)&superblock, RRDFILE_ALIGNMENT, sizeof(*superblock));
264
- if (unlikely(ret)) {
265
- fatal("DBENGINE: posix_memalign:%s", strerror(ret));
266
- }
263
+ (void)posix_memalignz((void *)&superblock, RRDFILE_ALIGNMENT, sizeof(*superblock));
264
memset(superblock, 0, sizeof(*superblock));
265
(void) strncpy(superblock->magic_number, RRDENG_DF_MAGIC, RRDENG_MAGIC_SZ);
266
(void) strncpy(superblock->version, RRDENG_DF_VER, RRDENG_VER_SZ);
@@ -297,10 +294,7 @@ static int check_data_file_superblock(uv_file file)
294
uv_buf_t iov;
295
uv_fs_t req;
296
300
- ret = posix_memalignz((void *)&superblock, RRDFILE_ALIGNMENT, sizeof(*superblock));
301
- if (unlikely(ret)) {
302
- fatal("DBENGINE: posix_memalign:%s", strerror(ret));
303
- }
297
+ (void)posix_memalignz((void *)&superblock, RRDFILE_ALIGNMENT, sizeof(*superblock));
298
iov = uv_buf_init((void *)superblock, sizeof(*superblock));
299
300
ret = uv_fs_read(NULL, &req, file, &iov, 1, 0, NULL);
src/database/engine/journalfile.c
+3
-11
@@ -580,10 +580,7 @@ int journalfile_create(struct rrdengine_journalfile *journalfile, struct rrdengi
580
journalfile->file = file;
581
__atomic_add_fetch(&ctx->stats.journalfile_creations, 1, __ATOMIC_RELAXED);
582
583
- ret = posix_memalignz((void *)&superblock, RRDFILE_ALIGNMENT, sizeof(*superblock));
584
- if (unlikely(ret)) {
585
- fatal("DBENGINE: posix_memalign:%s", strerror(ret));
586
- }
583
+ (void)posix_memalignz((void *)&superblock, RRDFILE_ALIGNMENT, sizeof(*superblock));
584
memset(superblock, 0, sizeof(*superblock));
585
(void) strncpy(superblock->magic_number, RRDENG_JF_MAGIC, RRDENG_MAGIC_SZ);
586
(void) strncpy(superblock->version, RRDENG_JF_VER, RRDENG_VER_SZ);
@@ -617,10 +614,7 @@ static int journalfile_check_superblock(uv_file file)
614
uv_buf_t iov;
615
uv_fs_t req;
616
620
- ret = posix_memalignz((void *)&superblock, RRDFILE_ALIGNMENT, sizeof(*superblock));
621
- if (unlikely(ret)) {
622
- fatal("DBENGINE: posix_memalign:%s", strerror(ret));
623
- }
617
+ (void)posix_memalignz((void *)&superblock, RRDFILE_ALIGNMENT, sizeof(*superblock));
618
iov = uv_buf_init((void *)superblock, sizeof(*superblock));
619
620
ret = uv_fs_read(NULL, &req, file, &iov, 1, 0, NULL);
@@ -813,9 +807,7 @@ static uint64_t journalfile_iterate_transactions(struct rrdengine_instance *ctx,
807
file_size = journalfile->unsafe.pos;
808
809
max_id = 1;
816
- ret = posix_memalignz((void *)&buf, RRDFILE_ALIGNMENT, READAHEAD_BYTES);
817
- if (unlikely(ret))
818
- fatal("DBENGINE: posix_memalign:%s", strerror(ret));
810
+ (void)posix_memalignz((void *)&buf, RRDFILE_ALIGNMENT, READAHEAD_BYTES);
811
812
for (pos = sizeof(struct rrdeng_jf_sb); pos < file_size; pos += READAHEAD_BYTES) {
813
size_bytes = MIN(READAHEAD_BYTES, file_size - pos);
src/database/engine/pdc.c
+2
-4
@@ -1216,12 +1216,10 @@ static inline void *datafile_extent_read(struct rrdengine_instance *ctx, uv_file
1216
uv_fs_t request;
1217
1218
unsigned real_io_size = ALIGN_BYTES_CEILING(size_bytes);
1219
- int ret = posix_memalignz(&buffer, RRDFILE_ALIGNMENT, real_io_size);
1220
- if (unlikely(ret))
1221
- fatal("DBENGINE: posix_memalign(): %s", strerror(ret));
1219
+ (void)posix_memalignz(&buffer, RRDFILE_ALIGNMENT, real_io_size);
1220
1221
uv_buf_t iov = uv_buf_init(buffer, real_io_size);
1224
- ret = uv_fs_read(NULL, &request, file, &iov, 1, (int64_t)pos, NULL);
1222
+ int ret = uv_fs_read(NULL, &request, file, &iov, 1, (int64_t)pos, NULL);
1223
if (unlikely(-1 == ret)) {
1224
ctx_io_error(ctx);
1225
posix_memalign_freez(buffer);
src/database/engine/rrdengine.c
+2
-9
@@ -393,9 +393,7 @@ WAL *wal_get(struct rrdengine_instance *ctx, unsigned size) {
393
if(unlikely(!wal)) {
394
wal = mallocz(sizeof(WAL));
395
wal->buf_size = RRDENG_BLOCK_SIZE;
396
- int ret = posix_memalignz((void *)&wal->buf, RRDFILE_ALIGNMENT, wal->buf_size);
397
- if (unlikely(ret))
398
- fatal("DBENGINE: posix_memalign:%s", strerror(ret));
396
+ (void)posix_memalignz((void *)&wal->buf, RRDFILE_ALIGNMENT, wal->buf_size);
397
__atomic_add_fetch(&wal_globals.atomics.allocated, 1, __ATOMIC_RELAXED);
398
}
399
@@ -732,7 +730,6 @@ static struct rrdengine_datafile *get_datafile_to_write_extent(struct rrdengine_
730
static struct extent_io_descriptor *
731
datafile_extent_build(struct rrdengine_instance *ctx, struct page_descr_with_data *base, uv_buf_t *iov)
732
{
735
- int ret;
733
unsigned i, count, size_bytes, pos, real_io_size;
734
uint32_t uncompressed_payload_length, max_compressed_size, payload_offset;
735
struct page_descr_with_data *descr, *eligible_pages[MAX_PAGES_PER_EXTENT];
@@ -763,11 +760,7 @@ datafile_extent_build(struct rrdengine_instance *ctx, struct page_descr_with_dat
760
payload_offset = sizeof(*header) + count * sizeof(header->descr[0]);
761
max_compressed_size = dbengine_max_compressed_size(uncompressed_payload_length, compression_algorithm);
762
size_bytes = payload_offset + MAX(uncompressed_payload_length, max_compressed_size) + sizeof(*trailer);
766
- ret = posix_memalignz((void *)&xt_io_descr->buf, RRDFILE_ALIGNMENT, ALIGN_BYTES_CEILING(size_bytes));
767
- if (unlikely(ret)) {
768
- fatal("DBENGINE: posix_memalign:%s", strerror(ret));
769
- /* freez(xt_io_descr);*/
770
- }
763
+ (void)posix_memalignz((void *)&xt_io_descr->buf, RRDFILE_ALIGNMENT, ALIGN_BYTES_CEILING(size_bytes));
764
memset(xt_io_descr->buf, 0, ALIGN_BYTES_CEILING(size_bytes));
765
(void) memcpy(xt_io_descr->descr_array, eligible_pages, sizeof(struct page_descr_with_data *) * count);
766
xt_io_descr->descr_count = count;
src/libnetdata/memory/nd-mallocz.c
+51
-29
@@ -386,72 +386,94 @@ void freez_int(void *ptr, const char *file, const char *function, size_t line) {
386
}
387
#else
388
389
-ALWAYS_INLINE char *strdupz(const char *s) {
389
+ALWAYS_INLINE NORETURN
390
+static void out_of_memory(const char *call, size_t size) {
391
+ struct rusage usage = { 0 };
392
+ if(getrusage(RUSAGE_SELF, &usage) != 0)
393
+ usage.ru_maxrss = 0;
394
+
395
+ OS_SYSTEM_MEMORY sm = os_last_reported_system_memory();
396
+ fatal("Out of memory on %s(%zu bytes)!\n"
397
+ "System memory available: %lu, while our max RSS usage is: %ld\n"
398
+ "O/S mmap limit: %llu, while our mmap count is: %zu",
399
+ call, size,
400
+ sm.ram_available_bytes, usage.ru_maxrss,
401
+ os_mmap_limit(), __atomic_load_n(&nd_mmap_count, __ATOMIC_RELAXED));
402
+}
403
+
404
+ALWAYS_INLINE MALLOCLIKE NEVERNULL WARNUNUSED
405
+char *strdupz(const char *s) {
406
workers_memory_call(WORKERS_MEMORY_CALL_LIBC_STRDUP);
407
408
char *t = strdup(s);
393
- if (unlikely(!t)) {
394
- OS_SYSTEM_MEMORY sm = os_last_reported_system_memory();
395
- fatal("Cannot strdup() string '%s' (system memory available bytes: %lu)", s, sm.ram_available_bytes);
396
- }
409
+ if (unlikely(!t))
410
+ out_of_memory(__FUNCTION__ , strlen(s) + 1);
411
+
412
return t;
413
}
414
400
-ALWAYS_INLINE char *strndupz(const char *s, size_t len) {
415
+ALWAYS_INLINE MALLOCLIKE NEVERNULL WARNUNUSED
416
+char *strndupz(const char *s, size_t len) {
417
workers_memory_call(WORKERS_MEMORY_CALL_LIBC_STRNDUP);
418
419
char *t = strndup(s, len);
404
- if (unlikely(!t)) {
405
- OS_SYSTEM_MEMORY sm = os_last_reported_system_memory();
406
- fatal("Cannot strndup() string '%s' of len %zu (system memory available bytes: %lu)", s, len, sm.ram_available_bytes);
407
- }
420
+ if (unlikely(!t))
421
+ out_of_memory(__FUNCTION__ , len + 1);
422
+
423
return t;
424
}
425
426
// If ptr is NULL, no operation is performed.
412
-ALWAYS_INLINE void freez(void *ptr) {
427
+ALWAYS_INLINE
428
+void freez(void *ptr) {
429
if(likely(ptr)) {
430
workers_memory_call(WORKERS_MEMORY_CALL_LIBC_FREE);
431
free(ptr);
432
}
433
}
434
419
-ALWAYS_INLINE void *mallocz(size_t size) {
435
+ALWAYS_INLINE MALLOCLIKE NEVERNULL WARNUNUSED
436
+void *mallocz(size_t size) {
437
workers_memory_call(WORKERS_MEMORY_CALL_LIBC_MALLOC);
438
void *p = malloc(size);
422
- if (unlikely(!p)) {
423
- OS_SYSTEM_MEMORY sm = os_last_reported_system_memory();
424
- fatal("Cannot allocate %zu bytes of memory (system memory available bytes: %lu)", size, sm.ram_available_bytes);
425
- }
439
+ if (unlikely(!p))
440
+ out_of_memory(__FUNCTION__, size);
441
+
442
return p;
443
}
444
429
-ALWAYS_INLINE void *callocz(size_t nmemb, size_t size) {
445
+ALWAYS_INLINE MALLOCLIKE NEVERNULL WARNUNUSED
446
+void *callocz(size_t nmemb, size_t size) {
447
workers_memory_call(WORKERS_MEMORY_CALL_LIBC_CALLOC);
448
void *p = calloc(nmemb, size);
432
- if (unlikely(!p)) {
433
- OS_SYSTEM_MEMORY sm = os_last_reported_system_memory();
434
- fatal("Cannot allocate %zu bytes of memory (system memory available bytes: %lu)", nmemb * size, sm.ram_available_bytes);
435
- }
449
+ if (unlikely(!p))
450
+ out_of_memory(__FUNCTION__, nmemb * size);
451
+
452
return p;
453
}
454
439
-ALWAYS_INLINE void *reallocz(void *ptr, size_t size) {
455
+ALWAYS_INLINE MALLOCLIKE NEVERNULL WARNUNUSED
456
+void *reallocz(void *ptr, size_t size) {
457
workers_memory_call(WORKERS_MEMORY_CALL_LIBC_REALLOC);
458
void *p = realloc(ptr, size);
442
- if (unlikely(!p)) {
443
- OS_SYSTEM_MEMORY sm = os_last_reported_system_memory();
444
- fatal("Cannot re-allocate memory to %zu bytes. (system memory available bytes: %lu)", size, sm.ram_available_bytes);
445
- }
459
+ if (unlikely(!p))
460
+ out_of_memory(__FUNCTION__, size);
461
+
462
return p;
463
}
464
449
-ALWAYS_INLINE int posix_memalignz(void **memptr, size_t alignment, size_t size) {
465
+ALWAYS_INLINE
466
+int posix_memalignz(void **memptr, size_t alignment, size_t size) {
467
workers_memory_call(WORKERS_MEMORY_CALL_LIBC_POSIX_MEMALIGN);
451
- return posix_memalign(memptr, alignment, size);
468
+ int rc = posix_memalign(memptr, alignment, size);
469
+ if(unlikely(rc))
470
+ out_of_memory(__FUNCTION__, size);
471
+
472
+ return rc;
473
}
474
454
-ALWAYS_INLINE void posix_memalign_freez(void *ptr) {
475
+ALWAYS_INLINE
476
+void posix_memalign_freez(void *ptr) {
477
workers_memory_call(WORKERS_MEMORY_CALL_LIBC_POSIX_MEMALIGN_FREE);
478
free(ptr);
479
}
src/libnetdata/memory/nd-mallocz.h
+5
-5
@@ -51,11 +51,11 @@ void freez_int(void *ptr, const char *file, const char *function, size_t line);
51
size_t mallocz_usable_size_int(void *ptr, const char *file, const char *function, size_t line);
52
53
#else // NETDATA_TRACE_ALLOCATIONS
54
-char *strdupz(const char *s) MALLOCLIKE NEVERNULL;
55
-char *strndupz(const char *s, size_t len) MALLOCLIKE NEVERNULL;
56
-void *callocz(size_t nmemb, size_t size) MALLOCLIKE NEVERNULL;
57
-void *mallocz(size_t size) MALLOCLIKE NEVERNULL;
58
-void *reallocz(void *ptr, size_t size) MALLOCLIKE NEVERNULL;
54
+char *strdupz(const char *s) MALLOCLIKE NEVERNULL WARNUNUSED;
55
+char *strndupz(const char *s, size_t len) MALLOCLIKE NEVERNULL WARNUNUSED;
56
+void *callocz(size_t nmemb, size_t size) MALLOCLIKE NEVERNULL WARNUNUSED;
57
+void *mallocz(size_t size) MALLOCLIKE NEVERNULL WARNUNUSED;
58
+void *reallocz(void *ptr, size_t size) MALLOCLIKE NEVERNULL WARNUNUSED;
59
void freez(void *ptr);
60
#endif // NETDATA_TRACE_ALLOCATIONS
61