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 src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,4 @@ target_link_libraries(coldtrace PUBLIC ${MODS} dice-box.o dice-dispatch.o
# useful for testing (allows loading additional shared libraries)
add_library(coldtrace-unboxed SHARED)
target_link_libraries(coldtrace-unboxed PUBLIC vsync dice.h dl)
target_link_libraries(coldtrace-unboxed PUBLIC ${MODS} dice-dispatch.o writer.o)
target_link_libraries(coldtrace-unboxed PUBLIC ${MODS} writer.o)
9 changes: 6 additions & 3 deletions src/subs_cxa.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,22 @@
DICE_MODULE_INIT()

PS_SUBSCRIBE(CAPTURE_AFTER, EVENT_CXA_GUARD_ACQUIRE, {
struct __cxa_guard_acquire_event *ev = EVENT_PAYLOAD(ev);
struct coldtrace_atomic_entry *e =
coldtrace_thread_append(md, COLDTRACE_CXA_GUARD_ACQUIRE, event);
coldtrace_thread_append(md, COLDTRACE_CXA_GUARD_ACQUIRE, ev->addr);
e->atomic_index = coldtrace_next_atomic_idx();
})

PS_SUBSCRIBE(CAPTURE_BEFORE, EVENT_CXA_GUARD_RELEASE, {
struct __cxa_guard_release_event *ev = EVENT_PAYLOAD(ev);
struct coldtrace_atomic_entry *e =
coldtrace_thread_append(md, COLDTRACE_CXA_GUARD_RELEASE, event);
coldtrace_thread_append(md, COLDTRACE_CXA_GUARD_RELEASE, ev->addr);
e->atomic_index = coldtrace_next_atomic_idx();
})

PS_SUBSCRIBE(CAPTURE_BEFORE, EVENT_CXA_GUARD_ABORT, {
struct __cxa_guard_abort_event *ev = EVENT_PAYLOAD(ev);
struct coldtrace_atomic_entry *e =
coldtrace_thread_append(md, COLDTRACE_CXA_GUARD_RELEASE, event);
coldtrace_thread_append(md, COLDTRACE_CXA_GUARD_RELEASE, ev->addr);
e->atomic_index = coldtrace_next_atomic_idx();
})
2 changes: 1 addition & 1 deletion src/subs_tsan.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ area_t areas_[AREAS];
e->atomic_index = idx_b; \
}

#define REL_LOG_FENCE(addr) \
#define REL_LOG_FENCE(addr) \
area_t *area = get_area(addr); \
uint64_t idx_a = area->idx_a; \
caslock_release(&area->lock); \
Expand Down
2 changes: 1 addition & 1 deletion src/thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ get_coldtrace_thread(metadata_t *md)
static inline bool
with_stack_(coldtrace_entry_type type)
{
switch (type) {
switch (type & ~ZERO_FLAG) {
case COLDTRACE_FREE:
case COLDTRACE_ALLOC:
case COLDTRACE_MMAP:
Expand Down
12 changes: 8 additions & 4 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ include_directories(../src)
include_directories(checkers)
include_directories(../deps/dice/test/include)

include_directories(../deps/dice/include)

add_library(trace_checker SHARED checkers/trace_checker.c)
target_link_libraries(trace_checker PUBLIC vsync coldtrace-unboxed)
target_link_libraries(trace_checker PRIVATE vsync coldtrace-unboxed)
add_library(trace_checker_mock SHARED checkers/trace_checker_mock.c)
target_link_libraries(trace_checker_mock PRIVATE vsync)

set(OPTIONS_atomic_test -ensure-traces)
set(OPTIONS_spinlock -ensure-traces)
Expand All @@ -22,7 +26,7 @@ foreach(SRC ${SRCS})
target_link_libraries(${TARGET} PRIVATE tsano vsync pthread)

if(${TARGET} MATCHES "^trace_.*")
target_link_libraries(${TARGET} PRIVATE trace_checker)
target_link_libraries(${TARGET} PRIVATE trace_checker_mock)
add_test(NAME ${TARGET}-test
COMMAND ${PROJECT_SOURCE_DIR}/scripts/coldtrace-check ./${TARGET})
else()
Expand All @@ -34,5 +38,5 @@ foreach(SRC ${SRCS})
./${TARGET})
endif()
endforeach()
target_compile_options(trace_fence PRIVATE -fsanitize=thread -Wno-error=tsan -Wno-unknown-warning-option)

target_compile_options(trace_fence PRIVATE -fsanitize=thread -Wno-error=tsan
-Wno-unknown-warning-option)
37 changes: 32 additions & 5 deletions test/checkers/trace_checker.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#ifndef LOG_LEVEL
#define LOG_LEVEL INFO
#endif
#define TRACE_CHECKER_IMPL

#include "trace_checker.h"

Expand Down Expand Up @@ -212,6 +213,9 @@ _check_strict(coldtrace_entry_type type, uint64_t ptr_value,
// if it was required make it optional
if (iter->atleast > 0)
(iter->atleast)--;
// if atmost 0 make infinity
if (iter->atmost == 0)
return;
// if it has more ocuurencies left next
if ((iter->atmost)-- == 1)
next_entry_and_reset(iter);
Expand All @@ -221,16 +225,39 @@ _check_wildcard(coldtrace_entry_type type, uint64_t ptr_value,
struct next_expected_entry_iterator *iter, uint64_t tid, int i)
{
struct expected_entry *wild = (iter->e);
// if current matches the wildcard
if (type == wild->type) {

if (type != wild->type) {
// no wildcard match yet
log_info("thread=%lu entry=%d mismatch: looking for wildcard=%s", tid,
i, coldtrace_entry_type_str(wild->type));
return;
}
// wildcard match
if (wild->check == NO_CHECK) {
log_info("thread=%lu entry=%d wildcard match=%s", tid, i,
coldtrace_entry_type_str(wild->type));
next_entry_and_reset(iter);
return;
}
// check the ptr
uint64_t *check_val = &_entry_ptr_values[wild->check];
if (*check_val == CHECK_UNINITIALIZED) {
*check_val = ptr_value;
log_info("thread=%lu entry=%d wildcard match=%s match=ptr=%lu", tid, i,
coldtrace_entry_type_str(wild->type), ptr_value);
next_entry_and_reset(iter);
} else if (*check_val == ptr_value) {
// ptr match
log_info("thread=%lu entry=%d wildcard match=%s match=ptr=%lu", tid, i,
coldtrace_entry_type_str(wild->type), ptr_value);
next_entry_and_reset(iter);
} else {
// no wildcard match yet
log_info("thread=%lu entry=%d mismatch: looking for wildcard=%s", tid,
i, coldtrace_entry_type_str(wild->type));
// ptr mismatch
log_fatal(
"thread=%lu entry=%d match=%s wildcard pointer mismatch found=%lu "
"expected=%lu",
tid, i, coldtrace_entry_type_str(wild->type), ptr_value,
*check_val);
}
}

Expand Down
36 changes: 25 additions & 11 deletions test/checkers/trace_checker.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#ifndef TRACE_CHECKER_H
#define TRACE_CHECKER_H

#include "dice/compiler.h"
#ifdef __cplusplus
extern "C" {
#endif
Expand All @@ -27,11 +28,12 @@ struct expected_entry {
};

#define EXPECT_ENTRY(TYPE) \
(struct expected_entry) \
{ \
.type = TYPE, .set = true, .atleast = 1, .atmost = 1, .wild = false, \
.check = -1 \
}
(struct expected_entry){.type = TYPE, \
.set = true, \
.atleast = 1, \
.atmost = 1, \
.wild = false, \
.check = -1}
#define EXPECT_VALUE(TYPE, CHECK) \
(struct expected_entry) \
{ \
Expand All @@ -44,22 +46,34 @@ struct expected_entry {
.type = TYPE, .set = true, .atleast = 1, .atmost = 1, .wild = true, \
.check = -1, \
}
#define EXPECT_SUFFIX_VALUE(TYPE, CHECK) \
(struct expected_entry) \
{ \
.type = TYPE, .set = true, .atleast = 1, .atmost = 1, .wild = true, \
.check = CHECK, \
}
#define EXPECT_SOME(TYPE, ATLEAST, ATMOST) \
(struct expected_entry) \
{ \
.type = TYPE, .set = true, .atleast = ATLEAST, .atmost = ATMOST, \
.wild = false, .check = -1, \
}

#define EXPECTED_ANY_SUFFIX EXPECTED_SUFFIX(0, 0)

#define EXPECT_END \
#define EXPECT_SOME_VALUE(TYPE, ATLEAST, ATMOST, CHECK) \
(struct expected_entry) \
{ \
.type = 0, .set = false, .atleast = 0, .atmost = 0, .wild = false, \
.check = -1 \
.type = TYPE, .set = true, .atleast = ATLEAST, .atmost = ATMOST, \
.wild = false, .check = CHECK, \
}

#define EXPECTED_ANY_SUFFIX EXPECT_SUFFIX(0, 0)

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

void register_expected_trace(uint64_t tid, struct expected_entry *trace);
void register_entry_callback(void (*callback)(const void *entry));
Expand Down
23 changes: 23 additions & 0 deletions test/checkers/trace_checker_mock.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include "trace_checker.h"

DICE_WEAK
void
register_expected_trace(uint64_t tid, struct expected_entry *trace)
{
abort();
}
DICE_WEAK
void
register_entry_callback(void (*callback)(const void *entry))
{
}
DICE_WEAK
void
register_close_callback(void (*callback)(const void *page, size_t size))
{
}
DICE_WEAK
void
register_final_callback(void (*callback)(void))
{
}
10 changes: 5 additions & 5 deletions test/trace_alloc_free.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@

struct expected_entry expected_1[] = {

EXPECT_ENTRY(COLDTRACE_ALLOC),
EXPECT_SOME(COLDTRACE_FREE, 0, 1),
EXPECT_SOME(COLDTRACE_ALLOC, 0, 1),
EXPECT_SOME(COLDTRACE_WRITE, 0, 1),
EXPECT_ENTRY(COLDTRACE_FREE),
EXPECT_VALUE(COLDTRACE_ALLOC, 0),
EXPECT_SOME_VALUE(COLDTRACE_FREE, 0, 1, 0),
EXPECT_SOME_VALUE(COLDTRACE_ALLOC, 0, 1, 1),
EXPECT_SOME_VALUE(COLDTRACE_WRITE, 0, 1, 1),
EXPECT_VALUE(COLDTRACE_FREE, 1),
EXPECT_ENTRY(COLDTRACE_THREAD_EXIT),
EXPECT_END,
};
Expand Down
40 changes: 20 additions & 20 deletions test/trace_atomic.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include "coldtrace/entries.h"
#include <atomic>
#include <cstdio>
#include <cstdlib>
Expand All @@ -10,28 +11,28 @@
#define ATOMIC_RW_CYCLE \
EXPECT_VALUE(COLDTRACE_ATOMIC_READ, 5), \
EXPECT_VALUE(COLDTRACE_ATOMIC_WRITE, 5), \
EXPECT_SOME(COLDTRACE_READ, 0, 1), EXPECT_SOME(COLDTRACE_WRITE, 0, 1)
EXPECT_SOME_VALUE(COLDTRACE_READ, 0, 1, 6), EXPECT_SOME_VALUE(COLDTRACE_WRITE, 0, 1, 6)

struct expected_entry expected_1[] = {
EXPECT_SOME(COLDTRACE_ALLOC, 0, 1),
EXPECT_SOME(COLDTRACE_WRITE, 0, 1),
EXPECT_SOME(COLDTRACE_FREE, 0, 1),
EXPECT_SOME(COLDTRACE_ALLOC, 0, 1),
EXPECT_SOME(COLDTRACE_WRITE, 0, 1),
EXPECT_VALUE(COLDTRACE_THREAD_CREATE, 1),
EXPECT_SOME_VALUE(COLDTRACE_ALLOC, 0, 1, 0),
EXPECT_SOME_VALUE(COLDTRACE_WRITE, 0, 1, 0),
EXPECT_SOME_VALUE(COLDTRACE_FREE, 0, 1, 0),
EXPECT_SOME_VALUE(COLDTRACE_ALLOC, 0, 1, 1),
EXPECT_SOME_VALUE(COLDTRACE_WRITE, 0, 1, 1),
EXPECT_VALUE(COLDTRACE_THREAD_CREATE, 2),
EXPECT_VALUE(COLDTRACE_THREAD_CREATE, 3),
EXPECT_SOME(COLDTRACE_READ, 0, 1),
EXPECT_VALUE(COLDTRACE_THREAD_JOIN, 1),
EXPECT_VALUE(COLDTRACE_THREAD_CREATE, 4),
EXPECT_SOME(COLDTRACE_READ, 0, 1),
EXPECT_VALUE(COLDTRACE_THREAD_JOIN, 2),
EXPECT_SOME(COLDTRACE_READ, 0, 1),
EXPECT_VALUE(COLDTRACE_THREAD_JOIN, 3),
EXPECT_SOME(COLDTRACE_READ, 0, 1),
EXPECT_VALUE(COLDTRACE_THREAD_JOIN, 4),
EXPECT_ENTRY(COLDTRACE_THREAD_EXIT),
EXPECT_END,
};
struct expected_entry expected_2[] = {
EXPECT_VALUE(COLDTRACE_THREAD_START, 1),
EXPECT_VALUE(COLDTRACE_THREAD_START, 2),
ATOMIC_RW_CYCLE,
ATOMIC_RW_CYCLE,
ATOMIC_RW_CYCLE,
Expand All @@ -42,12 +43,12 @@ struct expected_entry expected_2[] = {
ATOMIC_RW_CYCLE,
ATOMIC_RW_CYCLE,
ATOMIC_RW_CYCLE,
EXPECT_VALUE(COLDTRACE_THREAD_EXIT, 1),
EXPECT_VALUE(COLDTRACE_THREAD_EXIT, 2),
EXPECT_END,
};

struct expected_entry expected_3[] = {
EXPECT_VALUE(COLDTRACE_THREAD_START, 2),
EXPECT_VALUE(COLDTRACE_THREAD_START, 3),
ATOMIC_RW_CYCLE,
ATOMIC_RW_CYCLE,
ATOMIC_RW_CYCLE,
Expand All @@ -58,18 +59,17 @@ struct expected_entry expected_3[] = {
ATOMIC_RW_CYCLE,
ATOMIC_RW_CYCLE,
ATOMIC_RW_CYCLE,
EXPECT_VALUE(COLDTRACE_THREAD_EXIT, 2),
EXPECT_VALUE(COLDTRACE_THREAD_EXIT, 3),
EXPECT_END,
};

struct expected_entry expected_4[] = {
EXPECT_VALUE(COLDTRACE_THREAD_START, 3),
EXPECT_VALUE(COLDTRACE_ATOMIC_READ, 5),
EXPECT_SOME(COLDTRACE_ATOMIC_READ, 0, 3000),
EXPECT_SOME(COLDTRACE_READ, 0, 1),
EXPECT_SOME(COLDTRACE_ALLOC, 0, 1),
EXPECT_SOME(COLDTRACE_FREE, 0, 1),
EXPECT_VALUE(COLDTRACE_THREAD_EXIT, 3),
EXPECT_VALUE(COLDTRACE_THREAD_START, 4),
EXPECT_SOME_VALUE(COLDTRACE_ATOMIC_READ, 1, 0, 5),
EXPECT_SOME_VALUE(COLDTRACE_READ, 0, 1, 6),
EXPECT_SOME_VALUE(COLDTRACE_ALLOC, 0, 1, 7),
EXPECT_SOME_VALUE(COLDTRACE_FREE, 0, 1, 6),
EXPECT_VALUE(COLDTRACE_THREAD_EXIT, 4),
EXPECT_END,
};

Expand Down
29 changes: 14 additions & 15 deletions test/trace_cxa_guard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,30 @@
#define NUM_THREADS 2

struct expected_entry expected_1[] = {
EXPECT_SUFFIX(COLDTRACE_THREAD_CREATE),
EXPECT_SUFFIX(COLDTRACE_THREAD_CREATE),
EXPECT_SUFFIX(COLDTRACE_THREAD_JOIN),
EXPECT_SUFFIX(COLDTRACE_THREAD_JOIN),
EXPECT_SUFFIX_VALUE(COLDTRACE_THREAD_CREATE, 0),
EXPECT_SUFFIX_VALUE(COLDTRACE_THREAD_CREATE, 1),
EXPECT_SUFFIX_VALUE(COLDTRACE_THREAD_JOIN, 0),
EXPECT_SUFFIX_VALUE(COLDTRACE_THREAD_JOIN, 1),
EXPECT_SUFFIX(COLDTRACE_THREAD_EXIT),
EXPECT_END,
};

struct expected_entry expected_2[] = {
EXPECT_ENTRY(COLDTRACE_THREAD_START),
EXPECT_ENTRY(COLDTRACE_ATOMIC_READ),
EXPECT_VALUE(COLDTRACE_THREAD_START, 0),
EXPECT_VALUE(COLDTRACE_ATOMIC_READ, 2),
EXPECT_SOME(COLDTRACE_READ, 0, 1),
EXPECT_ENTRY(COLDTRACE_CXA_GUARD_ACQUIRE),
EXPECT_SUFFIX(COLDTRACE_CXA_GUARD_RELEASE),
EXPECT_ENTRY(COLDTRACE_READ),
EXPECT_ENTRY(COLDTRACE_FREE),
EXPECT_ENTRY(COLDTRACE_THREAD_EXIT),
EXPECT_SOME_VALUE(COLDTRACE_CXA_GUARD_ACQUIRE, 0, 1, 2),
EXPECT_SOME_VALUE(COLDTRACE_CXA_GUARD_RELEASE, 0, 1, 2),
EXPECT_SUFFIX_VALUE(COLDTRACE_THREAD_EXIT, 0),
EXPECT_END,
};

struct expected_entry expected_3[] = {
EXPECT_ENTRY(COLDTRACE_THREAD_START),
EXPECT_ENTRY(COLDTRACE_ATOMIC_READ),
EXPECT_SOME(COLDTRACE_CXA_GUARD_ACQUIRE, 0, 1),
EXPECT_SUFFIX(COLDTRACE_THREAD_EXIT),
EXPECT_VALUE(COLDTRACE_THREAD_START, 1),
EXPECT_VALUE(COLDTRACE_ATOMIC_READ, 2),
EXPECT_SOME_VALUE(COLDTRACE_CXA_GUARD_ACQUIRE, 0, 1, 2),
EXPECT_SOME_VALUE(COLDTRACE_CXA_GUARD_RELEASE, 0, 1, 2),
EXPECT_SUFFIX_VALUE(COLDTRACE_THREAD_EXIT, 1),
EXPECT_END,
};

Expand Down