On 15.12.2016 16:08, Pavel Labath wrote: > On 15 December 2016 at 14:14, Kamil Rytarowski <n...@gmx.com> wrote: >> On 15.12.2016 14:14, Pavel Labath wrote: >>>>> >>>>> 2. PTRACE_SETSIGINFO - equivalent currently unsupported, I will need to >>>>> add support for it in ptrace(2). >>> This value is currently only used in logging code, so we can just >>> remove it from the code base. However, it's a useful thing to have for >>> the future, so it may be worth making sure the NetBSD kernel supports >>> it. >>> >> >> I was wondering whether waitid(2) or wait6(2) could be used there, as >> they return siginfo_t. If so, NetBSD does not need dedicated ptrace(2) >> entry. > > Note that there are two siginfo_t structures in action here. One is > the siginfo_t the *inferior* gets as a result of some action (e.g. > kill(), raise(), hitting an int3, etc.). The other is the siginfo_t > corresponding to the SIGCHLD that the *debugger* gets when something > interesting happens to the inferior. (On linux at least ), waitid(2) > returns the second one. That one, however, generally does not contain > any useful information apart from the process ID. PTRACE_GETSIGINFO > returns the first one, and that one contains the interesting stuff > (the signal the inferior recieved, and in case of a SIGTRAP, the > information about the debug event is encoded there as well). This is > usually very important information for the debugger. > > PTRACE_SETSIGINFO allows you to overwrite the signal that the inferior > would receive. It can be used to inject "fake" signals into the > inferior. That can be a useful feature from time to time, but > currently we do not support that (on linux we support injecting a > signal via an argument to PTRACE_CONTINUE, which is a weaker > implementation of this call, as it can only inject a signal number, > not the full siginfo_t struct). So you may want to implement this at > some point, but on the grand scale of things, it's not something very > important. > >
I see, thank you for your explanation! It looks useful, but let it keep for later. >> >>>>> >>>>> 3. PTRACE_O_TRACEEXEC, PTRACE_O_TRACECLONE, PTRACE_O_TRACEEXIT - >>>>> equivalent to be implemented. >>> Do you mean "implemented in lldb-server" or "implemented in the >>> kernel"? Being notified when the inferior exec()s would definitely be >>> good. Tracing thread creation and exit is a nice-to-have but low >>> priority. The only reason we used it on linux is because that's the >>> only way to auto-attach to new threads, but I think that for you that >>> will happen automatically. >>> >> >> I mean implemented in the kernel. >> >> Thread (lwp) creation and termination is currently detectable in FreeBSD >> with a special event, if this is useful in the NetBSD context -- like a >> user setting a break on this event explicitly -- I will add it to TODO >> list. On NetBSD there is no need to explicitly start tracing new >> threads, tracing is per process and it is composed of a bulk of threads >> (lwp). POSIX threads are a layer with extra features built upon LWP. > BTW, are your debug registers per-process or per-thread? If they are > per thread, then you will need to hook thread creation so you can > inject the correct watchpoints and stuff, otherwise you will miss some > hits. If this is handled by the kernel, then you are probably fine. > Debug registers (watchpoints) are per-thread (lwp) and they are not being inherited on thread's or process' forks. It's a valid use-case. I just checked FreeBSD and there is PTRACE_LWP: This event flag controls tracing of LWP kernel thread creation and destruction. When this event is enabled, new LWPs will stop and report an event with PL_FLAG_BORN set before executing their first instruction, and exiting LWPs will stop and report an event with PL_FLAG_EXITED set before completing their termination. >> >> There is also the the exect(3) call in our libc inherited from BSD4.2, >> but it no longer works in a useful way. It used to singlestep execve(2) >> call. I was thinking whether/how to make it useful again, like combine >> in it execve(2) + PT_TRACE_ME + SIGSTOP/SIGTRAP on exec. >> >>>>> >>>>> 4. No tracing of VFORK events implemented. >>>>> >>>>> 5. Hardware assisted watchpoints (debug registers on amd64) have their >>>>> dedicated ptrace(2) API to set/unset watchpoints, they do not export raw >>>>> debug registers. >>>>> >>>>> 6. Other ptrace(2) calls have their equivalents on NetBSD >>>>> (PTRACE_PEEKUSER, PTRACE_POKEUSER etc). >>> Cool, I guess that means we can share (Read|Write)Memory(WithoutTrap|). >>> >> >> Functionality is the same, however the API is different. > Ok. If the api differs by too much, then we might as well keep them as > separate implementations. We'll see how it goes. > We will see how it goes. >> >>>>> >>>>> 7. SIGTRAP has currently only two si_code values (specified by POSIX). >>> The code for decoding si_code values is already messy and in need of a >>> rewrite. I think the act of decoding si_code values will need to be >>> OS- (and maybe event architecture-) specific, but the actions taken >>> upon individual events should be quite similar. >>> >> >> I was wondering whether it is useful to return distinct si_code for >> hardware assisted traps or PT_STEP. At the moment I ignored it. > If you are able to do that, then I'd recommend you go for it. It's > very useful to be able to figure out what caused the application to > stop. > It looks trivial to be implemented for x86, my original concern was usefulness of this information. My another concern was whether it's useful to keep PT_STEP and hardware watchpoints enabled at the same time (before returning to userspace and resuming a thread). And third issue was whether this feature can be portable (property retained) across capable ports (platforms). > Imagine the following situation: The user does a single-step and the > app stops with a SIGTRAP. What do you display to the user? Most likely > the SIGTRAP just means the single-step completed. However, any one of > the following things could happen: > - the instruction happened to trigger a watchpoint (you should report > that instead) > - the instruction happened to be the syscall instruction corresponding > to the raise(SIGTRAP) done by the application > - a random other application sent a SIGTRAP to your process > > The more information we get, the easier it is to display something > meaningful to the user. > > I makes sense. I think we could move it for TODO list for later and make the core functional first. >>> Agreed. The only thing that slightly worries me is the lack of >>> execve() tracing capability, if I understood correctly. While it >>> probably may be possible to work without it. I'd think about adding it >>> nonetheless. >>> >> >> I'm going to research it now and in case of required - as in >> implementing a debugger much easier -- I will go for it and add support. > > A debugger needs to know when the running image has changed, so that > it can e.g. rescan the symbol table and insert new breakpoints. I > think it would be quite hard to debug across an execve() without it. > There is also PT_SYSCALL to catch each syscall... so maybe add a dedicated filter to tap interesting system calls. It would handle thread (lwp) events and actions like execve(2). I don't think that performance is critical for tracee -- as breaking on each syscall slows the things down. I'm prioritizing reusing of already existing interfaces. I will research how is it done with GDB. > cheers, > pl >
signature.asc
Description: OpenPGP digital signature
_______________________________________________ lldb-dev mailing list lldb-dev@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev