Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
82aaf54
fix: free line number tables while class pins held (PROF-14545)
jbachorik May 13, 2026
1216c27
fix(profiler): musl/aarch64/JDK11 thread-wrapper canary+LR corruption
jbachorik May 13, 2026
15580c7
fix(profiler): close SIGVTALRM race in thread teardown (PROF-14603)
jbachorik May 13, 2026
c4edc63
fix(test): replace ASSERT_NE with early return in t10_body
jbachorik May 14, 2026
2105b61
refactor(profiler): lock-free class/endpoint/context maps via TripleB…
jbachorik May 13, 2026
6aa19b0
address: respond to review comments on PR #510
jbachorik May 15, 2026
3b54384
fix: remove double blank line in libraryPatcher_linux.cpp
Copilot May 15, 2026
2e1c298
fix: cleanup on pthread_exit/cancel in spec wrapper; refactor test
jbachorik May 15, 2026
caec7ee
test: address review comments on PR #510
jbachorik May 15, 2026
53e3e46
fix(test): replace ASSERT_NE with ADD_FAILURE+return in void* thread …
jbachorik May 15, 2026
d937faa
fix(profiler): lock-free class/endpoint/context maps via DoubleBuffer…
jbachorik May 12, 2026
f55b41f
test: skip HotSpot class-map assertion on J9
jbachorik May 12, 2026
61b94de
test: remove incorrect dictionary_classes_keys assertion
jbachorik May 12, 2026
9eda865
refactor(profiler): TripleBufferedDictionary with generic TripleBuffe…
jbachorik May 12, 2026
1cb8aae
test: bound concurrent dictionary test to prevent CI timeout
jbachorik May 12, 2026
45b3edd
docs: fix stale DoubleBufferedDictionary references in comments
jbachorik May 13, 2026
9abae2e
docs: clarify recent-buffer staleness trade-off in TripleBufferedDict…
jbachorik May 13, 2026
4cef2e4
fix(profiler): drop broken recent-fallback from TripleBufferedDictionary
jbachorik May 13, 2026
18087ff
fix: apply muse review — atomic rotate, counter tracking, stop() cleanup
jbachorik May 13, 2026
afb2e45
fix(profiler): remove clearStandby() from stop() — breaks counter-aft…
jbachorik May 13, 2026
2a9dd08
test: skip ContendedCallTraceStorageTest on musl-aarch64
jbachorik May 13, 2026
546a2e1
Merge remote-tracking branch 'origin/muse/crash-sigsegv-in-std-rb-tre…
jbachorik May 15, 2026
d0c9b4b
feat: add StringDictionaryBuffer — CAS-safe hash table with explicit IDs
jbachorik May 15, 2026
de900b7
fix: null-check malloc, atomic ids[], remove dead keylens in StringDi…
jbachorik May 15, 2026
2b65c11
feat: add StringDictionary triple-buffered wrapper with stable IDs
jbachorik May 15, 2026
55415fa
docs+test: clarify ID density, clearAll precondition; add lookupDurin…
jbachorik May 15, 2026
2fb78ee
test: concurrent stress tests for StringDictionary
jbachorik May 15, 2026
bda1129
test: fix LookupDuringDump stress test to be truly concurrent with in…
jbachorik May 15, 2026
8cd41b8
refactor: use StringDictionary for class/string/context maps in Profiler
jbachorik May 15, 2026
2730253
fix: use lookup() in recordTrace0/registerConstant0/vtableStub (not b…
jbachorik May 15, 2026
7b9228b
refactor: Lookup uses StringDictionary and lookupDuringDump for class…
jbachorik May 15, 2026
419f6b8
fix: RefCountGuard reentrancy ordering and clearAll() signal safety
jbachorik May 18, 2026
b06621c
refactor: remove TripleBufferedDictionary (superseded by StringDictio…
jbachorik May 18, 2026
214465e
refactor: extract RefCountGuard to own TU; add counter assertion to B…
jbachorik May 18, 2026
9f8f6fc
fix(dict): restore sizeLimit cap and add counter tracking to StringDi…
jbachorik May 18, 2026
732cc3c
Merge branch 'main' into muse/crash-sigsegv-in-std-rb-tree-increment-…
jbachorik May 18, 2026
44e1545
address: respond to review comments on PR #524
jbachorik May 18, 2026
b665040
fix(profiler): block async-signals across triple-buffer rotation
jbachorik May 18, 2026
7c05730
fix(profiler): hold lockAll across rotate + JFR dump to close cpool race
jbachorik May 18, 2026
1649e6f
docs(profiler): describe lock scope without referring to PR history
jbachorik May 18, 2026
5db968d
fix(profiler): initialize Error err with Error::OK
jbachorik May 19, 2026
208eb19
test: add fuzz target and multi-dict stress tests for StringDictionary
jbachorik May 19, 2026
9cf40a7
ci: add fuzz job (non-blocking) to nightly and PR workflows
jbachorik May 19, 2026
c441ebf
fix(review): address bot review comments on StringDictionary
jbachorik May 19, 2026
f0c9a47
fix(profiler): correct ids[] ordering and guard liveness in StringDic…
jbachorik May 19, 2026
28f86ec
Merge remote-tracking branch 'origin/main' into muse/crash-sigsegv-in…
jbachorik May 20, 2026
25ad897
fix: address bot review comments on StringDictionary/RefCountGuard
jbachorik May 20, 2026
191c126
fix(profiler): rotate dicts in flushJfr before chunk flush
jbachorik May 20, 2026
8bdf4db
refactor(profiler): extract rotateDictsAndRun, remove dead flushJfr
jbachorik May 20, 2026
82f0cf5
fix(refCountGuard): fix nested guard chain, dying-slot reentrance, an…
jbachorik May 20, 2026
e6676ec
address: respond to review comments on PR #524
jbachorik May 20, 2026
aa8df0e
docs(stringDictionary): clarify stk[34] overflow chain bound
jbachorik May 20, 2026
fd6dffd
fix: restore counter offsets for StringDictionary instances
jbachorik May 20, 2026
611926a
Merge branch 'main' into muse/crash-sigsegv-in-std-rb-tree-increment-…
jbachorik May 20, 2026
a325a48
fix: add spinPause() to busy-wait loop; fix stale comment in writeCpool
jbachorik May 20, 2026
d7ec1ad
fix: update copyright year to 2026 in stringDictionary.h
jbachorik May 20, 2026
1cf8721
fix: fix GeneratedMethodAccessor class name separator; fix stale comment
jbachorik May 20, 2026
b6bbb97
test: read debug counters before stopProfiler to avoid clearStandby r…
jbachorik May 21, 2026
896454d
docs: document rotate() invariants; add timeout warning to waitForAll…
jbachorik May 22, 2026
fbb0b9e
address: respond to review comments on PR #524
jbachorik May 22, 2026
c44aef9
Merge origin/main into muse/crash-sigsegv-in-std-rb-tree-increment-clean
Copilot May 22, 2026
dc82752
fix: guard normalized class name length in dump lookup
Copilot May 22, 2026
5f410b7
fix(build): remove explicit -lasan/-lubsan from ASAN linker args
jbachorik May 23, 2026
9c98736
fix(build): use clang's ASan runtime when linking with clang
jbachorik May 23, 2026
f9cf80f
fix(build): exhaustive when for Architecture in locateLibasan
jbachorik May 23, 2026
01e3d25
fix(build): add rpath for clang ASan runtime to gtest/so binaries
jbachorik May 23, 2026
5afc337
fix(build): strip explicit asan -l flags from gtest executable link
jbachorik May 23, 2026
2a8c230
docs: clarify rotate() comment — JNI callers can insert during rotate
jbachorik May 23, 2026
0995390
feat(counters): track DICTIONARY_PAGES/BYTES for SBTable allocations
jbachorik May 23, 2026
070e87c
Merge branch 'main' into muse/crash-sigsegv-in-std-rb-tree-increment-…
jbachorik May 24, 2026
268b686
fix: update copyright year to 2026 in tripleBuffer.h and refCountGuar…
jbachorik May 24, 2026
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
42 changes: 42 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ jobs:
if: needs.check-for-pr.outputs.skip != 'true'
outputs:
configurations: ${{ steps.compute.outputs.configurations }}
run_fuzz: ${{ steps.compute.outputs.run_fuzz }}
steps:
- name: Debounce label events
if: github.event.action == 'labeled'
Expand Down Expand Up @@ -155,6 +156,13 @@ jobs:
if echo "$labels" | grep -Fq "test:tsan"; then
configs="$configs"',"tsan"'
fi
if echo "$labels" | grep -Fq "test:fuzz"; then
echo "run_fuzz=true" >> $GITHUB_OUTPUT
else
echo "run_fuzz=false" >> $GITHUB_OUTPUT
fi
else
echo "run_fuzz=false" >> $GITHUB_OUTPUT
fi

configs="$configs]"
Expand Down Expand Up @@ -194,3 +202,37 @@ jobs:
body-file: test-summary.md
comment-id: ci-test-results

fuzz:
needs: [check-for-pr, compute-configurations]
if: needs.check-for-pr.outputs.skip != 'true' && needs.compute-configurations.outputs.run_fuzz == 'true'
runs-on: ubuntu-latest
continue-on-error: true
timeout-minutes: 30
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Cache Gradle Wrapper Binaries
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ~/.gradle/wrapper/dists
key: gradle-wrapper-${{ runner.os }}-${{ hashFiles('gradle/wrapper/gradle-wrapper.properties') }}
restore-keys: |
gradle-wrapper-${{ runner.os }}-
- name: Cache Gradle User Home
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ~/.gradle/caches
key: gradle-caches-${{ runner.os }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
gradle-caches-${{ runner.os }}-
- name: Setup OS
run: |
sudo apt-get update
sudo apt-get install -y clang
- name: Fuzz
run: ./gradlew :ddprof-lib:fuzz:fuzz -Pfuzz-duration=120 --no-daemon
- name: Upload crash artifacts
if: failure()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: fuzz-crashes
path: ddprof-lib/fuzz/build/fuzz-crashes/
32 changes: 32 additions & 0 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,38 @@ jobs:
uses: ./.github/workflows/test_workflow.yml
with:
configuration: '["asan"]' # Ignoring tsan for now '["asan", "tsan"]'
fuzz:
runs-on: ubuntu-latest
continue-on-error: true
timeout-minutes: 30
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Cache Gradle Wrapper Binaries
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ~/.gradle/wrapper/dists
key: gradle-wrapper-${{ runner.os }}-${{ hashFiles('gradle/wrapper/gradle-wrapper.properties') }}
restore-keys: |
gradle-wrapper-${{ runner.os }}-
- name: Cache Gradle User Home
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ~/.gradle/caches
key: gradle-caches-${{ runner.os }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
gradle-caches-${{ runner.os }}-
- name: Setup OS
run: |
sudo apt-get update
sudo apt-get install -y clang
- name: Fuzz
run: ./gradlew :ddprof-lib:fuzz:fuzz -Pfuzz-duration=120 --no-daemon
- name: Upload crash artifacts
if: failure()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: fuzz-crashes
path: ddprof-lib/fuzz/build/fuzz-crashes/
report-failures:
runs-on: ubuntu-latest
needs: run-test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,17 +187,23 @@ object ConfigurationPresets {
config.compilerArgs.set(asanCompilerArgs + commonLinuxCompilerArgs(version))

val libasan = PlatformUtils.locateLibasan(compiler)
// Link against the sanitizer runtime that matches the compiler:
// - clang: locateLibasan returns libclang_rt.asan-<arch>.so, which
// includes UBSan symbols; -lclang_rt.asan-<arch> satisfies -z defs
// for both __asan_* and __ubsan_* and matches the runtime that
// -fsanitize=address links into executables — one runtime, no conflict.
// - gcc: locateLibasan returns libasan.so; -lasan + -lubsan as before.
val asanLinkerArgs = if (libasan != null) {
listOf(
"-L${File(libasan).parent}",
"-lasan",
"-lubsan",
"-fsanitize=address",
"-fsanitize=undefined",
"-fno-omit-frame-pointer"
)
val asanLibDir = File(libasan).parent
val asanLibName = File(libasan).nameWithoutExtension.removePrefix("lib")
val ubsanLibs = if (asanLibName.startsWith("clang_rt")) emptyList()
else listOf("-lubsan")
listOf("-L$asanLibDir", "-l$asanLibName",
"-Wl,-rpath,$asanLibDir") +
ubsanLibs +
listOf("-fsanitize=address", "-fsanitize=undefined", "-fno-omit-frame-pointer")
} else {
emptyList()
listOf("-fsanitize=address", "-fsanitize=undefined", "-fno-omit-frame-pointer")
}

config.linkerArgs.set(commonLinuxLinkerArgs() + asanLinkerArgs)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class FuzzTargetsPlugin : Plugin<Project> {
val includeFiles = buildIncludePaths(project, extension, homebrewLLVM)

// Build compiler/linker args
val compilerArgs = buildFuzzCompilerArgs()
val compilerArgs = buildFuzzCompilerArgs(project)
val linkerArgs = buildFuzzLinkerArgs(homebrewLLVM, clangResourceDir, project.logger)

val fuzzSourceDir = extension.fuzzSourceDir.get().asFile
Expand Down Expand Up @@ -194,15 +194,17 @@ class FuzzTargetsPlugin : Plugin<Project> {
return includes
}

private fun buildFuzzCompilerArgs(): List<String> {
private fun buildFuzzCompilerArgs(project: Project): List<String> {
val version = project.version.toString()
val args = mutableListOf(
"-O1",
"-g",
"-fno-omit-frame-pointer",
"-fsanitize=fuzzer,address,undefined",
"-fvisibility=hidden",
"-std=c++17",
"-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION"
"-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION",
"-DPROFILER_VERSION=\"$version\""
)
if (PlatformUtils.currentPlatform == Platform.LINUX && PlatformUtils.isMusl()) {
args.add("-D__musl__")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,14 @@ class GtestTaskBuilder(
}

private fun buildLinkTask(compileTask: TaskProvider<NativeCompileTask>): TaskProvider<NativeLinkExecutableTask> {
val linkerArgs = config.linkerArgs.get()
// For executables, clang's -fsanitize=address statically embeds the full
// ASan runtime (--whole-archive libclang_rt.asan*.a). Adding an explicit
// -lclang_rt.asan or -lasan on top produces a second dynamic NEEDED entry,
// which triggers "incompatible ASan runtimes" at startup (two __asan_init
// calls). Strip the explicit sanitizer -l/-L/-rpath flags here so the
// executable relies solely on clang's automatic static embedding.
val sanitizerLibPattern = Regex("^(-lasan|-lubsan|-lclang_rt\\.asan.*|-lclang_rt\\.ubsan.*|-L.*/clang.*/|-Wl,-rpath,.*/clang.*/)")
val linkerArgs = config.linkerArgs.get().filter { !sanitizerLibPattern.containsMatchIn(it) }
val objDir = project.file("${project.layout.buildDirectory.get()}/obj/gtest/${config.name}/$testName")
val binary = project.file("${project.layout.buildDirectory.get()}/bin/gtest/${config.name}_$testName/$testName")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,25 @@ object PlatformUtils {
return null
}

fun locateLibasan(compiler: String = "gcc"): String? = locateLibrary("libasan", compiler)
fun locateLibasan(compiler: String = "gcc"): String? {
if (currentPlatform != Platform.LINUX) return null
// For clang, prefer the architecture-specific clang_rt.asan library over
// GCC's libasan. Using GCC's runtime alongside clang's libclang_rt.asan
// (which -fsanitize=address links for executables) causes "incompatible
// ASan runtimes" at startup. The clang runtime also includes UBSan symbols,
// so no separate -lubsan is needed.
if (compiler.contains("clang")) {
val archSuffix = when (currentArchitecture) {
Architecture.X64 -> "x86_64"
Architecture.ARM64 -> "aarch64"
Architecture.X86 -> "i386"
Architecture.ARM -> "arm"
}
val clangAsan = locateLibrary("libclang_rt.asan-$archSuffix", compiler)
if (clangAsan != null) return clangAsan
}
return locateLibrary("libasan", compiler)
}

fun locateLibtsan(compiler: String = "gcc"): String? = locateLibrary("libtsan", compiler)

Expand Down
Loading
Loading