janestreet/magic-trace

stop indicator does not work in multi-threaded application

dqminh opened this issue · 5 comments

We have a simple reproducer:

///usr/bin/env -S clang++ -O0 "$0" -o /tmp/demo && exec /tmp/demo "$@"
#include <iostream>
#include <fstream>
#include <thread>

using namespace std;


extern "C" {
void __attribute__((noinline)) __attribute__((used)) magic_trace_stop_indicator() { }
}

void task() {
    ifstream r;
    ofstream w;
    r.open("/dev/zero", ios::binary);
    w.open("/dev/null", ios::binary);
    char buf[4096] = {0};
    for (int i = 0; i >= 0; i++)
    {
        r.read(buf, sizeof(buf));
        w.write(buf, sizeof(buf));
        if (i % 100 == 0) {
            magic_trace_stop_indicator();
        }
    }
}

int main(int argc, char *argv[])
{
    if (argc > 1) {
        std::cout << "running in thread" << std::endl;
        std::thread t1(task);
        t1.join();
    } else {
        std::cout << "running in main" << std::endl;
        task();
    }
}

magic_trace_stop_indicator can be triggered reliably in main thread, but not in child thread.

How are you invoking magic-trace?

mikea commented

I was able to reproduce it with $ sudo $HOME/bin/magic-trace attach -p 1084651 -multi-thread -trigger .
Stops when running demo without args, doesn't when there's an arg.

$ uname -a
Linux 709L7M3 5.10.0-20-amd64 #1 SMP Debian 5.10.158-2 (2022-12-13) x86_64 GNU/Linux
$ $HOME/bin/magic-trace -version
v1.1.0

Does it work reliably when you attach to the tid (instead of the parent process) without using the -multi-thread parameter?

mikea commented

Does it work reliably when you attach to the tid (instead of the parent process) without using the -multi-thread parameter?

yes, attaching to gettid() without -multi-thread seems to stop as expected

I have also encountered the issue @mikea is seeing. I ended up writing a script that wraps magic-trace and uses fzf to offer me the available thread IDs to attach to.