blob: 4545f831dc961860e9bda32cf1b307b80561e397 [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
15All this machinery is in vg_syscall_mem.c.
16
17
18What are syscall/ioctl wrappers? What do they do?
19~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20Valgrind does what it does, in part, by keeping track of the status of
21all bytes of memory accessible by your program. When a system call
22happens, for example a request to read part of a file, control passes
23to the Linux kernel, which fulfills the request, and returns control
24to your program. The problem is that the kernel will often change the
25status of some part of your program's memory as a result.
26
27The job of syscall and ioctl wrappers is to spot such system calls,
28and update Valgrind's memory status maps accordingly. This is
29essential, because not doing so would cause you to be flooded with
30errors later on, and, in general, because it's important that
31Valgrind's idea of accessible memory corresponds to that of the Linux
32kernel's. And for other reasons too.
33
34In addition, Valgrind takes the opportunity to perform some sanity
35checks on the parameters you are presenting to system calls. This
36isn't essential for the correct operation of Valgrind, but it does
37allow it to warn you about various kinds of misuses which would
38otherwise mean your program just dies without warning, usually with a
39segmentation fault.
40
41So, let's look at an example of a wrapper for a system call which
42should be familiar to many Unix programmers.
43
44
45The syscall wrapper for read()
46~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
47Removing the debug printing clutter, it looks like this:
48
49 case __NR_read: /* syscall 3 */
50 /* size_t read(int fd, void *buf, size_t count); */
51 must_be_writable( "read(buf)", arg2, arg3 );
52 KERNEL_DO_SYSCALL(res);
53 if (!VG_(is_kerror)(res) && res > 0) {
54 make_readable( arg2, res );
55 }
56 break;
57
58The first thing we do is check that the buffer, which you planned to
59have the result written to, really is addressible ("writable", here).
60Hence:
61
62 must_be_writable( "read(buf)", arg2, arg3 );
63
64which causes Valgrind to issue a warning if the address range
65[arg2 .. arg2 + arg3 - 1] is not writable. This is one of those
66nice-to-have-but-not-essential checks mentioned above. Note that
67the syscall args are always called arg1, arg2, arg3, etc. Here,
68arg1 corresponds to "fd" in the prototype, arg2 to "buf", and arg3
69to "count".
70
71Now Valgrind asks the kernel to do the system call, depositing the
72return code in "res":
73
74 KERNEL_DO_SYSCALL(res);
75
76Finally, the really important bit. If, and only if, the system call
77was successful, mark the buffer as readable (ie, as having valid
78data), for as many bytes as were actually read:
79
80 if (!VG_(is_kerror)(res) && res > 0) {
81 make_readable( arg2, res );
82 }
83
84The function VG_(is_kerror) tells you whether or not its argument
85represents a Linux kernel return error code. Hence the test.
86
87
88Writing your own syscall wrappers (see below for ioctl wrappers)
89~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
90If Valgrind tells you that system call NNN is unimplemented, do the
91following:
92
931. Find out the name of the system call:
94
95 grep NNN /usr/include/asm/unistd.h
96
97 This should tell you something like __NR_mysyscallname.
98
99
1002. Do 'man 2 mysyscallname' to get some idea of what the syscall
101 does.
102
103
1043. Add a case to the already-huge collection of wrappers in
105 vg_syscall_mem.c. For each in-memory parameter which is read
106 by the syscall, do a must_be_readable or must_be_readable_asciiz
107 on that parameter. Then do the syscall. Then, if the syscall
108 succeeds, issue suitable make_readable/writable/noaccess calls
109 afterwards, so as to update Valgrind's memory maps to reflect
110 the state change caused by the call.
111
112 If you find this difficult, read the wrappers for other syscalls
113 for ideas. A good tip is to look for the wrapper for a syscall
114 which has a similar behaviour to yours, and use it as a
115 starting point.
116
117 If you have to #include headers for structure definitions,
118 put your #includes into vg_unsafe.h.
119
120 Test it.
121
122 Note that a common error is to call make_readable or make_writable
123 with 0 (NULL) as the first (address) argument. This usually means your
124 logic is slightly inadequate. It's a sufficiently common bug that
125 there's a built-in check for it, and you'll get a "probably sanity
126 check failure" for the syscall wrapper you just made, if this is
127 the case.
128
129 Note that many syscalls are bracketed by #if defined(__NR_mysyscall)
130 ... #endif, because they exist only in the 2.4 kernel and not
131 the 2.2 kernel. This enables the same piece of code to serve both
132 kernels. Please try and stick to this convention.
133
134
1354. Once happy, send me the patch. Pretty please.
136
137
138
139
140Writing your own ioctl wrappers
141~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
142Is pretty much the same as writing syscall wrappers.
143
144If you can't be bothered, do a cheap hack: add it (the ioctl number
145emitted in Valgrind's panic-message) to the long list of IOCTLs which
146are noted but not fully handled by Valgrind (search for the text
147"noted but unhandled ioctl" in vg_syscall_mem.c). This will get you
148going immediately, at the risk of giving you spurious value errors.
149
150As above, please do send me the resulting patch.
151
152