Now, ASN.1 may not strictly be an API, but it's pretty crap.
Not only that, if you're writing a debugger you all but have to lean on parsing procfs, which itself is a really horrible API…
> Special mention goes to its use of signals for IPC, which makes ptrace() nearly impossible to use in multithreaded applications or high-level languages, and is especially prone to "gotchas" and implementation errors.
Yep, you really gotta keep track of all your tracees. If you're not aggressively making sure you're notified of every single thing a tracee can possibly do to change itself (and there sure is a lot) you're going to have a really bad time.
> IIRC, tracing a process which receives an external SIGTRAP signal is especially difficult, as ptrace() uses that signal to indicate that the traced process made a system call.
Ooh, I know this! I just came off of implementing it on the kernel side because GDB obviously cares (and if you don't do it right, it won't "rewind" one instruction after the child stops when necessary and your disassembly will be off). You're supposed to call ptrace(PTRACE_GETSIGINFO, …) and check si_code, which for a real signal will be SIGTRAP (yes, the value of SIGTRAP itself; 5 on my machine) and for a syscall stop will be SI_USER (0 on my machine). Of course you'll only get a stop on a system call if you specifically request it, and I think some newer kernels support PTRACE_O_TRACESYSGOOD, which is meant for this kind of thing, but I did the laziest job I possibly could in my implementation and just told userspace I don't support such things ;)