Skip to content

Commit 0fbe6d5

Browse files
committed
wip: count sigprof/samples/matches to find where rust samples vanish
1 parent 582eda5 commit 0fbe6d5

2 files changed

Lines changed: 27 additions & 21 deletions

File tree

.github/workflows/ci.yml

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -333,30 +333,18 @@ jobs:
333333
- name: DIAGNOSE (temporary)
334334
if: runner.os == 'Linux'
335335
run: |
336-
sudo apt-get install -y -qq strace >/dev/null
337-
COUNT='import json,collections,sys; t=collections.Counter(json.loads(l)["type"] for l in open(sys.argv[1]) if l.strip()); print(" ", dict(t))'
336+
echo "##### rust toy: where do the samples go?"
337+
COZ_DEBUG_SAMPLES=1 timeout 120 ./coz run -o /tmp/r.jsonl --- ./rust/target/release/examples/toy 2>&1 | grep coz-dbg || echo " (no coz-dbg line)"
338338
339-
echo "##### 1. C toy in THIS job (control: is the environment sane?)"
339+
echo "##### C toy, same instrumentation, for comparison"
340340
g++ -g -O2 -c benchmarks/toy/toy.cpp -Iinclude -o /tmp/t.o
341341
g++ -g /tmp/t.o -o /tmp/ctoy -ldl -lpthread
342-
timeout 150 ./coz run -o /tmp/c.jsonl --- /tmp/ctoy >/dev/null 2>&1 || true
343-
python3 -c "$COUNT" /tmp/c.jsonl || echo " C toy: no profile"
344-
345-
echo "##### 2. does perf_event_open succeed for the Rust toy?"
346-
strace -f -qq -e trace=perf_event_open -o /tmp/st.txt ./coz run -o /tmp/s.jsonl --- ./rust/target/release/examples/toy >/dev/null 2>&1 || true
347-
echo " perf_event_open calls: $(grep -c perf_event_open /tmp/st.txt || true)"
348-
echo " failing calls:"; grep perf_event_open /tmp/st.txt | grep -E '= -1' | head -3 | sed 's/^/ /' || true
349-
echo " first call:"; grep perf_event_open /tmp/st.txt | head -1 | sed 's/^/ /' || true
350-
python3 -c "$COUNT" /tmp/s.jsonl || echo " no profile"
351-
352-
echo "##### 3. profiler lifecycle (verbose, captured to a file)"
353-
timeout 120 ./coz run --verbose -o /tmp/v.jsonl --- ./rust/target/release/examples/toy >/tmp/v.txt 2>&1 || true
354-
grep -aE 'Profiler thread|Registered thread|Starting sampling|startup complete' /tmp/v.txt | head -8 | sed 's/^/ /' || true
355-
python3 -c "$COUNT" /tmp/v.jsonl || echo " no profile"
356-
357-
echo "##### 4. C toy under strace, for comparison"
358-
strace -f -qq -e trace=perf_event_open -o /tmp/st2.txt ./coz run -o /tmp/c2.jsonl --- /tmp/ctoy >/dev/null 2>&1 || true
359-
echo " C toy perf_event_open calls: $(grep -c perf_event_open /tmp/st2.txt || true)"
342+
COZ_DEBUG_SAMPLES=1 timeout 120 ./coz run -o /tmp/c.jsonl --- /tmp/ctoy 2>&1 | grep coz-dbg || echo " (no coz-dbg line)"
343+
344+
echo "##### is toy.rs actually in scope?"
345+
timeout 30 ./coz run --verbose -o /tmp/v.jsonl --- /bin/true 2>&1 | head -2 || true
346+
timeout 60 ./coz run --verbose -o /tmp/v2.jsonl --- ./rust/target/release/examples/toy 2>/tmp/v2.txt >/dev/null || true
347+
grep -a 'Included source file' /tmp/v2.txt | grep -aE 'toy.rs|rust/src/lib.rs' | sed 's/^/ /' || echo " toy.rs NOT in scope"
360348
361349
- name: Profile the Rust toy under coz
362350
run: |

libcoz/profiler.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,13 @@
5252

5353
using namespace std;
5454

55+
// TEMPORARY diagnostics for the rust-on-linux CI failure.
56+
static std::atomic<size_t> g_dbg_sigprof{0};
57+
static std::atomic<size_t> g_dbg_no_state{0};
58+
static std::atomic<size_t> g_dbg_records{0};
59+
static std::atomic<size_t> g_dbg_samples{0};
60+
static std::atomic<size_t> g_dbg_matched{0};
61+
5562
// Diagnostic counters for delay application (macOS debugging)
5663
#ifdef __APPLE__
5764
static std::atomic<size_t> g_delays_applied{0};
@@ -511,6 +518,12 @@ void profiler::log_samples(ofstream& output, size_t start_time) {
511518
*/
512519
void profiler::shutdown() {
513520
if(_shutdown_run.test_and_set() == false) {
521+
if(getenv("COZ_DEBUG_SAMPLES")) {
522+
fprintf(stderr,
523+
"[coz-dbg] sigprof=%zu no_state=%zu perf_records=%zu samples=%zu matched=%zu\n",
524+
g_dbg_sigprof.load(), g_dbg_no_state.load(), g_dbg_records.load(),
525+
g_dbg_samples.load(), g_dbg_matched.load());
526+
}
514527
#ifdef __APPLE__
515528
// Stop the macOS sampling thread first so no more samples are produced
516529
// and no more pthread_kill() calls happen from apply_pending_delays()
@@ -718,10 +731,13 @@ void profiler::add_delays(thread_state* state) {
718731

719732
void profiler::process_samples(thread_state* state) {
720733
for(perf_event::record r : state->sampler) {
734+
g_dbg_records.fetch_add(1, std::memory_order_relaxed);
721735
if(r.is_sample()) {
736+
g_dbg_samples.fetch_add(1, std::memory_order_relaxed);
722737
// Find and match the line that contains this sample
723738
std::pair<line*, bool> sampled_line = match_line(r);
724739
if(sampled_line.first) {
740+
g_dbg_matched.fetch_add(1, std::memory_order_relaxed);
725741
sampled_line.first->add_sample();
726742
}
727743

@@ -855,8 +871,10 @@ void* profiler::start_profiler_thread(void* arg) {
855871
}
856872

857873
void profiler::samples_ready(int signum, siginfo_t* info, void* p) {
874+
g_dbg_sigprof.fetch_add(1, std::memory_order_relaxed);
858875
thread_state* state = get_instance().get_thread_state();
859876
if (!state) {
877+
g_dbg_no_state.fetch_add(1, std::memory_order_relaxed);
860878
return;
861879
}
862880
if (state->check_in_use()) {

0 commit comments

Comments
 (0)