digitalmars.D.learn - ptrace (process trace system call) on Linux from D
- Matej Nanut (6/6) Apr 25 2012 Hello everyone,
- mta`chrono (42/51) Apr 25 2012 Hello Matej,
- Matej Nanut (20/20) May 03 2012 Thank you for the reply, your recommendation works.
- Matej Nanut (5/5) May 04 2012 (1) I've managed this by putting the extern ptrace declaration in
- Stanislav Blinov (15/18) May 07 2012 You can achieve the same without additional files:
- Artur Skawina (5/27) May 07 2012 struct method names are mangled, including static and extern(C) ones.
- Stanislav Blinov (2/7) May 07 2012 Hmm, that's right. Silly me. Sorry for the confusion.
- mta`chrono (6/19) May 07 2012 I thing core.* (druntime) is the right place for _all_ bindings to libc.
- Matej Nanut (10/13) May 08 2012 Nevermind with that; I've been confused since there are exec*()
- mta`chrono (14/28) May 08 2012 But consider that fork() is a very specific UNIX syscall. There is
- Matej Nanut (29/50) May 08 2012 I think there must be something similiar, but I assume the usages
Hello everyone, I would like to know how to call ptrace (the system call) from D. I don't know what to import or link. If my understanding is correct, I need to create a .di file of some sort with stuff declared in it. How would I do this? Thanks, Matej
Apr 25 2012
Am 25.04.2012 18:36, schrieb Matej Nanut:Hello everyone, I would like to know how to call ptrace (the system call) from D. I don't know what to import or link. If my understanding is correct, I need to create a .di file of some sort with stuff declared in it. How would I do this? Thanks, MatejHello Matej, I guess you're asking for http://linux.die.net/man/2/ptrace. normally it's somewhere deep in druntime but I couldn't find it. Maybe someone is able to add it for you. But neverthenless, you can just put some declaration in your D file and call it. ---- import core.stdc.stdio; import core.sys.posix.sys.types; enum __ptrace_request { PTRACE_TRACEME = 0, PTRACE_PEEKTEXT = 1, PTRACE_PEEKDATA = 2, PTRACE_PEEKUSER = 3, PTRACE_POKETEXT = 4, PTRACE_POKEDATA = 5, PTRACE_POKEUSER = 6, PTRACE_CONT = 7, PTRACE_KILL = 8, PTRACE_SINGLESTEP = 9, PTRACE_GETREGS = 12, PTRACE_SETREGS = 13, PTRACE_GETFPREGS = 14, PTRACE_SETFPREGS = 15, PTRACE_ATTACH = 16, PTRACE_DETACH = 17, PTRACE_GETFPXREGS = 18, PTRACE_SETFPXREGS = 19, PTRACE_SYSCALL = 24, PTRACE_SETOPTIONS = 0x4200, PTRACE_GETEVENTMSG = 0x4201, PTRACE_GETSIGINFO = 0x4202, PTRACE_SETSIGINFO = 0x4203 } extern(C) long ptrace(__ptrace_request request, pid_t pid, void *addr, void *data); void main() { // just call ptrace like you would do in C } ----
Apr 25 2012
Thank you for the reply, your recommendation works. I could however not find ptrace anywhere in druntime. There is only one mention of it in std.process, in a comment. But I do have some other questions: (1) Can I declare a ptrace function which calls the original ptrace? (I would like to check the return value and errno for exception throwing and such). I essentially want to shadow the original. (2) Is it more D-ish to use something like "enum PTRequest { traceMe = 0, ... }" instead of the fully capitalised originals? It doesn't seem to affect the working of things. (3) wait() is declared as returning a pid_t in the manpage, and is declared as such in core.sys.posix.sys.wait. In std.c.process however, it returns an int. I can't even find a process.h in my Linux install. What am I supposed to use? I know it essentially doesn't matter, as pid_t is aliased as int. Are there D alternatives to wait() and fork() that I could use with ptrace() instead of the C posix system functions? (4) Some things are declared only in core.*, not in std.*. Will they be added at some point or is this how it's supposed to be?
May 03 2012
(1) I've managed this by putting the extern ptrace declaration in a seperate file and call it via filename.ptrace in my program. Apparently a new std.process is in the works that does supply a sort of fork(). I'm sorry for not looking through things properly before.
May 04 2012
On Friday, 4 May 2012 at 14:47:05 UTC, Matej Nanut wrote:(1) I've managed this by putting the extern ptrace declaration in a seperate file and call it via filename.ptrace in my program.You can achieve the same without additional files: // This struct acts as a namespace to hide C declarations, // just like separate module struct PtraceApi { static: extern(C) long ptrace(__ptrace_request request, pid_t pid, void *addr, void *data); } long ptrace(__ptrace_request request, pid_t pid, void *addr, void *data) { auto result = PtraceApi.ptrace(request, pid, addr, data); // Check result and errno for errors... }
May 07 2012
On 05/07/12 12:45, Stanislav Blinov wrote:On Friday, 4 May 2012 at 14:47:05 UTC, Matej Nanut wrote:struct method names are mangled, including static and extern(C) ones. (they have to be, or you'd get collisions; a way to turn it off for cases like this one would be useful, yes.) artur(1) I've managed this by putting the extern ptrace declaration in a seperate file and call it via filename.ptrace in my program.You can achieve the same without additional files: // This struct acts as a namespace to hide C declarations, // just like separate module struct PtraceApi { static: extern(C) long ptrace(__ptrace_request request, pid_t pid, void *addr, void *data); } long ptrace(__ptrace_request request, pid_t pid, void *addr, void *data) { auto result = PtraceApi.ptrace(request, pid, addr, data); // Check result and errno for errors... }
May 07 2012
On Monday, 7 May 2012 at 11:30:33 UTC, Artur Skawina wrote:struct method names are mangled, including static and extern(C) ones. (they have to be, or you'd get collisions; a way to turn it off for cases like this one would be useful, yes.)Hmm, that's right. Silly me. Sorry for the confusion.
May 07 2012
(2) Is it more D-ish to use something like "enum PTRequest { traceMe = 0, ... }" instead of the fully capitalised originals? It doesn't seem to affect the working of things.Yes, that's more D-ish. In new D code I prefer the camelcased ones, but there are cases where you'd like to use the original ones. it's up to! ;-)(3) wait() is declared as returning a pid_t in the manpage, and is declared as such in core.sys.posix.sys.wait. In std.c.process however, it returns an int. I can't even find a process.h in my Linux install. What am I supposed to use? I know it essentially doesn't matter, as pid_t is aliased as int. Are there D alternatives to wait() and fork() that I could use with ptrace() instead of the C posix system functions? (4) Some things are declared only in core.*, not in std.*. Will they be added at some point or is this how it's supposed to be?I thing core.* (druntime) is the right place for _all_ bindings to libc. But yeha, there are still some relicts in std.c.* of the good old days. What do you meant by "D alternatives to wait() and fork() that could be used with ptrace()". Maybe I don't understand your intention.
May 07 2012
On Monday, 7 May 2012 at 22:56:07 UTC, mta`chrono wrote:What do you meant by "D alternatives to wait() and fork() that could be used with ptrace()". Maybe I don't understand your intention.Nevermind with that; I've been confused since there are exec*() functions in std.process, but no wait() and fork(). I think there's a new std.process in the works that has more D-ish ways to do these. And thanks for the core.* VS std.c.* clarification. I didn't even think of using core.* all the way for libc bindings. If struct method names are mangled, does that mean that that way of doing it doesn't work? I'll try it anyway, to try and get rid of a few extra files.
May 08 2012
Am 08.05.2012 18:12, schrieb Matej Nanut:On Monday, 7 May 2012 at 22:56:07 UTC, mta`chrono wrote:But consider that fork() is a very specific UNIX syscall. There is nothing similar like that on Windows. That's maybe why they didn't wrap it in Phobos. Maybe the same applies to wait() that seems to rely on the UNIX signal stuff. But there should be some kind of derivate on windows, too. But neverthenless you are free to use every C-Funktion. You just need some kind of definition to tell dmd to create the right symbols. If the definition is already present in druntime, it's fine - just use it! otherwise you have to define it yourself.What do you meant by "D alternatives to wait() and fork() that could be used with ptrace()". Maybe I don't understand your intention.Nevermind with that; I've been confused since there are exec*() functions in std.process, but no wait() and fork(). I think there's a new std.process in the works that has more D-ish ways to do these. And thanks for the core.* VS std.c.* clarification. I didn't even think of using core.* all the way for libc bindings.If struct method names are mangled, does that mean that that way of doing it doesn't work? I'll try it anyway, to try and get rid of a few extra files.It shouldn't work. But you can add another custom ptrace method (_NOT_ extern(C)) with different operators. If you can give more information of your superior intention (what are you going to create?) then I'll might provide a better assistance!
May 08 2012
On Tuesday, 8 May 2012 at 16:41:55 UTC, mta`chrono wrote:But consider that fork() is a very specific UNIX syscall. There is nothing similar like that on Windows. That's maybe why they didn't wrap it in Phobos.Ah yes, very true. I didn't think of that.Maybe the same applies to wait() that seems to rely on the UNIX signal stuff. But there should be some kind of derivate on windows, too.I think there must be something similiar, but I assume the usages are slightly different and as such wrapping these things into a common API might hinder performance. Also, since I need these for use with ptrace, the program will only run on Linux (maybe POSIX?) systems anyway (I don't think Windows has ptrace?).I do kinda want the same operators though.If struct method names are mangled, does that mean that that way of doing it doesn't work? I'll try it anyway, to try and get rid of a few extra files.It shouldn't work. But you can add another custom ptrace method (_NOT_ extern(C)) with different operators.If you can give more information of your superior intention (what are you going to create?) then I'll might provide a better assistance!I basically want to track system calls and mess with the program issuing them. (As per ptrace(PTRACE_SYSCALL, ...).) The common pattern of doing something like this is: --- void main(string[] args) { pid_t childPid; switch (childPid = fork()) { case -1: /* error stuff */ break; case 0: ptrace(PTRACE_TRACEME, 0, null, null); execvp(args[1], args[1 .. $]); break; default: /* do ptrace magic in parent */ break; } } --- And for this I would like the most D-ish way of importing/including/linking wait(), fork() and ptrace(). :-) Thanks, Matej
May 08 2012