Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(profiling): make sanitizers happy #11448

Closed
wants to merge 87 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
7010687
fix tsan
taegyunkim Nov 18, 2024
304fed2
add tsan options
taegyunkim Nov 18, 2024
1ec9fad
update gtest
taegyunkim Nov 19, 2024
c745eed
set clang for safety
taegyunkim Nov 19, 2024
ba4bb25
add lsan suppressions
taegyunkim Nov 19, 2024
11bb977
lsan fix
taegyunkim Nov 19, 2024
d790c0a
use synchronized pool
taegyunkim Nov 19, 2024
e45b6f2
make tsan happy
taegyunkim Nov 19, 2024
f8e3ef9
use moodycamel concurrenqueue instead of crossbeam
taegyunkim Nov 19, 2024
ad0b7ea
use atomic
taegyunkim Nov 19, 2024
726f6c6
Merge branch 'main' into taegyunkim/prof-10916-sanitizer-fixes
taegyunkim Nov 19, 2024
8685d33
destructor for sample pool
taegyunkim Nov 19, 2024
030bcd1
Merge branch 'taegyunkim/prof-10916-sanitizer-fixes' of github.com:Da…
taegyunkim Nov 19, 2024
6477ca4
Merge branch 'main' into taegyunkim/prof-10916-sanitizer-fixes
taegyunkim Nov 19, 2024
35aef24
Merge branch 'main' into taegyunkim/prof-10916-sanitizer-fixes
taegyunkim Nov 26, 2024
9a41c0a
Merge branch 'main' into taegyunkim/prof-10916-sanitizer-fixes
taegyunkim Dec 4, 2024
ede54f4
use pthread
taegyunkim Dec 4, 2024
e2bd96d
use https
taegyunkim Dec 4, 2024
b8b94b9
fix format
taegyunkim Dec 4, 2024
f90b8d3
chore(profiling): gh action with sanitized native tests
taegyunkim Dec 4, 2024
b2b135f
Merge branch 'taegyunkim/prof-10916-gh-actions' into taegyunkim/prof-…
taegyunkim Dec 4, 2024
aa96c6d
use ubuntu 24.04
taegyunkim Dec 4, 2024
81a15fc
rename
taegyunkim Dec 4, 2024
efe1406
use llvm 19
taegyunkim Dec 4, 2024
b00f75d
use install script
taegyunkim Dec 4, 2024
5deff6e
Merge branch 'main' into taegyunkim/prof-10916-sanitizer-fixes
taegyunkim Dec 5, 2024
f5165be
fix deadlock
taegyunkim Dec 5, 2024
457850e
fix(profiling): recreate locks after fork
taegyunkim Dec 5, 2024
1eb7ae5
release note
taegyunkim Dec 5, 2024
81b7f50
libdd 14.3.1
taegyunkim Dec 5, 2024
9c06fd1
remove unused
taegyunkim Dec 5, 2024
f627d57
use pthread
taegyunkim Dec 5, 2024
0aecc54
use simplistic shared vector protected by mutex
taegyunkim Dec 5, 2024
8fced24
use 18
taegyunkim Dec 5, 2024
3ea6dbe
also run on mac
taegyunkim Dec 5, 2024
df36116
typo and timeout
taegyunkim Dec 5, 2024
d7e3628
remove curly braces
taegyunkim Dec 5, 2024
823b3d2
dont think this is needed
taegyunkim Dec 5, 2024
0122eab
install bash and llvm
taegyunkim Dec 5, 2024
98cec75
use llvm18
taegyunkim Dec 5, 2024
3d6e08c
use export
taegyunkim Dec 5, 2024
9ce6908
remove unused
taegyunkim Dec 5, 2024
2304d27
recreate mutex used in echion after fork
taegyunkim Dec 5, 2024
4a99f13
also recreate thread_info_map_lock
taegyunkim Dec 5, 2024
1465f84
reset string table
taegyunkim Dec 5, 2024
cb168ed
reset after fork
taegyunkim Dec 5, 2024
8fed38b
Merge branch 'taegyunkim/prof-10916-profile-locks' into taegyunkim/pr…
taegyunkim Dec 5, 2024
9bae2c2
remove LSAN sup
taegyunkim Dec 5, 2024
791d84e
remove concurrentqueue
taegyunkim Dec 5, 2024
240b86f
revert changes to cformat
taegyunkim Dec 5, 2024
6545921
remove tag mutex
taegyunkim Dec 5, 2024
d8f9393
also recreate task_link_map_lock
taegyunkim Dec 5, 2024
c57bc60
revert changes to uploader builder
taegyunkim Dec 5, 2024
8b07000
use postfork child
taegyunkim Dec 5, 2024
43bb629
cancel first and then lock
taegyunkim Dec 5, 2024
ec5d018
use prints and verbose mode
taegyunkim Dec 5, 2024
843d332
more debug output
taegyunkim Dec 5, 2024
9de2f6c
more debugging
taegyunkim Dec 5, 2024
6bc6e96
Revert "more debugging"
taegyunkim Dec 5, 2024
64575bc
Revert "more debug output"
taegyunkim Dec 5, 2024
19e808c
Revert "use prints and verbose mode"
taegyunkim Dec 5, 2024
29a521e
revert back cancel token
taegyunkim Dec 5, 2024
e97a2c0
use 19
taegyunkim Dec 5, 2024
43db148
Revert "remove concurrentqueue"
taegyunkim Dec 6, 2024
c1d57b4
use moodycamel
taegyunkim Dec 6, 2024
e5cf5db
handle leak
taegyunkim Dec 6, 2024
6041d54
tsan suppressions
taegyunkim Dec 6, 2024
e2141db
Revert "revert changes to cformat"
taegyunkim Dec 6, 2024
59359b3
Merge branch 'main' into taegyunkim/prof-10916-sanitizer-fixes
taegyunkim Dec 6, 2024
a75393e
init should only set pid
taegyunkim Dec 6, 2024
f0d2095
another case
taegyunkim Dec 6, 2024
98d1ccc
turn off macos
taegyunkim Dec 9, 2024
ad5ea75
Merge branch 'main' into taegyunkim/prof-10916-sanitizer-fixes
taegyunkim Dec 9, 2024
9cdb6ef
Merge branch 'main' into taegyunkim/prof-10916-sanitizer-fixes
taegyunkim Dec 9, 2024
195e20c
simplify actions script
taegyunkim Dec 9, 2024
ec6d8df
use taegyunkim/algorithm-include
taegyunkim Dec 9, 2024
0305060
comment
taegyunkim Dec 9, 2024
f656683
comment
taegyunkim Dec 9, 2024
92a2733
revert changes to cancel token
taegyunkim Dec 9, 2024
6d72260
update tsan suppressions
taegyunkim Dec 9, 2024
94a215f
is it possible to not recreate token?
taegyunkim Dec 9, 2024
b8797f0
Merge branch 'main' into taegyunkim/prof-10916-sanitizer-fixes
taegyunkim Dec 9, 2024
2398820
keep cloning
taegyunkim Dec 9, 2024
80a41c4
Merge branch 'main' into taegyunkim/prof-10916-sanitizer-fixes
taegyunkim Dec 9, 2024
edc6456
take address of vector elem
taegyunkim Dec 9, 2024
ce93423
Merge branch 'main' into taegyunkim/prof-10916-sanitizer-fixes
taegyunkim Dec 9, 2024
7c80d18
Discard changes to ddtrace/internal/datadog/profiling/stack_v2/src/sa…
taegyunkim Dec 9, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ endif()

include(ExternalProject)
set(TAG_LIBDATADOG
"v14.1.0"
"v14.3.1"
CACHE STRING "libdatadog github tag")

set(Datadog_BUILD_DIR ${CMAKE_BINARY_DIR}/libdatadog)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
fc6be3383d3a115804c43e2c66dd176c63f33b362d987d9b1211034e2b549c2d libdatadog-aarch64-alpine-linux-musl.tar.gz
b9c972afea19696ee6a459d2fa65563b738baf77dcb12739c8e4ae44d1c975fb libdatadog-aarch64-apple-darwin.tar.gz
1a9bc4d99d23f7baf403b6b7527f9b9d76bdb166dc34656150561dcb148cc90b libdatadog-aarch64-unknown-linux-gnu.tar.gz
8244831681332dfa939eefe6923fe6a8beaffff48cb336f836b55a438078add1 libdatadog-x86_64-alpine-linux-musl.tar.gz
76fcb3bfe3b3971d77f6dd4968ffe6bd5f6a1ada82e2e990a78919107dc2ee40 libdatadog-x86_64-unknown-linux-gnu.tar.gz
57f83aff275628bb1af89c22bb4bd696726daf2a9e09b6cd0d966b29e65a7ad6 libdatadog-aarch64-alpine-linux-musl.tar.gz
2be2efa98dfc32f109abdd79242a8e046a7a300c77634135eb293e000ecd4a4c libdatadog-aarch64-apple-darwin.tar.gz
36db8d50ccabb71571158ea13835c0f1d05d30b32135385f97c16343cfb6ddd4 libdatadog-aarch64-unknown-linux-gnu.tar.gz
2f61fd21cf2f8147743e414b4a8c77250a17be3aecc42a69ffe54f0a603d5c92 libdatadog-x86_64-alpine-linux-musl.tar.gz
f01f05600591063eba4faf388f54c155ab4e6302e5776c7855e3734955f7daf7 libdatadog-x86_64-unknown-linux-gnu.tar.gz
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ class SampleManager
private:
static inline unsigned int max_nframes{ g_default_max_nframes };
static inline SampleType type_mask{ SampleType::All };
static inline std::mutex init_mutex{};
static inline size_t sample_pool_capacity{ g_default_sample_pool_capacity };
static inline std::unique_ptr<SynchronizedSamplePool> sample_pool{ nullptr };

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,28 @@

#include "sample.hpp"

extern "C"
{
#include "datadog/common.h"
}
#include "vendored/concurrentqueue.h"

#include <memory>
#include <optional>

namespace Datadog {

struct Deleter
{
void operator()(ddog_ArrayQueue* object) { ddog_ArrayQueue_drop(object); }
};

class SynchronizedSamplePool
{
private:
std::unique_ptr<ddog_ArrayQueue, Deleter> pool;
moodycamel::ConcurrentQueue<std::unique_ptr<Sample>> pool;
std::atomic<size_t> capacity;

public:
SynchronizedSamplePool(size_t capacity);
SynchronizedSamplePool(size_t _capacity)
{
capacity.store(_capacity);
pool = moodycamel::ConcurrentQueue<std::unique_ptr<Sample>>(_capacity);
}

std::optional<Sample*> take_sample();
std::optional<Sample*> return_sample(Sample* sample);
void postfork_child();
};
} // namespace Datadog

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,9 @@ Datadog::Profile::collect(const ddog_prof_Sample& sample, int64_t endtime_ns)
void
Datadog::Profile::postfork_child()
{
profile_mtx.unlock();
// DEV: Need to reset locks in child to avoid deadlock, and we recreate
// the data structures these lock protect.
profile_mtx.~mutex();
new (&profile_mtx) std::mutex();
cycle_buffers();
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,78 +2,35 @@

#include "libdatadog_helpers.hpp"

extern "C"
{
#include "datadog/common.h"
}
#include "vendored/concurrentqueue.h"

namespace Datadog {

void
sample_delete_fn(void* sample)
{
delete static_cast<Sample*>(sample); // NOLINT(cppcoreguidelines-owning-memory)
}

SynchronizedSamplePool::SynchronizedSamplePool(size_t capacity)
{
ddog_ArrayQueue_NewResult array_queue_new_result = ddog_ArrayQueue_new(capacity, sample_delete_fn);
if (array_queue_new_result.tag == DDOG_ARRAY_QUEUE_NEW_RESULT_OK) {
pool = std::unique_ptr<ddog_ArrayQueue, Deleter>(array_queue_new_result.ok);
} else {
auto err = array_queue_new_result.err;
std::string errmsg = err_to_msg(&err, "Failed to create sample pool");
std::cerr << errmsg << std::endl;
ddog_Error_drop(&err);
pool = nullptr;
}
}

std::optional<Sample*>
SynchronizedSamplePool::take_sample()
{
std::optional<Sample*> result = std::nullopt;
std::unique_ptr<Sample> sample = nullptr;

// It's actually ok to call ddog_ArrayQueue_* methods with a nullptr,
// they will return an error result, but we already have printed out
// an error message in the constructor, so check for nullptr here to
// avoid spamming the error message.
if (pool != nullptr) {
ddog_ArrayQueue_PopResult pop_result = ddog_ArrayQueue_pop(pool.get());
pool.try_dequeue(sample);

if (pop_result.tag == DDOG_ARRAY_QUEUE_POP_RESULT_OK) {
result = static_cast<Sample*>(pop_result.ok);
} else if (pop_result.tag == DDOG_ARRAY_QUEUE_POP_RESULT_ERR) {
auto err = pop_result.err;
std::string errmsg = err_to_msg(&err, "Failed to get sample from pool");
std::cerr << errmsg << std::endl;
ddog_Error_drop(&err);
}
if (sample == nullptr) {
return std::nullopt;
}

return result;
return sample.release();
}

std::optional<Sample*>
SynchronizedSamplePool::return_sample(Sample* sample)
{
std::optional<Sample*> result = std::nullopt;

if (pool != nullptr) {
ddog_ArrayQueue_PushResult push_result = ddog_ArrayQueue_push(pool.get(), sample);

if (push_result.tag == DDOG_ARRAY_QUEUE_PUSH_RESULT_OK) {
// The sample was successfully returned to the pool.
} else if (push_result.tag == DDOG_ARRAY_QUEUE_PUSH_RESULT_FULL) {
result = static_cast<Sample*>(push_result.full);
} else if (push_result.tag == DDOG_ARRAY_QUEUE_PUSH_RESULT_ERR) {
auto err = push_result.err;
std::string errmsg = err_to_msg(&err, "Failed to return sample to pool");
std::cerr << errmsg << std::endl;
ddog_Error_drop(&err);
}
// We don't want the pool to grow without a bound, so check the size and
// discard the sample if it's larger than capacity.
if (capacity.load() <= pool.size_approx()) {
return sample;
} else {
std::unique_ptr<Sample> ptr = nullptr;
ptr.reset(sample);
pool.enqueue(std::move(ptr));
return std::nullopt;
}

return result;
}
} // namespace Datadog
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
fixes:
- |
Fixes an issue where calling ``unlock()`` on unlocked mutex could result in
an undefined behavior.
Fixes an issue where the child process could deadlock after ``fork()`` as
it didn't reset the locks.

7 changes: 6 additions & 1 deletion scripts/cformat.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,17 @@ then
| grep -v '_taint_tracking/_vendor/' \
| grep -v 'ddtrace/appsec/_iast/_taint_tracking/cmake-build-debug/' \
| grep -v '^ddtrace/appsec/_iast/_taint_tracking/_vendor/' \
| grep -v '^ddtrace/internal/datadog/profiling/dd_wrapper/include/vendored/' \
| while IFS= read -r file; do
clang-format -i $file
echo "Formatting $file"
done
else
git ls-files '*.c' '*.h' '*.cpp' '*.hpp' | grep -v '^ddtrace/vendor/' | grep -v '^ddtrace/appsec/_iast/_taint_tracking/_vendor/' | while read filename
git ls-files '*.c' '*.h' '*.cpp' '*.hpp' \
| grep -v '^ddtrace/vendor/' \
| grep -v '^ddtrace/appsec/_iast/_taint_tracking/_vendor/' \
| grep -v '^ddtrace/internal/datadog/profiling/dd_wrapper/include/vendored/' \
| while read filename
do
CFORMAT_TMP=`mktemp`
clang-format "$filename" > "$CFORMAT_TMP"
Expand Down
Loading