better logging and error reporting

cpp
Avril 4 years ago
parent 801fd7b3fc
commit dba703e503
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -52,6 +52,13 @@ debug: | dirs $(PROJECT)-debug.a
-$(MAKE) dirs -$(MAKE) dirs
$(MAKE) $(PROJECT)-debug.so $(MAKE) $(PROJECT)-debug.so
# Rebuild both release and debug targets from scratch
.PHONY: all
all: | clean
-$(MAKE) release
-$(MAKE) clean-rebuild
-$(MAKE) debug
# Targets # Targets
dirs: dirs:

@ -39,6 +39,7 @@ struct Cow {
struct Cow::Fake : Cow { struct Cow::Fake : Cow {
Fake() = delete; Fake() = delete;
Fake(const Cow& real);
Fake(const Fake& copy); Fake(const Fake& copy);
Fake(Fake&& move); Fake(Fake&& move);
~Fake(); ~Fake();
@ -50,7 +51,6 @@ struct Cow::Fake : Cow {
protected: protected:
cow_t* get_raw() const override; cow_t* get_raw() const override;
private: private:
Fake(const Cow& real);
cow_t* const fake; cow_t* const fake;
}; };

@ -2,23 +2,35 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <assert.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <limits.h> #include <limits.h>
#include <stddef.h> #include <stddef.h>
#include <errno.h>
#include <cow.h> #include <cow.h>
#define LIKELY(ex) __builtin_expect(!!(ex), 1)
#define UNLIKELY(ex) __builtin_expect(!!(ex), 0)
#define box(t) aligned_alloc(_Alignof(t), sizeof(t)) #define box(t) aligned_alloc(_Alignof(t), sizeof(t))
#if defined(DEBUG) || defined(COW_TRACE) #if defined(DEBUG) || defined(COW_TRACE)
#define TRACE(msg, ...) (fprintf(stderr, "[TRACE] %s->%s %d: " msg "\n", __FILE__, __func__, __LINE__, __VA_ARGS__), (void)0) #define TRACE(msg, ...) (fprintf(stderr, "<libcow> [TRACE] %s->%s():%d: " msg "\n", __FILE__, __func__, __LINE__, __VA_ARGS__), (void)0)
#else #else
#define TRACE(msg, ...) ((void)0) #define TRACE(msg, ...) ((void)0)
#endif #endif
#if !defined(COW_NO_ASSERT)
#define ASSERT(expr, msg) do { if(!(expr)) die("assertion failed: `" #expr "`: " msg); } while(0)
#else
#define ASSERT(op, msg) ((void)0)
#endif
#define LASSERT(expr, msg) ASSERT(LIKELY(expr), "(unexpected) " msg)
#define UASSERT(expr, msg) ASSERT(UNLIKELY(expr), "(expected) " msg)
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.
@ -30,8 +42,13 @@ _Static_assert(offsetof(cow_t, origin) == 0, "`cow_t.origin` must have an offset
static __attribute__((noreturn)) __attribute__((noinline)) __attribute__((cold)) void die(const char* error) static __attribute__((noreturn)) __attribute__((noinline)) __attribute__((cold)) void die(const char* error)
{ {
perror(error); fprintf(stderr, "<libcow> [FATAL]: ");
exit(1); if(!errno)
fprintf(stderr, "%s\n (no matching errno, try compiling with `-DCOW_TRACE` and/or `-DDEBUG`)\n", error);
else
perror(error);
abort();
} }
static inline cow_t* box_value(cow_t v) static inline cow_t* box_value(cow_t v)
@ -39,6 +56,8 @@ 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)); 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;
LASSERT(cow_ptr(boxed) == boxed->origin, "ptr extraction mismatch. this should never happen (check origin field offset)");
return boxed; return boxed;
} }
@ -81,7 +100,7 @@ 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); TRACE("mapped new origin cow page of %lu size at %p (memfd %d)", size, ret.origin, ret.fd);
return box_value(ret); return box_value(ret);
} }

@ -4,9 +4,9 @@ int main()
{ {
Cow real(4096); Cow real(4096);
Cow::Fake clone = real.clone(); Cow::Fake clone = real;
{ {
Cow::Fake clone2 = clone.clone(); Cow::Fake clone2 = clone;
} }
return 0; return 0;
} }

Loading…
Cancel
Save