Skip to content
Draft
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
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ object ConfigurationPresets {
config.compilerArgs.set(
listOf("-O0", "-g", "-DDEBUG") + commonLinuxCompilerArgs(version)
)
config.linkerArgs.set(commonLinuxLinkerArgs())
config.linkerArgs.set(commonLinuxLinkerArgs() + listOf("-Wl", "-z", "nodelete"))
}
Platform.MACOS -> {
config.compilerArgs.set(
Expand Down
15 changes: 13 additions & 2 deletions ddprof-lib/src/main/cpp/counters.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 Datadog, Inc
* Copyright 2023, 2026 Datadog, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -57,6 +57,8 @@
X(THREAD_NAMES_COUNT, "thread_names_count") \
X(THREAD_FILTER_PAGES, "thread_filter_pages") \
X(THREAD_FILTER_BYTES, "thread_filter_bytes") \
X(THREAD_REGISTRY_BOOTSTRAP_FAILURES, "thread_registry_bootstrap_failures") \
X(THREAD_REGISTRY_STALE_SLOTS_RETIRED, "thread_registry_stale_slots_retired") \
X(JMETHODID_SKIPPED, "jmethodid_skipped_count") \
X(CODECACHE_NATIVE_SIZE_BYTES, "codecache_native_size_bytes") \
X(CODECACHE_NATIVE_COUNT, "native_codecache_count") \
Expand All @@ -66,10 +68,19 @@
X(AGCT_NATIVE_NO_JAVA_CONTEXT, "agct_native_no_java_context") \
X(AGCT_BLOCKED_IN_VM, "agct_blocked_in_vm") \
X(SKIPPED_WALLCLOCK_UNWINDS, "skipped_wallclock_unwinds") \
X(WC_SIGNAL_SUPPRESSED_SAMPLED_RUN, "wc_signals_suppressed_sampled_run") \
X(WC_PRECHECK_REGISTRY_LOOKUPS, "wc_precheck_registry_lookups") \
X(WC_PRECHECK_CANDIDATES_REJECTED, "wc_precheck_candidates_rejected") \
X(WC_PRECHECK_LOOKUP_BUDGET_EXHAUSTED, "wc_precheck_lookup_budget_exhausted") \
X(WC_SIGNAL_SUPPRESSED_OWNED_BLOCK, "wc_signals_suppressed_owned_block") \
X(WC_UNOWNED_BLOCKED_SUPPRESSED, "wc_unowned_blocked_suppressed") \
X(WC_UNOWNED_BLOCKED_RECORDED, "wc_unowned_blocked_recorded") \
X(WC_SIGNAL_QUEUE_FULL, "wc_signals_queue_full") \
X(TASK_BLOCK_EMITTED, "task_block_emitted") \
X(TASK_BLOCK_SKIPPED_TRACE_CONTEXT, "task_block_skipped_trace_context") \
X(TASK_BLOCK_SKIPPED_TOO_SHORT, "task_block_skipped_too_short") \
X(TASK_BLOCK_STACK_CAPTURE_FAILED, "task_block_stack_capture_failed") \
X(TASK_BLOCK_RECORD_FAILED, "task_block_record_failed") \
X(TASK_BLOCK_DROPPED_ROTATION, "task_block_dropped_rotation") \
X(UNWINDING_TIME_ASYNC, "unwinding_ticks_async") \
X(UNWINDING_TIME_JVMTI, "unwinding_ticks_jvmti") \
X(CALLTRACE_STORAGE_DROPPED, "calltrace_storage_dropped_traces") \
Expand Down
4 changes: 4 additions & 0 deletions ddprof-lib/src/main/cpp/engine.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright 2017 Andrei Pangin
* Copyright 2026, Datadog, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -51,6 +52,9 @@ class Engine {
virtual void stop();
virtual long interval() const { return 0L; }

// Whether empty-filter wall prechecks can consume ThreadFilter registry state.
virtual bool supportsUnfilteredWallPrecheck() const { return false; }

virtual int registerThread(int tid) { return -1; }
virtual void unregisterThread(int tid) {}

Expand Down
22 changes: 16 additions & 6 deletions ddprof-lib/src/main/cpp/event.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class ExecutionEvent : public Event {
OSThreadState _thread_state;
ExecutionMode _execution_mode;
u64 _weight;
u32 _call_trace_id;
u64 _call_trace_id;

ExecutionEvent()
: Event(), _thread_state(OSThreadState::RUNNABLE), _execution_mode(ExecutionMode::UNKNOWN),
Expand Down Expand Up @@ -122,13 +122,13 @@ class WallClockEpochEvent {
u32 _num_failed_samples;
u32 _num_exited_threads;
u32 _num_permission_denied;
u64 _num_suppressed_sampled_run;
u64 _num_suppressed_owned_block;

WallClockEpochEvent(u64 start_time)
: _dirty(false), _start_time(start_time), _duration_millis(0),
_num_samplable_threads(0), _num_successful_samples(0),
_num_failed_samples(0), _num_exited_threads(0),
_num_permission_denied(0), _num_suppressed_sampled_run(0) {}
_num_permission_denied(0), _num_suppressed_owned_block(0) {}

bool hasChanged() { return _dirty; }

Expand Down Expand Up @@ -167,10 +167,10 @@ class WallClockEpochEvent {
}
}

void addNumSuppressedSampledRun(u64 n) {
void addNumSuppressedOwnedBlock(u64 n) {
if (n > 0) {
_dirty = true;
_num_suppressed_sampled_run += n;
_num_suppressed_owned_block += n;
}
}

Expand All @@ -181,7 +181,7 @@ class WallClockEpochEvent {
void newEpoch(u64 start_time) {
_dirty = false;
_start_time = start_time;
_num_suppressed_sampled_run = 0;
_num_suppressed_owned_block = 0;
}
};

Expand All @@ -206,4 +206,14 @@ typedef struct QueueTimeEvent {
u32 _queueLength;
} QueueTimeEvent;

typedef struct TaskBlockEvent {
u64 _start;
u64 _end;
u64 _blocker;
u64 _unblockingSpanId;
Context _ctx;
u64 _callTraceId;
OSThreadState _observedBlockingState;
} TaskBlockEvent;

#endif // _EVENT_H
32 changes: 31 additions & 1 deletion ddprof-lib/src/main/cpp/flightRecorder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1873,6 +1873,21 @@ void Recording::recordMethodSample(Buffer *buf, int tid, u64 call_trace_id,
flushIfNeeded(buf);
}

void Recording::recordTaskBlock(Buffer *buf, int tid, TaskBlockEvent *event) {
int start = buf->skip(1);
buf->putVar64(T_TASK_BLOCK);
buf->putVar64(event->_start);
buf->putVar64(event->_end - event->_start);
buf->putVar64(tid);
buf->putVar64(event->_blocker);
buf->putVar64(event->_unblockingSpanId);
buf->putVar64(event->_callTraceId);
buf->put8(static_cast<int>(event->_observedBlockingState));
writeContextSnapshot(buf, event->_ctx);
writeEventSizePrefix(buf, start);
flushIfNeeded(buf);
}

void Recording::recordWallClockEpoch(Buffer *buf, WallClockEpochEvent *event) {
int start = buf->skip(1);
buf->putVar64(T_WALLCLOCK_SAMPLE_EPOCH);
Expand All @@ -1883,7 +1898,7 @@ void Recording::recordWallClockEpoch(Buffer *buf, WallClockEpochEvent *event) {
buf->putVar64(event->_num_failed_samples);
buf->putVar64(event->_num_exited_threads);
buf->putVar64(event->_num_permission_denied);
buf->putVar64(event->_num_suppressed_sampled_run);
buf->putVar64(event->_num_suppressed_owned_block);
writeEventSizePrefix(buf, start);
flushIfNeeded(buf);
}
Expand Down Expand Up @@ -2138,6 +2153,21 @@ void FlightRecorder::recordQueueTime(int lock_index, int tid,
}
}

bool FlightRecorder::recordTaskBlock(int lock_index, int tid,
TaskBlockEvent *event) {
OptionalSharedLockGuard locker(&_rec_lock);
if (locker.ownsLock()) {
Recording* rec = _rec;
if (rec != nullptr) {
Buffer *buf = rec->buffer(lock_index);
rec->addThread(lock_index, tid);
rec->recordTaskBlock(buf, tid, event);
return true;
}
}
return false;
}

void FlightRecorder::recordDatadogSetting(int lock_index, int length,
const char *name, const char *value,
const char *unit) {
Expand Down
2 changes: 2 additions & 0 deletions ddprof-lib/src/main/cpp/flightRecorder.h
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,7 @@ class Recording {
void recordWallClockEpoch(Buffer *buf, WallClockEpochEvent *event);
void recordTraceRoot(Buffer *buf, int tid, TraceRootEvent *event);
void recordQueueTime(Buffer *buf, int tid, QueueTimeEvent *event);
void recordTaskBlock(Buffer *buf, int tid, TaskBlockEvent *event);
void recordAllocation(RecordingBuffer *buf, int tid, u64 call_trace_id,
AllocEvent *event);
void recordMallocSample(Buffer *buf, int tid, u64 call_trace_id,
Expand Down Expand Up @@ -424,6 +425,7 @@ class FlightRecorder {
void wallClockEpoch(int lock_index, WallClockEpochEvent *event);
void recordTraceRoot(int lock_index, int tid, TraceRootEvent *event);
void recordQueueTime(int lock_index, int tid, QueueTimeEvent *event);
bool recordTaskBlock(int lock_index, int tid, TaskBlockEvent *event);

bool active() const { return _rec != NULL; }

Expand Down
30 changes: 30 additions & 0 deletions ddprof-lib/src/main/cpp/frames.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,39 @@
/*
* Copyright 2026, Datadog, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _FRAMES_H
#define _FRAMES_H

#include <jni.h>
#include <jvmti.h>
#include "vmEntry.h"

inline void copyJvmtiFrames(ASGCT_CallFrame *frames,
const jvmtiFrameInfo *jvmti_frames,
jint num_frames) {
// The source and destination commonly refer to the two views of the same
// CallTraceBuffer union. Read both source fields before either write.
for (jint i = 0; i < num_frames; ++i) {
jmethodID method = jvmti_frames[i].method;
jlocation location = jvmti_frames[i].location;
frames[i].method_id = method;
frames[i].bci = static_cast<jint>(location);
LP64_ONLY(frames[i].padding = 0;)
}
}

inline int makeFrame(ASGCT_CallFrame *frames, jint type, jmethodID id) {
frames[0].bci = type;
frames[0].method_id = id;
Expand Down
Loading
Loading