> I am using utrace for a school project. Great! Thanks for your interest in utrace.
> I would like to trace system calls for an application an all its > descendants, and transmit them to user space. I have implemented a > circular buffer, in which i can place a simple message, and then export > the buffer to user space with a character device. Feel free to share your code here even if it's not at all ready for prime time. > (i did it with set_current_status(TASK_INTERRUPTIBLE) and sleep() then > wake_up_task from the producers). That's the fundamental way to do it, and the correct style of thing from the utrace perspective. You might want to use some slightly higher-level facilities available in the kernel (that translate into that same sort of thing at low level), such as wait_event_interruptible() (linux/wait.h), wait_for_completion_interruptible (linux/completion.h), etc. > I tried to synchronized the consumers with UTRACE_STOP and > utrace_control(UTRACE_RESUME) and it works fine. Excellent! > The problem is that (if i understood correctly) when returning from > UTRACE_STOP from a monitor function like SYSCALL_ENTRY, my callback won' > be called again for the same system call on UTRACE_RESUME. This way if > the buffer is full and i return UTRACE_STOP, i will loose the possibility > to log the syscall_entry into the buffer. This exact problem is addressed in recent versions of utrace (with UTRACE_API_VERSION >= 20090421). If you use UTRACE_REPORT rather than UTRACE_RESUME, then report_syscall_entry will be called a second time. This time its @action will have the UTRACE_SYSCALL_RESUMED bit set. That flag tells you that this is a second (or later) repeated report for the same syscall entry after your engine or another one has used UTRACE_STOP and then resumed. There is another wrinkle about this that you will encounter when working with another engine that might modify syscall parameters (e.g. kmview or ptrace). The recommended protocol is to do: if (utrace_resume_action(action) == UTRACE_STOP) return UTRACE_SYSCALL_RUN | UTRACE_REPORT; first thing, even if you don't need to stop for your own work. That handles the case where another engine has stopped the thread so as to fiddle with its registers. You won't do your notification/logging yet, but instead get the next callback with (action & UTRACE_SYSCALL_RESUMED) when you can see the registers as modified by the other engine. Note that one or more other engines might stop and resume multiple times before actually letting the syscall proceed. So you should check the incoming utrace_resume_action as above even for a call that comes in with UTRACE_SYSCALL_RESUMED set. > Calling schedule() from the utrace callback while the buffer is full > would solve the problem, but as i understand that is not recommended, > since it doesn't play nice with other monitoring engines that might be > active. Correct. Don't do that! > How could i solve this problem and still be friendly with utrace? I think UTRACE_REPORT->UTRACE_SYSCALL_RESUMED takes care of your issue. Thanks, Roland