blob: 1e049e0301185fa5f4ad7f464b7d0abf23100112 [file] [log] [blame]
sewardjde4a1d02002-03-22 01:27:54 +00001
2Dealing with missing system call or ioctl wrappers in Valgrind
3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4You're probably reading this because Valgrind bombed out whilst
5running your program, and advised you to read this file. The good
6news is that, in general, it's easy to write the missing syscall or
7ioctl wrappers you need, so that you can continue your debugging. If
8you send the resulting patches to me, then you'll be doing a favour to
9all future Valgrind users too.
10
11Note that an "ioctl" is just a special kind of system call, really; so
12there's not a lot of need to distinguish them (at least conceptually)
13in the discussion that follows.
14
njn75b31b32003-06-12 11:24:10 +000015All this machinery is in coregrind/vg_syscalls.c.
sewardjde4a1d02002-03-22 01:27:54 +000016
17
18What are syscall/ioctl wrappers? What do they do?
19~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
njn75b31b32003-06-12 11:24:10 +000020Valgrind does what it does, in part, by keeping track of everything your
21program does. When a system call happens, for example a request to read
22part of a file, control passes to the Linux kernel, which fulfills the
23request, and returns control to your program. The problem is that the
24kernel will often change the status of some part of your program's memory
25as a result, and skins (instrumentation plug-ins) may need to know about
26this.
sewardjde4a1d02002-03-22 01:27:54 +000027
njn75b31b32003-06-12 11:24:10 +000028Syscall and ioctl wrappers have two jobs:
sewardjde4a1d02002-03-22 01:27:54 +000029
njn75b31b32003-06-12 11:24:10 +0000301. Tell a skin what's about to happen, before the syscall takes place. A
31 skin could perform checks beforehand, eg. if memory about to be written
32 is actually writeable. This part is useful, but not strictly
33 essential.
34
352. Tell a skin what just happened, after a syscall takes place. This is
36 so it can update its view of the program's state, eg. that memory has
37 just been written to. This step is essential.
38
39The "happenings" mostly involve reading/writing of memory.
sewardjde4a1d02002-03-22 01:27:54 +000040
41So, let's look at an example of a wrapper for a system call which
42should be familiar to many Unix programmers.
43
44
njn75b31b32003-06-12 11:24:10 +000045The syscall wrapper for time()
sewardjde4a1d02002-03-22 01:27:54 +000046~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
47Removing the debug printing clutter, it looks like this:
48
njn75b31b32003-06-12 11:24:10 +000049 case __NR_time: /* syscall 13 */
50 /* time_t time(time_t *t); */
51 if (arg1 != (UInt)NULL) {
52 SYSCALL_TRACK( pre_mem_write, tst, "time", arg1, sizeof(time_t) );
53 }
54 KERNEL_DO_SYSCALL(tid,res);
55 if (!VG_(is_kerror)(res) && arg1 != (UInt)NULL) {
56 VG_TRACK( post_mem_write, arg1, sizeof(time_t) );
57 }
58 break;
sewardjde4a1d02002-03-22 01:27:54 +000059
njn75b31b32003-06-12 11:24:10 +000060The first thing we do is, if a non-NULL buffer is passed in as the argument,
61tell the skin that the buffer is about to be written to:
sewardjde4a1d02002-03-22 01:27:54 +000062
njn75b31b32003-06-12 11:24:10 +000063 if (arg1 != (UInt)NULL) {
64 SYSCALL_TRACK( pre_mem_write, tst, "time", arg1, sizeof(time_t) );
65 }
sewardjde4a1d02002-03-22 01:27:54 +000066
njn75b31b32003-06-12 11:24:10 +000067Now Valgrind asks the kernel to actally do the system call, for the thread
68identified by thread ID "tid", depositing the return value in "res":
sewardjde4a1d02002-03-22 01:27:54 +000069
njn75b31b32003-06-12 11:24:10 +000070 KERNEL_DO_SYSCALL(tid, res);
sewardjde4a1d02002-03-22 01:27:54 +000071
72Finally, the really important bit. If, and only if, the system call
njn75b31b32003-06-12 11:24:10 +000073was successful, tell the skin that the memory was written:
sewardjde4a1d02002-03-22 01:27:54 +000074
njn75b31b32003-06-12 11:24:10 +000075 if (!VG_(is_kerror)(res) && arg1 != (UInt)NULL) {
76 VG_TRACK( post_mem_write, arg1, sizeof(time_t) );
77 }
sewardjde4a1d02002-03-22 01:27:54 +000078
79The function VG_(is_kerror) tells you whether or not its argument
80represents a Linux kernel return error code. Hence the test.
81
82
83Writing your own syscall wrappers (see below for ioctl wrappers)
84~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
85If Valgrind tells you that system call NNN is unimplemented, do the
86following:
87
881. Find out the name of the system call:
89
90 grep NNN /usr/include/asm/unistd.h
91
92 This should tell you something like __NR_mysyscallname.
93
94
952. Do 'man 2 mysyscallname' to get some idea of what the syscall
96 does.
97
98
993. Add a case to the already-huge collection of wrappers in
njn39209d42003-06-13 15:02:29 +0000100 coregrind/vg_syscalls.c. For each in-memory parameter which is
101 read or written by the syscall, do one of
njn75b31b32003-06-12 11:24:10 +0000102
103 SYSCALL_TRACK( pre_mem_read, ... )
104 SYSCALL_TRACK( pre_mem_read_asciiz, ... )
105 SYSCALL_TRACK( pre_mem_write, ... )
106
107 for that parameter. Then do the syscall. Then, if the syscall
108 succeeds, issue suitable VG_TRACK( post_mem_write, ... ) calls.
109 (There's no need for post_mem_read calls.)
110
sewardjde4a1d02002-03-22 01:27:54 +0000111 If you find this difficult, read the wrappers for other syscalls
112 for ideas. A good tip is to look for the wrapper for a syscall
113 which has a similar behaviour to yours, and use it as a
114 starting point.
115
116 If you have to #include headers for structure definitions,
117 put your #includes into vg_unsafe.h.
118
119 Test it.
120
njn75b31b32003-06-12 11:24:10 +0000121 Note that a common error is to call VG_TRACK( post_mem_write, ... )
122 with 0 (NULL) as the first (address) argument. This usually means
123 your logic is slightly inadequate. It's a sufficiently common bug
124 that there's a built-in check for it, and you'll get a "probably
125 sanity check failure" for the syscall wrapper you just made, if this
126 is the case.
sewardjde4a1d02002-03-22 01:27:54 +0000127
128 Note that many syscalls are bracketed by #if defined(__NR_mysyscall)
129 ... #endif, because they exist only in the 2.4 kernel and not
130 the 2.2 kernel. This enables the same piece of code to serve both
131 kernels. Please try and stick to this convention.
132
133
1344. Once happy, send me the patch. Pretty please.
135
136
137
138
139Writing your own ioctl wrappers
140~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
141Is pretty much the same as writing syscall wrappers.
142
njn75b31b32003-06-12 11:24:10 +0000143There's a default case, sometimes it isn't correct and you have to write a
144more specific case to get the right behaviour.
sewardjde4a1d02002-03-22 01:27:54 +0000145
146As above, please do send me the resulting patch.
147
148