> Another question. How can ->report_signal(info) change info->si_signo > (or other data in *info) when we have multiple engines? I mean, how > can engines cooperate if they want to change ->si_signo.
This is just an instance of the general subject of engine cooperation when engines do perturbation. Each engine's report_signal callback gets arguments saying what the previous engine decided to do. This includes the enum utrace_signal_action, the siginfo_t contents, and the sigaction--as well as all of the user registers and memory. Each engine can change any of those how it sees fit. > For example, ptrace_report_signal() sets ->si_signo = SIGTRAP. But > if we have another engine attached before ptrace-engine, then its > ->report_signal() was already called. This means that engine can't > know about this SIGTRAP? Well, there wasn't any SIGTRAP. That engine doesn't know about the virtual reality that the ptrace engine is creating. In the same way, if that engine A precedes an engine C whose report_quiesce(0) changes the user registers, then A will never know that user-mode ran with different register contents than what its report_quiesce(0) observed. That's just the fundamental nature of there being an ordering among engines. Similarly, if engine C follows the ptrace engine, it will perceive(*) that there was a SIGTRAP that the ptrace engine then decided to ignore. *unless it checks the orig_ka argument, which is NULL to indicate that there this is a UTRACE_SIGNAL_{REPORT,HANDLER} pass without an original real signal. > In short. If any engine changes *info, how should it take into account > other engines attached before? If you are perturbing the state, then you've decided you don't really care about what came before. An engine like ptrace is not really trying to keep out of the way of other engines, it's just doing what it does. The intent of the API is that every engine has the opportunity to be informed about what other engines are doing, and make its own decisions. The fact of ordering and the linear nature of time means that each engine can't really be aware of every other engine all the time, only the earlier ones in the list (and indirectly see the effects of later ones after the fact through means like UTRACE_REPORT). > ptrace also changes *info via ->last_siginfo. IOW, the owner of engine > plays with info, not ->report_signal(). I assume that ptrace is the only > engine which "has rights" to play with *info outside of ->report_signal(), > right? Well, it certainly doesn't seem like all that clean a thing to do. But the kerneldoc for the report_signal API does document: For a report without a new signal, @info * is left uninitialized and must be set completely by an engine that * chooses to deliver a signal; if there was a previous @report_signal * callback ending in %UTRACE_STOP and it was just resumed using * %UTRACE_REPORT or %UTRACE_INTERRUPT, then @info is left unchanged * from the previous callback. In this way, the original signal can * be left in @info while returning %UTRACE_STOP|%UTRACE_SIGNAL_IGN * and then found again when resuming @task with %UTRACE_INTERRUPT. So I think the bottom line is that this is something that you can fiddle with just like you can fiddle with the registers. All sorts of such fiddling are possible, and don't break any core assumptions of the utrace API. It's just a question of what fiddling is really a good idea and how to mediate higher-level choices about that. You don't risk any bad effects beyond what some unhelpful engine (or just userland run wild) might do anyway, i.e. scrambling user registers and siginfo_t so they foul up application behavior. But that's just a baseline limit on harm. At higher levels you want to cooperate with other engines so they all work together usefully in practice. The API offers only one mechanism to synchronize with anyone else fiddling such things. That is to do the fiddling in your report_* callbacks where you are explicitly serialized with the callbacks of other engines and have specified ways to be sure you observe what they do. I think it's entirely reasonable to say that only ptrace should fiddle with siginfo_t outside of report_signal callbacks, just as a convention about what's couth. But that's beyond the scope of the utrace API level itself. Thanks, Roland