blob: 231f693cd0af1775e6d3887d63719d91746fbab4 [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
nethercote137bc552003-11-14 17:47:54 +000025as a result, and tools (instrumentation plug-ins) may need to know about
njn75b31b32003-06-12 11:24:10 +000026this.
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
nethercote137bc552003-11-14 17:47:54 +0000301. Tell a tool what's about to happen, before the syscall takes place. A
31 tool could perform checks beforehand, eg. if memory about to be written
njn75b31b32003-06-12 11:24:10 +000032 is actually writeable. This part is useful, but not strictly
33 essential.
34
nethercote137bc552003-11-14 17:47:54 +0000352. Tell a tool what just happened, after a syscall takes place. This is
njn75b31b32003-06-12 11:24:10 +000036 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
nethercote98ae6da2004-01-19 19:32:30 +000049 PRE(time)
50 {
njn75b31b32003-06-12 11:24:10 +000051 /* time_t time(time_t *t); */
nethercoteef0c7662004-11-06 15:38:43 +000052 PRINT("time ( %p )",arg1);
53 if (arg1 != (UWord)NULL) {
54 PRE_MEM_WRITE( "time", arg1, sizeof(time_t) );
njn75b31b32003-06-12 11:24:10 +000055 }
nethercote98ae6da2004-01-19 19:32:30 +000056 }
57
58 POST(time)
59 {
nethercoteef0c7662004-11-06 15:38:43 +000060 if (arg1 != (UWord)NULL) {
61 POST_MEM_WRITE( arg1, sizeof(vki_time_t) );
njn75b31b32003-06-12 11:24:10 +000062 }
nethercote98ae6da2004-01-19 19:32:30 +000063 }
sewardjde4a1d02002-03-22 01:27:54 +000064
nethercote98ae6da2004-01-19 19:32:30 +000065The first thing we do happens before the syscall occurs, in the PRE() function:
66if a non-NULL buffer is passed in as the argument, tell the tool that the
67buffer is about to be written to:
sewardjde4a1d02002-03-22 01:27:54 +000068
nethercoteef0c7662004-11-06 15:38:43 +000069 if (arg1 != (UWord)NULL) {
70 PRE_MEM_WRITE( "time", arg1, sizeof(vki_time_t) );
njn75b31b32003-06-12 11:24:10 +000071 }
sewardjde4a1d02002-03-22 01:27:54 +000072
nethercote98ae6da2004-01-19 19:32:30 +000073Finally, the really important bit, after the syscall occurs, in the POST()
74function: if, and only if, the system call was successful, tell the tool that
75the memory was written:
sewardjde4a1d02002-03-22 01:27:54 +000076
nethercote98ae6da2004-01-19 19:32:30 +000077 if (arg1 != (UInt)NULL) {
nethercoteef0c7662004-11-06 15:38:43 +000078 POST_MEM_WRITE( arg1, sizeof(vki_time_t) );
njn75b31b32003-06-12 11:24:10 +000079 }
sewardjde4a1d02002-03-22 01:27:54 +000080
fitzhardinge603e8c52004-01-19 22:02:43 +000081The POST() function won't be called if the syscall failed, so you
82don't need to worry about checking that in the POST() function.
83(Note: this is sometimes a bug; some syscalls do return results when
84they "fail" - for example, nanosleep returns the amount of unslept
85time if interrupted. TODO: add another per-syscall flag for this
86case.)
sewardjde4a1d02002-03-22 01:27:54 +000087
nethercoteef0c7662004-11-06 15:38:43 +000088Note that we use the type 'vki_time_t'. This is a copy of the kernel
89type, with 'vki_' prefixed. Our copies of such types are kept in the
90appropriate vki*.h file(s). We don't include kernel headers or glibc headers
91directly.
92
sewardjde4a1d02002-03-22 01:27:54 +000093
94Writing your own syscall wrappers (see below for ioctl wrappers)
95~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
96If Valgrind tells you that system call NNN is unimplemented, do the
97following:
98
991. Find out the name of the system call:
100
101 grep NNN /usr/include/asm/unistd.h
102
103 This should tell you something like __NR_mysyscallname.
nethercotef94fe2f2004-09-10 14:23:59 +0000104 Copy this entry to coregrind/$(VG_PLATFORM)/vki_unistd.h.
sewardjde4a1d02002-03-22 01:27:54 +0000105
nethercoteef0c7662004-11-06 15:38:43 +0000106
sewardjde4a1d02002-03-22 01:27:54 +00001072. Do 'man 2 mysyscallname' to get some idea of what the syscall
fitzhardinge603e8c52004-01-19 22:02:43 +0000108 does. Note that the actual kernel interface can differ from this,
109 so you might also want to check a version of the Linux kernel
110 source.
111
112 NOTE: any syscall which has something to do with signals or
113 threads is probably "special", and needs more careful handling.
114 Post something to valgrind-developers if you aren't sure.
sewardjde4a1d02002-03-22 01:27:54 +0000115
116
1173. Add a case to the already-huge collection of wrappers in
njn39209d42003-06-13 15:02:29 +0000118 coregrind/vg_syscalls.c. For each in-memory parameter which is
119 read or written by the syscall, do one of
njn75b31b32003-06-12 11:24:10 +0000120
nethercoteef0c7662004-11-06 15:38:43 +0000121 PRE_MEM_READ( ... )
122 PRE_MEM_RASCIIZ( ... )
123 PRE_MEM_WRITE( ... )
njn75b31b32003-06-12 11:24:10 +0000124
125 for that parameter. Then do the syscall. Then, if the syscall
nethercoteef0c7662004-11-06 15:38:43 +0000126 succeeds, issue suitable POST_MEM_WRITE( ... ) calls.
127 (There's no need for POST_MEM_READ calls.)
nethercote98ae6da2004-01-19 19:32:30 +0000128
fitzhardinge603e8c52004-01-19 22:02:43 +0000129 Also, add it to the sys_info[] array; use SYSBA if it requires a
130 PRE() and POST() function, and SYSB_ if it only requires a PRE()
131 function. The 2nd arg of these macros indicate if the syscall
132 could possibly block.
njn75b31b32003-06-12 11:24:10 +0000133
sewardjde4a1d02002-03-22 01:27:54 +0000134 If you find this difficult, read the wrappers for other syscalls
135 for ideas. A good tip is to look for the wrapper for a syscall
136 which has a similar behaviour to yours, and use it as a
137 starting point.
138
nethercote73b526f2004-10-31 18:48:21 +0000139 If you need structure definitions and/or constants for your syscall,
140 copy them from the kernel headers into include/vki.h and co., with
141 the appropriate vki_*/VKI_* name mangling. Don't #include any
142 kernel headers. And certainly don't #include any glibc headers.
sewardjde4a1d02002-03-22 01:27:54 +0000143
144 Test it.
145
nethercoteef0c7662004-11-06 15:38:43 +0000146 Note that a common error is to call POST_MEM_WRITE( ... )
njn75b31b32003-06-12 11:24:10 +0000147 with 0 (NULL) as the first (address) argument. This usually means
148 your logic is slightly inadequate. It's a sufficiently common bug
149 that there's a built-in check for it, and you'll get a "probably
150 sanity check failure" for the syscall wrapper you just made, if this
151 is the case.
sewardjde4a1d02002-03-22 01:27:54 +0000152
sewardjde4a1d02002-03-22 01:27:54 +0000153
nethercote98ae6da2004-01-19 19:32:30 +00001544. Once happy, send us the patch. Pretty please.
sewardjde4a1d02002-03-22 01:27:54 +0000155
156
157
158
159Writing your own ioctl wrappers
160~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
fitzhardinge603e8c52004-01-19 22:02:43 +0000161
162Is pretty much the same as writing syscall wrappers, except that all
163the action happens within PRE(ioctl) and POST(ioctl).
sewardjde4a1d02002-03-22 01:27:54 +0000164
njn75b31b32003-06-12 11:24:10 +0000165There's a default case, sometimes it isn't correct and you have to write a
166more specific case to get the right behaviour.
sewardjde4a1d02002-03-22 01:27:54 +0000167
nethercote98ae6da2004-01-19 19:32:30 +0000168As above, please create a bug report and attach the patch as described
mueller30c956a2004-01-02 23:27:29 +0000169on http://valgrind.kde.org/bugs.html
sewardjde4a1d02002-03-22 01:27:54 +0000170