trace logging with DEBUG or explicitly in release with COW_TRACE macro defs

error_handling
Avril 4 years ago
parent 52c80b1b08
commit 4e24d281e2
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -1,10 +1,15 @@
#ifndef _COW_H #ifndef _COW_H
#define _COW_H #define _COW_H
#ifdef __cplusplus
#define restrict __restrict__
extern "C" {
#endif
#include <stdlib.h> #include <stdlib.h>
// Copy-on-write mapped memory. // Copy-on-write mapped memory.
typedef struct cow cow_t, *cow; typedef struct cow cow_t;
/// Create a new copy-on-write area of `size` bytes. /// Create a new copy-on-write area of `size` bytes.
/// Writes to this instance pointer (`cow_ptr()`) are written to the allocated memory. /// Writes to this instance pointer (`cow_ptr()`) are written to the allocated memory.
@ -29,4 +34,9 @@ size_t cow_size(const cow_t* cow);
//XXX: Too unsafe and not useful enough to warrant a function/macro. //XXX: Too unsafe and not useful enough to warrant a function/macro.
//#define cow_from_ptr(p) (cow_t*)(&(p)) //#define cow_from_ptr(p) (cow_t*)(&(p))
#ifdef __cplusplus
#undef restrict
}
#endif
#endif /* _COW_H */ #endif /* _COW_H */

@ -13,6 +13,12 @@
#define box(t) aligned_alloc(_Alignof(t), sizeof(t)) #define box(t) aligned_alloc(_Alignof(t), sizeof(t))
#if defined(DEBUG) || defined(COW_TRACE)
#define TRACE(msg, ...) (fprintf(stderr, "[TRACE] %s->%s %d: " msg "\n", __FILE__, __func__, __LINE__, __VA_ARGS__), (void)0)
#else
#define TRACE(msg, ...) ((void)0)
#endif
struct cow { struct cow {
void* origin; // ptr to mapped memory. This *MUST* be the first field and have an offset of 0. void* origin; // ptr to mapped memory. This *MUST* be the first field and have an offset of 0.
@ -31,6 +37,7 @@ static __attribute__((noreturn)) __attribute__((noinline)) __attribute__((cold))
static inline cow_t* box_value(cow_t v) static inline cow_t* box_value(cow_t v)
{ {
cow_t* boxed = box(cow_t); cow_t* boxed = box(cow_t);
TRACE("boxing cow_t { origin = %p, fd = 0x%x, size = %lu } -> %p (%lu bytes)", v.origin, v.fd, v.size, (const void*)boxed, sizeof(cow_t));
*boxed = v; *boxed = v;
return boxed; return boxed;
} }
@ -74,11 +81,13 @@ cow_t* cow_create(size_t size)
ret.origin = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, ret.fd, 0); ret.origin = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, ret.fd, 0);
if(ret.origin == MAP_FAILED) die("cow_create:mmap"); if(ret.origin == MAP_FAILED) die("cow_create:mmap");
TRACE("mapped new cow page of %lu size at %p (memfd %d)", size, ret.origin, ret.fd);
return box_value(ret); return box_value(ret);
} }
void cow_free(cow_t* restrict cow) void cow_free(cow_t* restrict cow)
{ {
TRACE("unmapping %s cow of %lu size from %p (fd %d, real fd %d)", cow_is_fake(cow) ? "fake" : "and closing fd of origin", cow->size, cow->origin, cow->fd, cow_real_fd(cow));
munmap(cow->origin, cow->size); munmap(cow->origin, cow->size);
if(!cow_is_fake(cow)) if(!cow_is_fake(cow))
close(cow->fd); close(cow->fd);
@ -94,5 +103,6 @@ cow_t* cow_clone(const cow_t* cow)
clone.fd = (~INT_MAX) | cow->fd; clone.fd = (~INT_MAX) | cow->fd;
clone.size = cow->size; clone.size = cow->size;
TRACE("mapped cloned cow page of %lu size from %p (%s) at %p (clone fd %d, parent fd %d, real fd %d)", clone.size, cow->origin, cow_is_fake(cow) ? "fake" : "origin", clone.origin, clone.fd, cow->fd, cow_real_fd(&clone));
return box_value(clone); return box_value(clone);
} }

Loading…
Cancel
Save