Should a thead init callback ever be called more than once for a given thread?
My client prints a startup message (with [pid]) and registers a thread init
callback which prints [pid/tid]. It also registers a thread exit callback.
Generally it works like I expect. But for some targets I see
something like this:
### [19361] CLIENT STARTUP
### [19361/19361] Thread start
### [19362/19362] Thread start
### [19362] CLIENT STARTUP
### [19362/19362] Thread start
### [19362/19362] Thread exit
### [19361/19361] Thread exit
### [19363/19363] Thread start
### [19363] CLIENT STARTUP
### [19363/19363] Thread start
### [19363/19363] Thread exit
So when 19361 forks a new process 19362, in that new process the
thread_init callback for 19362 is called first, then dr_client_main,
then the thread_init callback is called again.
Why would a thread_init callback be called twice for the same thread?
My guess is it's something like this:
- 19361 calls fork()
- in the new process 19362 (which is for the time being a copy
of 19361) DynamoRIO notices a new thread and calls thread_init -
even though the thread has a copy of the state from 19361
- 19362 then calls exec() to replace the old image with a new one,
DynamoRIO does some magic to inject itself into that new
executable, and relaunch the client, so we get a client startup
message and then another thread_init for 19362
If my client is maintaining per-thread state, it would seem logical
to ignore at least one of these thread_inits. Is there some guidance
on the best way to maintain per-thread state in a way that works
nicely with forks and execs?