Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion deps/dice
Submodule dice updated 54 files
+3 −1 .github/workflows/actions-smolbsd.yml
+8 −1 .github/workflows/actions.yml
+2 −0 CMakeLists.txt
+2 −23 README.md
+1 −1 bench/raytracing/patches/reduce-samples.patch
+2 −0 bench/scratchapixel/Makefile
+1 −1 include/dice/chains/capture.h
+1 −1 include/dice/chains/intercept.h
+1 −1 include/dice/compiler.h
+1 −1 include/dice/dispatch.h
+58 −0 include/dice/events/annotate_rwlock.h
+1 −1 include/dice/events/cxa.h
+1 −1 include/dice/events/malloc.h
+10 −1 include/dice/events/memaccess.h
+38 −0 include/dice/events/memcpy.h
+1 −1 include/dice/events/mman.h
+1 −1 include/dice/events/pthread.h
+1 −1 include/dice/events/self.h
+1 −1 include/dice/events/semaphore.h
+1 −1 include/dice/events/stacktrace.h
+1 −1 include/dice/events/thread.h
+1 −1 include/dice/handler.h
+1 −1 include/dice/interpose.h
+1 −1 include/dice/log.h
+1 −1 include/dice/mempool.h
+1 −1 include/dice/module.h
+1 −1 include/dice/now.h
+2 −26 include/dice/pubsub.h
+1 −1 include/dice/rbtree.h
+1 −1 include/dice/self.h
+1 −1 include/dice/thread_id.h
+36 −0 include/dice/types.h
+0 −3 scripts/dice
+4 −1 src/mod/CMakeLists.txt
+63 −0 src/mod/annotate_rwlock.c
+0 −37 src/mod/autocept.c
+0 −12 src/mod/autocept.h
+0 −71 src/mod/autocept_aarch64.S
+0 −79 src/mod/autocept_generic.S
+0 −30 src/mod/autocept_list.S
+0 −77 src/mod/autocept_x86_64.S
+61 −0 src/mod/memcpy.c
+12 −0 test/interpose/CMakeLists.txt
+273 −0 test/interpose/annotate_rwlock_test.c
+1 −1 test/interpose/cxa_test.c
+1 −1 test/interpose/interpose_test.c.in
+33 −0 test/interpose/interposed.h.in
+229 −0 test/interpose/memcpy_test.c
+1 −1 test/interpose/mman_test.c
+1 −1 test/interpose/pthread_cond_test.c
+1 −1 test/interpose/pthread_create_test.c
+1 −1 test/interpose/pthread_mutex_test.c
+1 −1 test/interpose/pthread_rwlock_test.c
+1 −1 test/interpose/sem_test.c
1 change: 1 addition & 0 deletions scripts/coldtrace-check
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ TSANO="$COLDTRACE_ROOT/deps/dice/deps/tsano/tsano"
export COLDTRACE_PATH=/tmp/traces
export COLDTRACE_MAX_FILES=3
export COLDTRACE_DISABLE_COPY=true
export COLDTRACE_DISABLE_WRITES=true
exec $TSANO env LD_PRELOAD="$PRELOAD" "$@"
5 changes: 4 additions & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ math(EXPR PRIO_subs_pthread "${COLDTRACE_BASE_PRIO} + 5")
math(EXPR PRIO_subs_malloc "${COLDTRACE_BASE_PRIO} + 6")
math(EXPR PRIO_subs_cxa "${COLDTRACE_BASE_PRIO} + 7")
math(EXPR PRIO_subs_mman "${COLDTRACE_BASE_PRIO} + 8")
math(EXPR PRIO_subs_annotate_rwlock "${COLDTRACE_BASE_PRIO} + 9")

set(CMAKE_INTERPROCEDURAL_OPTIMIZATION true)

Expand All @@ -34,7 +35,8 @@ set(SRCS
subs_pthread.c
subs_malloc.c
subs_mman.c
subs_cxa.c)
subs_cxa.c
subs_annotate_rwlock.c)

set(MODS)
foreach(SRC ${SRCS})
Expand Down Expand Up @@ -67,6 +69,7 @@ set(MODS
dice-cxa.o
dice-tsan.o
dice-stacktrace.o
dice-annotate_rwlock.o
dice.o)

add_library(coldtrace SHARED)
Expand Down
43 changes: 43 additions & 0 deletions src/subs_annotate_rwlock.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (C) 2025 Huawei Technologies Co., Ltd.
* SPDX-License-Identifier: MIT
*/
#include <coldtrace/counters.h>
#include <coldtrace/thread.h>
#include <dice/events/annotate_rwlock.h>
#include <dice/module.h>

DICE_MODULE_INIT();

PS_SUBSCRIBE(CAPTURE_EVENT, EVENT_ANNOTATE_RWLOCK_CREATE, {
struct AnnotateRWLockCreate_event *ev = EVENT_PAYLOAD(ev);

struct coldtrace_atomic_entry *e = coldtrace_thread_append(
md, COLDTRACE_RW_LOCK_CREATE, (void *)ev->lock);
e->atomic_index = coldtrace_next_atomic_idx();
})

PS_SUBSCRIBE(CAPTURE_EVENT, EVENT_ANNOTATE_RWLOCK_DESTROY, {
struct AnnotateRWLockDestroy_event *ev = EVENT_PAYLOAD(ev);

struct coldtrace_atomic_entry *e = coldtrace_thread_append(
md, COLDTRACE_RW_LOCK_DESTROY, (void *)ev->lock);
e->atomic_index = coldtrace_next_atomic_idx();
})

PS_SUBSCRIBE(CAPTURE_EVENT, EVENT_ANNOTATE_RWLOCK_ACQ, {
struct AnnotateRWLockAcquired_event *ev = EVENT_PAYLOAD(ev);

struct coldtrace_atomic_entry *e = coldtrace_thread_append(
md, ev->is_w?COLDTRACE_RW_LOCK_ACQ_EXC:COLDTRACE_RW_LOCK_ACQ_SHR, (void *)ev->lock);

e->atomic_index = coldtrace_next_atomic_idx();
})
PS_SUBSCRIBE(CAPTURE_EVENT, EVENT_ANNOTATE_RWLOCK_REL, {
struct AnnotateRWLockReleased_event *ev = EVENT_PAYLOAD(ev);

struct coldtrace_atomic_entry *e = coldtrace_thread_append(
md, ev->is_w?COLDTRACE_RW_LOCK_REL_EXC:COLDTRACE_RW_LOCK_REL_SHR, (void *)ev->lock);

e->atomic_index = coldtrace_next_atomic_idx();
})
51 changes: 34 additions & 17 deletions src/writer.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <coldtrace/writer.h>
#include <dice/compiler.h>
#include <dice/log.h>
#include <dice/mempool.h>
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
Expand All @@ -25,15 +26,20 @@ struct writer_impl {
static void
get_trace_(struct writer_impl *impl)
{
if (coldtrace_writes_disabled())
return;
assert(impl->initd);
if (impl->buffer) {
return;
}
impl->enumerator = 0;
impl->size = coldtrace_get_trace_size();
impl->offset = 0;

impl->size = coldtrace_get_trace_size();
impl->offset = 0;
impl->enumerator = 0;

if (coldtrace_writes_disabled()) {
impl->buffer = mempool_alloc(impl->size);
return;
}

const char *pattern = coldtrace_get_file_pattern();
char file_name[strlen(pattern) + 20];
sprintf(file_name, pattern, impl->tid, impl->enumerator);
Expand All @@ -59,10 +65,19 @@ get_trace_(struct writer_impl *impl)
static void
new_trace_(struct writer_impl *impl)
{
if (coldtrace_writes_disabled())
if (coldtrace_writes_disabled()) {
size_t trace_size = coldtrace_get_trace_size();
if (impl->size != trace_size) {
impl->size = trace_size;
mempool_free(impl->buffer);
impl->buffer = mempool_alloc(impl->size);
}
impl->offset = 0;
return;
}
coldtrace_writer_close(impl->buffer, impl->offset, impl->tid);
munmap(impl->buffer, impl->size);

impl->enumerator = (impl->enumerator + 1) % coldtrace_get_max();
impl->size = coldtrace_get_trace_size();
impl->offset = 0;
Expand All @@ -83,15 +98,12 @@ new_trace_(struct writer_impl *impl)


DICE_HIDE void *
coldtrace_writer_reserve(struct coldtrace_writer *ct, size_t size)
coldtrace_writer_reserve(struct coldtrace_writer *writer, size_t size)
{
if (coldtrace_writes_disabled())
return NULL;

struct writer_impl *impl = (struct writer_impl *)ct;
struct writer_impl *impl = (struct writer_impl *)writer;
get_trace_(impl);
if (impl->buffer == MAP_FAILED) {
return false;
if (impl->buffer == MAP_FAILED || impl->buffer == NULL) {
return NULL;
}

// check if size of trace was reduced
Expand All @@ -107,7 +119,7 @@ coldtrace_writer_reserve(struct coldtrace_writer *ct, size_t size)
}
}

char *ptr = (char *)(impl->buffer + impl->offset / sizeof(uint64_t));
char *ptr = (char *)(impl->buffer) + impl->offset;
impl->offset += size;
return ptr;
}
Expand All @@ -118,9 +130,11 @@ coldtrace_writer_init(struct coldtrace_writer *ct, uint64_t id)
// Ensure the size of implementation matches the public size
assert(sizeof(struct writer_impl) == sizeof(struct coldtrace_writer));
struct writer_impl *impl;
impl = (struct writer_impl *)ct;
impl->initd = true;
impl->tid = id;
impl = (struct writer_impl *)ct;
impl->initd = true;
impl->tid = id;
impl->buffer = NULL;
impl->size = 0;
}

DICE_HIDE void
Expand All @@ -130,6 +144,9 @@ coldtrace_writer_fini(struct coldtrace_writer *ct)
if (!impl->initd)
return;
coldtrace_writer_close(impl->buffer, impl->offset, impl->tid);

if (coldtrace_writes_disabled())
mempool_free(impl->buffer);
}


Expand Down
1 change: 1 addition & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
include_directories(../src)
include_directories(checkers)
include_directories(../deps/dice/test/include)

add_library(trace_checker SHARED checkers/trace_checker.c)
target_link_libraries(trace_checker PUBLIC vsync coldtrace-unboxed)
Expand Down
86 changes: 78 additions & 8 deletions test/checkers/trace_checker.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@
#include <coldtrace/config.h>
#include <coldtrace/entries.h>
#include <dice/chains/capture.h>
#include <dice/ensure.h>
#include <dice/log.h>
#include <dice/module.h>
#include <dice/self.h>
#include <vsync/spinlock/caslock.h>

#define MAX_NTHREADS 128
#define MAX_ENTRY_CALLBACKS 100
Expand Down Expand Up @@ -104,6 +106,78 @@ iter_type(struct entry_it it)
return coldtrace_entry_parse_type(it.buf);
}

static void _check_next(coldtrace_entry_type type, struct expected_entry **exp,
uint64_t tid, int i);
static void
_check_strict(coldtrace_entry_type type, struct expected_entry **exp,
uint64_t tid, int i)
{
struct expected_entry *e = *exp;
bool mismatch = (type != e->type);
// no matched and required
if (mismatch && e->atleast > 0) {
log_fatal("thread=%lu entry=%d found=%s expected=%s", tid, i,
coldtrace_entry_type_str(type),
coldtrace_entry_type_str(e->type));
// not matched advance pointer and check the next one
} else if (mismatch) {
// if next is required
struct expected_entry *next = e + 1;
if (next->set && next->atleast > 0 && type == next->type) {
(*exp)++; // skip optional
_check_next(type, exp, tid, i);
return;
}
(*exp)++; // advance pointer
log_warn("%lu event mismatch (go to next)", tid);
_check_next(type, exp, tid, i);
return;
}
// matched
log_info("thread=%lu entry=%d match=%s", tid, i,
coldtrace_entry_type_str(e->type));
// if it was required make it optional
if (e->atleast > 0)
e->atleast--;
// if it has more ocuurencies left next
if (e->atmost-- == 1)
(*exp)++;
}
static void
_check_wildcard(coldtrace_entry_type type, struct expected_entry **exp,
uint64_t tid, int i)
{
struct expected_entry *e = *exp;
struct expected_entry *next = e + 1;
// see the next if required
if (next->set && next->atleast > 0 && type == next->type) {
(*exp)++; // skip wildcard
_check_next(type, exp, tid, i);
return;
}
/// just match it
log_info("thread=%lu entry=%d wildcard match=%s", tid, i,
coldtrace_entry_type_str(e->type));
ensure(e->atleast == e->atmost);
ensure(e->atleast == 1);
(*exp)++;
}

static void
_check_next(coldtrace_entry_type type, struct expected_entry **exp,
uint64_t tid, int i)
{
struct expected_entry *e = *exp;
// wild false
if (!e->wild) {
_check_strict(type, exp, tid, i);
// wild true
} else {
_check_wildcard(type, exp, tid, i);
}
}


// -----------------------------------------------------------------------------
// trace checker
// -----------------------------------------------------------------------------
Expand All @@ -112,13 +186,15 @@ iter_type(struct entry_it it)
void
coldtrace_writer_close(void *page, const size_t size, uint64_t tid)
{
static caslock_t loop_lock = CASLOCK_INIT();
log_info("checking thread=%lu", tid);
struct entry_it it = iter_init(page, size);
struct expected_entry *next = _expected[tid];

if (_close_callback)
_close_callback(page, size);

caslock_acquire(&loop_lock);
for (int i = 0; iter_next(it); iter_advance(&it), i++) {
coldtrace_entry_type type = iter_type(it);

Expand All @@ -132,17 +208,11 @@ coldtrace_writer_close(void *page, const size_t size, uint64_t tid)
log_fatal("thread=%lu entry=%d found=%s but trace empty", tid, i,
coldtrace_entry_type_str(type));

if ((type != next->type))
log_fatal("thread=%lu entry=%d found=%s expected=%s", tid, i,
coldtrace_entry_type_str(type),
coldtrace_entry_type_str(next->type));

log_info("thread=%lu entry=%d match=%s", tid, i,
coldtrace_entry_type_str(next->type));
next++;
_check_next(type, &next, tid, i);
}
if (next && next->set)
log_fatal("expected trace is not empty");
caslock_release(&loop_lock);
}

PS_SUBSCRIBE(CAPTURE_EVENT, EVENT_SELF_FINI, {
Expand Down
22 changes: 20 additions & 2 deletions test/checkers/trace_checker.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ extern "C" {
#endif

#include <coldtrace/entries.h>
#include <dice/pubsub.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
Expand All @@ -19,17 +20,34 @@ extern "C" {
struct expected_entry {
coldtrace_entry_type type;
bool set;
unsigned atleast;
unsigned atmost;
bool wild;
};

#define EXPECT_ENTRY(TYPE) \
(struct expected_entry) \
{ \
.type = TYPE, .set = true, \
.type = TYPE, .set = true, .atleast = 1, .atmost = 1, .wild = false, \
}
#define EXPECT_SUFFIX(TYPE) \
(struct expected_entry) \
{ \
.type = TYPE, .set = true, .atleast = 1, .atmost = 1, .wild = true, \
}
#define EXPECT_SOME(TYPE, ATLEAST, ATMOST) \
(struct expected_entry) \
{ \
.type = TYPE, .set = true, .atleast = ATLEAST, .atmost = ATMOST, \
.wild = false, \
}

#define EXPECTED_ANY_SUFFIX EXPECTED_SUFFIX(0, 0)

#define EXPECT_END \
(struct expected_entry) \
{ \
.type = 0, .set = false, \
.type = 0, .set = false, .atleast = 0, .atmost = 0, .wild = false, \
}


Expand Down
8 changes: 3 additions & 5 deletions test/trace_alloc_free.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@


struct expected_entry expected_1[] = {
#if !defined(__clang__)
EXPECT_ENTRY(COLDTRACE_ALLOC),
EXPECT_ENTRY(COLDTRACE_FREE),
#endif
EXPECT_ENTRY(COLDTRACE_ALLOC),
EXPECT_ENTRY(COLDTRACE_WRITE),
EXPECT_SOME(COLDTRACE_FREE, 0, 1),
EXPECT_SOME(COLDTRACE_ALLOC, 0, 1),
EXPECT_SOME(COLDTRACE_WRITE, 0, 1),
EXPECT_ENTRY(COLDTRACE_FREE),
EXPECT_ENTRY(COLDTRACE_THREAD_EXIT),
EXPECT_END,
Expand Down
Loading
Loading