Skip to content

Commit d85f055

Browse files
committed
Add counters
1 parent 608094b commit d85f055

5 files changed

Lines changed: 27 additions & 28 deletions

File tree

build-logic/conventions/src/main/kotlin/com/datadoghq/native/config/ConfigurationPresets.kt

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,21 @@ object ConfigurationPresets {
3737
project.logger.lifecycle("Setting up standard build configurations for $currentPlatform-$currentArch")
3838
project.logger.lifecycle("Using compiler: $compiler")
3939

40+
// Opt-in compile-time fault injection. When -PenableFaultInjection is
41+
// passed we append -D__FAULT_INJECTION__ to the standard release/debug
42+
// library builds, so the documented buildRelease / buildDebug workflows
43+
// produce a fault-injected libjavaProfiler.so. It is intentionally NOT
44+
// applied to asan/tsan/fuzzer: those configs install their own SIGSEGV
45+
// interception, which conflicts with the deliberately-faulting loads.
46+
val faultInjection = project.hasProperty("enableFaultInjection")
4047
extension.buildConfigurations.apply {
4148
register("release") {
4249
configureRelease(this, currentPlatform, currentArch, version)
50+
if (faultInjection) compilerArgs.add("-D__FAULT_INJECTION__")
4351
}
4452
register("debug") {
4553
configureDebug(this, currentPlatform, currentArch, version)
54+
if (faultInjection) compilerArgs.add("-D__FAULT_INJECTION__")
4655
}
4756
register("asan") {
4857
configureAsan(this, currentPlatform, currentArch, version, rootDir, compiler)
@@ -53,14 +62,6 @@ object ConfigurationPresets {
5362
register("fuzzer") {
5463
configureFuzzer(this, currentPlatform, currentArch, version, rootDir, compiler)
5564
}
56-
// Opt-in fault-injection config: a release build with -D__FAULT_INJECTION__.
57-
// Only registered when -PenableFaultInjection is passed, so normal
58-
// builds never see the define.
59-
if (project.hasProperty("enableFaultInjection")) {
60-
register("faultinjection") {
61-
configureFaultInjection(this, currentPlatform, currentArch, version)
62-
}
63-
}
6465
}
6566

6667
val activeConfigs = extension.getActiveConfigurations(currentPlatform, currentArch)
@@ -133,22 +134,6 @@ object ConfigurationPresets {
133134
}
134135
}
135136

136-
/**
137-
* Fault-injection configuration: identical to release but with
138-
* -D__FAULT_INJECTION__, which activates the compile-time fault-injection
139-
* layer (faultInjection.h) at the profiler's memory-access sites. Opt-in
140-
* only (see setupStandardConfigurations); never shipped in production.
141-
*/
142-
fun configureFaultInjection(
143-
config: BuildConfiguration,
144-
platform: Platform,
145-
architecture: Architecture,
146-
version: String
147-
) {
148-
configureRelease(config, platform, architecture, version)
149-
config.compilerArgs.add("-D__FAULT_INJECTION__")
150-
}
151-
152137
fun configureDebug(
153138
config: BuildConfiguration,
154139
platform: Platform,

ddprof-lib/src/main/cpp/counters.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,11 @@
124124
* paths (delegated and direct) go into SAMPLES_DROPPED_REC_LOCK. */ \
125125
X(JVMTI_STACKS_DROPPED_LOCK, "jvmti_stacks_dropped_lock") \
126126
X(SAMPLES_DROPPED_REC_LOCK, "samples_dropped_rec_lock") \
127-
X(SAMPLES_DROPPED_THREAD_LOCAL, "samples_dropped_thread_local")
127+
X(SAMPLES_DROPPED_THREAD_LOCAL, "samples_dropped_thread_local") \
128+
X(SAFECOPY_FAILED, "safecopy_failed") \
129+
X(SAFEFETCH_FAILED, "safefetch_failed") \
130+
X(FAULTS_INJECTED, "faults_injected") \
131+
X(WALKVM_LONGJMP_RECOVERED, "walkvm_longjmp_recovered")
128132
#define X_ENUM(a, b) a,
129133
typedef enum CounterId : int {
130134
DD_COUNTER_TABLE(X_ENUM) DD_NUM_COUNTERS

ddprof-lib/src/main/cpp/faultInjection.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
// normal build links a no-op object file.
2121
#ifdef __FAULT_INJECTION__
2222

23+
#include "counters.h" // Counters::increment (FAULTS_INJECTED)
2324
#include "os.h" // OS::page_size
2425
#include "threadLocalData.h" // ProfiledThread::currentSignalSafe / nextFiRandom
2526
#include <atomic>
@@ -78,7 +79,13 @@ bool shouldFire(u64 threshold, const char* fn) {
7879
// stream per call site while keeping the fire probability exactly
7980
// threshold/2^64.
8081
u64 r = nextRandom() ^ ((u64)(uintptr_t)fn * KNUTH);
81-
return r < threshold;
82+
if (__builtin_expect(r < threshold, 0)) {
83+
// Every address/int/long injection routes through here, so this is the one
84+
// place that counts an actually-injected fault.
85+
Counters::increment(FAULTS_INJECTED);
86+
return true;
87+
}
88+
return false;
8289
}
8390

8491
uintptr_t poisonAddress() {

ddprof-lib/src/main/cpp/hotspot/hotspotSupport.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,7 @@ void HotspotSupport::checkFault(ProfiledThread* thrd) {
970970
}
971971

972972
thrd->resetCrashHandler();
973+
Counters::increment(WALKVM_LONGJMP_RECOVERED);
973974
longjmp(*thrd->getJmpCtx(), 1);
974975
}
975976

ddprof-lib/src/main/cpp/safeAccess.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@
1616

1717

1818
#include "safeAccess.h"
19-
#include <cstdio>
20-
#include <cstdlib>
19+
#include "counters.h"
2120
#include <signal.h>
2221
#include <ucontext.h>
2322

@@ -280,14 +279,17 @@ bool SafeAccess::handle_safefetch(int sig, void* context) {
280279
if ((sig == SIGSEGV || sig == SIGBUS) && uc != nullptr) {
281280
if (pc == (uintptr_t)safefetch32_impl) {
282281
uc->current_pc = (uintptr_t)safefetch32_cont;
282+
Counters::increment(SAFEFETCH_FAILED);
283283
return true;
284284
} else if (pc == (uintptr_t)safefetch64_impl) {
285285
uc->current_pc = (uintptr_t)safefetch64_cont;
286+
Counters::increment(SAFEFETCH_FAILED);
286287
return true;
287288
} else if (pc >= (uintptr_t)safecopy_impl && pc < (uintptr_t)safecopy_cont) {
288289
// Unlike safefetch, the faulting load can be at any pc inside the copy
289290
// loop, so match the whole [safecopy_impl, safecopy_cont) range.
290291
uc->current_pc = (uintptr_t)safecopy_cont;
292+
Counters::increment(SAFECOPY_FAILED);
291293
return true;
292294
}
293295
}

0 commit comments

Comments
 (0)