blob: fe362d3236e6baf8682218a1b977e14c5c5670b6 [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
tom645de782005-10-05 08:27:08 +000015All this machinery is in coregrind/m_syswrap.
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.
tom645de782005-10-05 08:27:08 +0000104 Copy this entry to coregrind/vki_unistd-$(VG_PLATFORM).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
tom645de782005-10-05 08:27:08 +0000118 the coregrind/m_syswrap/syswrap-*.c files.
119 For each in-memory parameter which is read or written by
120 the syscall, do one of
njn75b31b32003-06-12 11:24:10 +0000121
nethercoteef0c7662004-11-06 15:38:43 +0000122 PRE_MEM_READ( ... )
123 PRE_MEM_RASCIIZ( ... )
124 PRE_MEM_WRITE( ... )
njn75b31b32003-06-12 11:24:10 +0000125
126 for that parameter. Then do the syscall. Then, if the syscall
nethercoteef0c7662004-11-06 15:38:43 +0000127 succeeds, issue suitable POST_MEM_WRITE( ... ) calls.
128 (There's no need for POST_MEM_READ calls.)
nethercote98ae6da2004-01-19 19:32:30 +0000129
tom645de782005-10-05 08:27:08 +0000130 Also, add it to the syscall_table[] array; use one of GENX_, GENXY
131 LINX_, LINXY, PLAX_, PLAXY.
132 GEN* for generic syscalls (in syswrap-generic.c), LIN* for linux
133 specific ones (in syswrap-linux.c) and PLA* for the platform
134 dependant ones (in syswrap-$(PLATFORM)-linux.c).
135 The *XY variant if it requires a PRE() and POST() function, and
136 the *X_ variant if it only requires a PRE()
fitzhardinge603e8c52004-01-19 22:02:43 +0000137 function. The 2nd arg of these macros indicate if the syscall
138 could possibly block.
njn75b31b32003-06-12 11:24:10 +0000139
sewardjde4a1d02002-03-22 01:27:54 +0000140 If you find this difficult, read the wrappers for other syscalls
141 for ideas. A good tip is to look for the wrapper for a syscall
142 which has a similar behaviour to yours, and use it as a
143 starting point.
144
nethercote73b526f2004-10-31 18:48:21 +0000145 If you need structure definitions and/or constants for your syscall,
146 copy them from the kernel headers into include/vki.h and co., with
147 the appropriate vki_*/VKI_* name mangling. Don't #include any
148 kernel headers. And certainly don't #include any glibc headers.
sewardjde4a1d02002-03-22 01:27:54 +0000149
150 Test it.
151
nethercoteef0c7662004-11-06 15:38:43 +0000152 Note that a common error is to call POST_MEM_WRITE( ... )
njn75b31b32003-06-12 11:24:10 +0000153 with 0 (NULL) as the first (address) argument. This usually means
154 your logic is slightly inadequate. It's a sufficiently common bug
155 that there's a built-in check for it, and you'll get a "probably
156 sanity check failure" for the syscall wrapper you just made, if this
157 is the case.
sewardjde4a1d02002-03-22 01:27:54 +0000158
sewardjde4a1d02002-03-22 01:27:54 +0000159
nethercote98ae6da2004-01-19 19:32:30 +00001604. Once happy, send us the patch. Pretty please.
sewardjde4a1d02002-03-22 01:27:54 +0000161
162
163
164
165Writing your own ioctl wrappers
166~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
fitzhardinge603e8c52004-01-19 22:02:43 +0000167
168Is pretty much the same as writing syscall wrappers, except that all
169the action happens within PRE(ioctl) and POST(ioctl).
sewardjde4a1d02002-03-22 01:27:54 +0000170
njn75b31b32003-06-12 11:24:10 +0000171There's a default case, sometimes it isn't correct and you have to write a
172more specific case to get the right behaviour.
sewardjde4a1d02002-03-22 01:27:54 +0000173
nethercote98ae6da2004-01-19 19:32:30 +0000174As above, please create a bug report and attach the patch as described
njn272b2162005-05-17 03:22:38 +0000175on http://www.valgrind.org.
sewardjde4a1d02002-03-22 01:27:54 +0000176