blob: 24af45bf4254ccb8302c96ca3cd2fde9fc104025 [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~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bartf4775492008-04-26 10:47:29 +000047The wrapper for the time system call looks like this:
sewardjde4a1d02002-03-22 01:27:54 +000048
bartf4775492008-04-26 10:47:29 +000049 PRE(sys_time)
nethercote98ae6da2004-01-19 19:32:30 +000050 {
njn75b31b32003-06-12 11:24:10 +000051 /* time_t time(time_t *t); */
bartf4775492008-04-26 10:47:29 +000052 PRINT("sys_time ( %p )",ARG1);
53 PRE_REG_READ1(long, "time", int *, t);
54 if (ARG1 != 0) {
55 PRE_MEM_WRITE( "time(t)", ARG1, sizeof(vki_time_t) );
njn75b31b32003-06-12 11:24:10 +000056 }
nethercote98ae6da2004-01-19 19:32:30 +000057 }
58
bartf4775492008-04-26 10:47:29 +000059 POST(sys_time)
nethercote98ae6da2004-01-19 19:32:30 +000060 {
bartf4775492008-04-26 10:47:29 +000061 if (ARG1 != 0) {
62 POST_MEM_WRITE( ARG1, sizeof(vki_time_t) );
njn75b31b32003-06-12 11:24:10 +000063 }
nethercote98ae6da2004-01-19 19:32:30 +000064 }
sewardjde4a1d02002-03-22 01:27:54 +000065
bart3af9e992008-05-01 12:23:48 +000066The first thing we do happens before the syscall occurs, in the PRE() function.
67The PRE() function typically starts with invoking to the PRINT() macro. This
68PRINT() macro implements support for the --trace-syscalls command line option.
69Next, the tool is told the return type of the syscall, that the syscall has
70one argument, the type of the syscall argument and that the argument is being
71read from a register:
bartf4775492008-04-26 10:47:29 +000072
73 PRE_REG_READ1(long, "time", int *, t);
74
75Next, if a non-NULL buffer is passed in as the argument, tell the tool that the
nethercote98ae6da2004-01-19 19:32:30 +000076buffer is about to be written to:
sewardjde4a1d02002-03-22 01:27:54 +000077
bartf4775492008-04-26 10:47:29 +000078 if (ARG1 != 0) {
79 PRE_MEM_WRITE( "time", ARG1, sizeof(vki_time_t) );
njn75b31b32003-06-12 11:24:10 +000080 }
sewardjde4a1d02002-03-22 01:27:54 +000081
nethercote98ae6da2004-01-19 19:32:30 +000082Finally, the really important bit, after the syscall occurs, in the POST()
83function: if, and only if, the system call was successful, tell the tool that
84the memory was written:
sewardjde4a1d02002-03-22 01:27:54 +000085
bartf4775492008-04-26 10:47:29 +000086 if (ARG1 != 0) {
87 POST_MEM_WRITE( ARG1, sizeof(vki_time_t) );
njn75b31b32003-06-12 11:24:10 +000088 }
sewardjde4a1d02002-03-22 01:27:54 +000089
fitzhardinge603e8c52004-01-19 22:02:43 +000090The POST() function won't be called if the syscall failed, so you
91don't need to worry about checking that in the POST() function.
92(Note: this is sometimes a bug; some syscalls do return results when
93they "fail" - for example, nanosleep returns the amount of unslept
94time if interrupted. TODO: add another per-syscall flag for this
95case.)
sewardjde4a1d02002-03-22 01:27:54 +000096
nethercoteef0c7662004-11-06 15:38:43 +000097Note that we use the type 'vki_time_t'. This is a copy of the kernel
98type, with 'vki_' prefixed. Our copies of such types are kept in the
99appropriate vki*.h file(s). We don't include kernel headers or glibc headers
100directly.
101
sewardjde4a1d02002-03-22 01:27:54 +0000102
103Writing your own syscall wrappers (see below for ioctl wrappers)
104~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
105If Valgrind tells you that system call NNN is unimplemented, do the
106following:
107
1081. Find out the name of the system call:
109
tomaaaf3ae2010-03-31 07:34:30 +0000110 grep NNN /usr/include/asm/unistd*.h
sewardjde4a1d02002-03-22 01:27:54 +0000111
112 This should tell you something like __NR_mysyscallname.
njn71043fe2007-03-10 00:52:54 +0000113 Copy this entry to include/vki/vki-scnums-$(VG_PLATFORM).h.
sewardjde4a1d02002-03-22 01:27:54 +0000114
nethercoteef0c7662004-11-06 15:38:43 +0000115
sewardjde4a1d02002-03-22 01:27:54 +00001162. Do 'man 2 mysyscallname' to get some idea of what the syscall
fitzhardinge603e8c52004-01-19 22:02:43 +0000117 does. Note that the actual kernel interface can differ from this,
118 so you might also want to check a version of the Linux kernel
119 source.
120
121 NOTE: any syscall which has something to do with signals or
122 threads is probably "special", and needs more careful handling.
123 Post something to valgrind-developers if you aren't sure.
sewardjde4a1d02002-03-22 01:27:54 +0000124
125
1263. Add a case to the already-huge collection of wrappers in
tom645de782005-10-05 08:27:08 +0000127 the coregrind/m_syswrap/syswrap-*.c files.
128 For each in-memory parameter which is read or written by
129 the syscall, do one of
njn75b31b32003-06-12 11:24:10 +0000130
nethercoteef0c7662004-11-06 15:38:43 +0000131 PRE_MEM_READ( ... )
132 PRE_MEM_RASCIIZ( ... )
133 PRE_MEM_WRITE( ... )
njn75b31b32003-06-12 11:24:10 +0000134
135 for that parameter. Then do the syscall. Then, if the syscall
nethercoteef0c7662004-11-06 15:38:43 +0000136 succeeds, issue suitable POST_MEM_WRITE( ... ) calls.
137 (There's no need for POST_MEM_READ calls.)
nethercote98ae6da2004-01-19 19:32:30 +0000138
tom645de782005-10-05 08:27:08 +0000139 Also, add it to the syscall_table[] array; use one of GENX_, GENXY
140 LINX_, LINXY, PLAX_, PLAXY.
141 GEN* for generic syscalls (in syswrap-generic.c), LIN* for linux
142 specific ones (in syswrap-linux.c) and PLA* for the platform
Elliott Hughesed398002017-06-21 14:41:24 -0700143 dependent ones (in syswrap-$(PLATFORM)-linux.c).
tom645de782005-10-05 08:27:08 +0000144 The *XY variant if it requires a PRE() and POST() function, and
145 the *X_ variant if it only requires a PRE()
bartf4775492008-04-26 10:47:29 +0000146 function.
njn75b31b32003-06-12 11:24:10 +0000147
sewardjde4a1d02002-03-22 01:27:54 +0000148 If you find this difficult, read the wrappers for other syscalls
149 for ideas. A good tip is to look for the wrapper for a syscall
150 which has a similar behaviour to yours, and use it as a
151 starting point.
152
nethercote73b526f2004-10-31 18:48:21 +0000153 If you need structure definitions and/or constants for your syscall,
154 copy them from the kernel headers into include/vki.h and co., with
155 the appropriate vki_*/VKI_* name mangling. Don't #include any
156 kernel headers. And certainly don't #include any glibc headers.
sewardjde4a1d02002-03-22 01:27:54 +0000157
158 Test it.
159
nethercoteef0c7662004-11-06 15:38:43 +0000160 Note that a common error is to call POST_MEM_WRITE( ... )
njn75b31b32003-06-12 11:24:10 +0000161 with 0 (NULL) as the first (address) argument. This usually means
162 your logic is slightly inadequate. It's a sufficiently common bug
163 that there's a built-in check for it, and you'll get a "probably
164 sanity check failure" for the syscall wrapper you just made, if this
165 is the case.
sewardjde4a1d02002-03-22 01:27:54 +0000166
sewardjde4a1d02002-03-22 01:27:54 +0000167
nethercote98ae6da2004-01-19 19:32:30 +00001684. Once happy, send us the patch. Pretty please.
sewardjde4a1d02002-03-22 01:27:54 +0000169
170
171
172
173Writing your own ioctl wrappers
174~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
fitzhardinge603e8c52004-01-19 22:02:43 +0000175
176Is pretty much the same as writing syscall wrappers, except that all
177the action happens within PRE(ioctl) and POST(ioctl).
sewardjde4a1d02002-03-22 01:27:54 +0000178
njn75b31b32003-06-12 11:24:10 +0000179There's a default case, sometimes it isn't correct and you have to write a
180more specific case to get the right behaviour.
sewardjde4a1d02002-03-22 01:27:54 +0000181
nethercote98ae6da2004-01-19 19:32:30 +0000182As above, please create a bug report and attach the patch as described
njn272b2162005-05-17 03:22:38 +0000183on http://www.valgrind.org.
sewardjde4a1d02002-03-22 01:27:54 +0000184
sewardj8eb8bab2015-07-21 14:44:28 +0000185
186Writing your own door call wrappers (Solaris only)
187~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
188
189Unlike syscalls or ioctls, door calls transfer data between two userspace
190programs, albeit through a kernel interface. Programs may use completely
191proprietary semantics in the data buffers passed between them.
192Therefore it may not be possible to capture these semantics within
193a Valgrind door call or door return wrapper.
194
195Nevertheless, for system or well-known door services it would be beneficial
196to have a door call and a door return wrapper. Writing such wrapper is pretty
197much the same as writing ioctl wrappers. Please take a few moments to study
198the following picture depicting how a door client and a door server interact
199through the kernel interface in a typical scenario:
200
201
202door client thread kernel door server thread
203invokes door_call() invokes door_return()
204-------------------------------------------------------------------
205 <---- PRE(sys_door, DOOR_RETURN)
206PRE(sys_door, DOOR_CALL) --->
207 ----> POST(sys_door, DOOR_RETURN)
208 ----> server_procedure()
209 <----
210 <---- PRE(sys_door, DOOR_RETURN)
211POST(sys_door, DOOR_CALL) <---
212
213The first PRE(sys_door, DOOR_RETURN) is invoked with data_ptr=NULL
214and data_size=0. That's because it has not received any data from
215a door call, yet.
216
217Semantics are described by the following functions
218in coregring/m_syswrap/syswrap-solaris.c module:
219o For a door call wrapper the following attributes of 'params' argument:
220 - data_ptr (and associated data_size) as input buffer (request);
221 described in door_call_pre_mem_params_data()
222 - rbuf (and associated rsize) as output buffer (response);
223 described in door_call_post_mem_params_rbuf()
224o For a door return wrapper the following parameters:
225 - data_ptr (and associated data_size) as input buffer (request);
226 described in door_return_post_mem_data()
227 - data_ptr (and associated data_size) as output buffer (response);
228 described in door_return_pre_mem_data()
229
230There's a default case which may not be correct and you have to write a
231more specific case to get the right behaviour. Unless Valgrind's option
232'--sim-hints=lax-doors' is specified, the default case also spits a warning.
233
234As above, please create a bug report and attach the patch as described
235on http://www.valgrind.org.