How to see system call that executed in current time by process?
proc
offers some information about what the kernel is currently doing "for" a process
/proc/${pid}/syscall
/proc/${pid}/stack
More information:
- http://man7.org/linux/man-pages/man5/proc.5.html
- http://blog.tanelpoder.com/2013/02/21/peeking-into-linux-kernel-land-using-proc-filesystem-for-quickndirty-troubleshooting/
Can strace tell me where in my code a syscall is called?
Using gdb, you can set conditional syscall catchpoints based on the args to the system call (analogous to the way you'd set conditional breakpoints on entry to a function based on the args to the function call). Then, when the catchpoint is triggered, you can see where the caller is (file name, line number, and source code).
Here's an example for x86_64.
$ cat gtest.c
#include <unistd.h>
int main()
{
write(1, "text\n", 5);
write(2, "text2\n", 6);
write(2, "\n", 1);
return 0;
}
$ cc gtest.c -g -o gtest
$ gdb -q gtest
Reading symbols from gtest...done.
(gdb) list
1 #include <unistd.h>
2 int main()
3 {
4 write(1, "text\n", 5);
5 write(2, "text2\n", 6);
6 write(2, "\n", 1);
7 return 0;
8 }
(gdb) catch syscall write
Catchpoint 1 (syscall 'write' [1])
(gdb) condition 1 $rdi == 2 && *(char *)$rsi == '\n' && $rdx == 1
(gdb) r
Starting program: /home/mp/gtest
text
text2
Catchpoint 1 (call to syscall write), 0x00007fffff13b970 in __write_nocancel ()
at ../sysdeps/unix/syscall-template.S:84
84 ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb) bt
#0 0x00007fffff13b970 in __write_nocancel () at ../sysdeps/unix/syscall-template.S:84
#1 0x00000000080006f6 in main () at gtest.c:6
(gdb) up
#1 0x00000000080006f6 in main () at gtest.c:6
6 write(2, "\n", 1);
(gdb)
Tracing a C blocking system call
Whenever a process issues a system call (such as a blocking read(2)
), the process starts to execute in kernel mode, that is, the kernel code that handles the particular system call is invoked.
After that, depending on the underlying device and the driver, the process can be suspended and put in a wait-queue. When a key is pressed, the kernel code that handles interrupts is invoked and from there it is deducted which key is pressed.
The kernel then resumes the process that is waiting for this input, and delivers the data by copying it from the kernel address space to the particular process' address space.
How to retrieve arguments passed to linux system call in C?
The arguments passed to open
(and any other case a system call receives a string) are pointers to the string's location in memory.
Unfortunately for you, these pointers are for the debugee's address space, and cannot be directly referenced from the debugger's address space.
The ptrace
documentation would have you repeatedly call ptrace(PTRACE_PEEKDATA...)
to obtain the string, 4 (or 8, depending on platform) bytes at a time. You can see an example of how to do that in the old fakeroot-ng code. Note that that code is under the GPL, so don't copy verbatim unless you are writing code of a compatible license.
Fortunately, there is a method of getting the data that is both simpler and faster. It is less portable, but if you're writing ptrace
code, you usually don't care.
The tracer thread can open the file /proc/pid/mem
(where pid is, of course, the numerical pid of the debugee). Note that only the ptracer of pid can open that file.
Once that file is open, you can pread
(2) from it at the offset of the address you want, and get the data directly from the debugee's address space. Since the read
interface isn't limited to four bytes, you can guess at the string's length, read that much bytes in, and then find the terminating NULL and know the precise string.
Since you are invoking less system calls, this method is not only easier, it is also much faster.
Related Topics
How to Keep Directory Structure with Aria2
How to Block Push to Master Branch on Remote
How to Redirect Ip Address Using Iptables
Nm Reports Symbol Is Defined But Ldd Reports Symbol Is Undefined
Crontab - Simple Echo Not Running
Differences Between Arm "Versions" (Armv7 Only)
How to Get Command History by Cursor Key in Linux Tclsh
Bash: Loop Until Command Exit Status Equals 0
Surprise! The Shell Suggests Command Line Switches
When Using Cpan in Linux Ubuntu Should I Run It Using Sudo/As Root or as My Default User
Can Not Install Software in Linux Error as Dpkg Was Interrupted
Udev Rule with Few Parent Device Attributes
How to Find The List of Processes Using a Particular Kernel Module
Cross-Platform Build Under Windows Targeting Linux Using Cmake