From 85be7a50fb7d7d7fc36db1bfeda6061833c24b21 Mon Sep 17 00:00:00 2001 From: Felix Moessbauer Date: Tue, 28 Apr 2020 19:21:34 +0200 Subject: [PATCH] feat: add printer detector to trace calls to the detector API --- README.md | 1 + drace-client/detectors/CMakeLists.txt | 1 + drace-client/detectors/printer/CMakeLists.txt | 17 +++ drace-client/detectors/printer/printer.cpp | 113 ++++++++++++++++++ standalone/binarydecoder/DetectorOutput.h | 16 +-- 5 files changed, 140 insertions(+), 8 deletions(-) create mode 100644 drace-client/detectors/printer/CMakeLists.txt create mode 100644 drace-client/detectors/printer/printer.cpp diff --git a/README.md b/README.md index 4ed2c8b..118b8a1 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,7 @@ DRace is shipped with the following detector backends: - tsan (internal ThreadSanitizer) - fasttrack (note: experimental) - dummy (no detection at all) +- printer (print all calls to the detector) #### tsan diff --git a/drace-client/detectors/CMakeLists.txt b/drace-client/detectors/CMakeLists.txt index 7e6853d..80e0ed9 100644 --- a/drace-client/detectors/CMakeLists.txt +++ b/drace-client/detectors/CMakeLists.txt @@ -9,6 +9,7 @@ # the LICENSE file in the top-level directory. add_subdirectory("dummy") +add_subdirectory("printer") if(WIN32) add_subdirectory("tsan") endif() diff --git a/drace-client/detectors/printer/CMakeLists.txt b/drace-client/detectors/printer/CMakeLists.txt new file mode 100644 index 0000000..5c0349f --- /dev/null +++ b/drace-client/detectors/printer/CMakeLists.txt @@ -0,0 +1,17 @@ +# DRace, a dynamic data race detector +# +# Copyright (c) Siemens AG, 2019 +# +# Authors: +# Felix Moessbauer +# +# This work is licensed under the terms of the MIT license. See +# the LICENSE file in the top-level directory. + +message(STATUS "Build detector printer") + +add_library("drace.detector.printer" SHARED "printer") +target_link_libraries("drace.detector.printer" "drace-common") +install(TARGETS "drace.detector.printer" + RUNTIME DESTINATION ${DRACE_RUNTIME_DEST} COMPONENT Runtime + LIBRARY DESTINATION ${DRACE_ARCHIVE_DEST} COMPONENT ARCHIVE) diff --git a/drace-client/detectors/printer/printer.cpp b/drace-client/detectors/printer/printer.cpp new file mode 100644 index 0000000..a04c864 --- /dev/null +++ b/drace-client/detectors/printer/printer.cpp @@ -0,0 +1,113 @@ +/* + * DRace, a dynamic data race detector + * + * Copyright 2018 Siemens AG + * + * Authors: + * Felix Moessbauer + * + * SPDX-License-Identifier: MIT + */ + +#include + +#include + +#ifdef WINDOWS +#define DUMMY_EXPORT __declspec(dllexport) +#else +#define DUMMY_EXPORT +#endif + +namespace drace { +namespace detector { +/// Fake detector that stubs the \ref Detector interface +class Dummy : public Detector { + public: + virtual bool init(int argc, const char** argv, Callback rc_clb) { + return true; + printf("init\n"); + } + + virtual void finalize() { printf("%p | finalize |\n", nullptr); } + + virtual void map_shadow(void* startaddr, size_t size_in_bytes) { + printf("%p | map_shadow | addr=%p size=%zu\n", nullptr, startaddr, + size_in_bytes); + }; + + virtual void func_enter(tls_t tls, void* pc) { + printf("%p | func_enter | pc=%p\n", tls, pc); + } + + virtual void func_exit(tls_t tls) { printf("%p | func_exit |\n", tls); } + + virtual void acquire(tls_t tls, void* mutex, int recursive, bool write) { + printf("%p | acquire | m=%p rec=%i w=%i\n", tls, mutex, recursive, + write); + } + + virtual void release(tls_t tls, void* mutex, bool write) { + printf("%p | release | m=%p, w=%i\n", tls, mutex, write); + } + + virtual void happens_before(tls_t tls, void* identifier) { + printf("%p | happens_before | %p\n", tls, identifier); + } + + virtual void happens_after(tls_t tls, void* identifier) { + printf("%p | happens_after | %p\n", tls, identifier); + } + + virtual void read(tls_t tls, void* pc, void* addr, size_t size) { + printf("%p | read | pc=%p, addr=%p, s=%zu\n", tls, pc, addr, + size); + } + + virtual void write(tls_t tls, void* pc, void* addr, size_t size) { + printf("%p | write | pc=%p, addr=%p, s=%zu\n", tls, pc, addr, + size); + } + + virtual void allocate(tls_t tls, void* pc, void* addr, size_t size) { + printf("%p | allocate | pc=%p, addr=%p, s=%zu\n", tls, pc, addr, + size); + } + + virtual void deallocate(tls_t tls, void* addr) { + printf("%p | deallocate | addr=%p\n", tls, addr); + } + + virtual void fork(tid_t parent, tid_t child, tls_t* tls) { + *tls = (void*)(0xFF0000ull + child); + printf("%p | fork | par=%i, child=%i\n", *tls, parent, child); + } + + virtual void join(tid_t parent, tid_t child) { + printf("%p | join | par=%i, child=%i\n", nullptr, parent, child); + } + + virtual void detach(tls_t tls, tid_t thread_id) { + printf("%p | detach | tid=%i\n", tls, thread_id); + }; + + virtual void finish(tls_t tls, tid_t thread_id) { + printf("%p | finish | tid=%i\n", tls, thread_id); + }; + + virtual const char* name() { + printf("%p | name |\n", nullptr); + return "Dummy"; + } + + virtual const char* version() { + printf("%p | version |\n", nullptr); + return "1.0.0"; + } +}; +} // namespace detector +} // namespace drace + +extern "C" DUMMY_EXPORT Detector* CreateDetector() { + return new drace::detector::Dummy(); +} diff --git a/standalone/binarydecoder/DetectorOutput.h b/standalone/binarydecoder/DetectorOutput.h index a230641..be8311e 100644 --- a/standalone/binarydecoder/DetectorOutput.h +++ b/standalone/binarydecoder/DetectorOutput.h @@ -53,9 +53,7 @@ class DetectorOutput { std::cout << "finished "; } - void makeOutput(ipc::event::BufferEntry* - buf) { // std::shared_ptr buf){ - + void makeOutput(ipc::event::BufferEntry* buf) { switch (buf->type) { case ipc::event::Type::FUNCENTER: _det->func_enter(*(tls[buf->payload.funcenter.thread_id]), @@ -134,11 +132,13 @@ class DetectorOutput { static int i = 0; s1 = race->first.stack_trace[0]; s2 = race->second.stack_trace[0]; - std::cout << s1 << " " << s2 << std::endl; - std::cout << race->first.thread_id << " " << race->second.thread_id - << std::endl; - std::cout << "race: " << i << "\n"; - i++; + std::cout << "pc: " << (void*)(s1) << " " << (void*)(s2) << std::endl + << "addr: " << (void*)(race->first.accessed_memory) << std::endl + << "rw: " << (race->first.write ? "write" : "read") << " " + << (race->second.write ? "write" : "read") << std::endl + << "tid: " << std::hex << race->first.thread_id << " " + << std::hex << race->second.thread_id << std::endl; + std::cout << "race: " << ++i << "\n"; } } };