regtest: add a fdleak filter for write on write on linux arm64
[valgrind.git] / README_MISSING_SYSCALL_OR_IOCTL
blob8ddced5c992d5feb7051396ac46534942cb9a60b
2 Dealing with missing system call or ioctl wrappers in Valgrind
3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 You're probably reading this because Valgrind bombed out whilst
5 running your program, and advised you to read this file.  The good
6 news is that, in general, it's easy to write the missing syscall or
7 ioctl wrappers you need, so that you can continue your debugging.  If
8 you send the resulting patches to me, then you'll be doing a favour to
9 all future Valgrind users too.
11 Note that an "ioctl" is just a special kind of system call, really; so
12 there's not a lot of need to distinguish them (at least conceptually)
13 in the discussion that follows.
15 All this machinery is in coregrind/m_syswrap.
18 What are syscall/ioctl wrappers?  What do they do?
19 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20 Valgrind does what it does, in part, by keeping track of everything your
21 program does.  When a system call happens, for example a request to read
22 part of a file, control passes to the Linux kernel, which fulfils the
23 request, and returns control to your program.  The problem is that the
24 kernel will often change the status of some part of your program's memory
25 as a result, and tools (instrumentation plug-ins) may need to know about
26 this.
28 Syscall and ioctl wrappers have two jobs: 
30 1. 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
32    is actually writable.  This part is useful, but not strictly
33    essential.
35 2. Tell a tool 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.
39 The "happenings" mostly involve reading/writing of memory.
41 So, let's look at an example of a wrapper for a system call which
42 should be familiar to many Unix programmers.
45 The syscall wrapper for time()
46 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
47 The wrapper for the time system call looks like this:
49   PRE(sys_time)
50   {
51      /* time_t time(time_t *t); */
52      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) );
56      }
57   }
59   POST(sys_time)
60   {  
61      if (ARG1 != 0) {
62         POST_MEM_WRITE( ARG1, sizeof(vki_time_t) );
63      }
64   }
66 The first thing we do happens before the syscall occurs, in the PRE() function.
67 The PRE() function typically starts with invoking to the PRINT() macro. This
68 PRINT() macro implements support for the --trace-syscalls command line option.
69 Next, the tool is told the return type of the syscall, that the syscall has
70 one argument, the type of the syscall argument and that the argument is being
71 read from a register:
73      PRE_REG_READ1(long, "time", int *, t);
75 Next, if a non-NULL buffer is passed in as the argument, tell the tool that the
76 buffer is about to be written to:
78      if (ARG1 != 0) {
79         PRE_MEM_WRITE( "time", ARG1, sizeof(vki_time_t) );
80      }
82 Finally, the really important bit, after the syscall occurs, in the POST()
83 function:  if, and only if, the system call was successful, tell the tool that
84 the memory was written:
86      if (ARG1 != 0) {
87         POST_MEM_WRITE( ARG1, sizeof(vki_time_t) );
88      }
90 The POST() function won't be called if the syscall failed, so you
91 don't need to worry about checking that in the POST() function.
92 (Note: this is sometimes a bug; some syscalls do return results when
93 they "fail" - for example, nanosleep returns the amount of unslept
94 time if interrupted. TODO: add another per-syscall flag for this
95 case.)
97 Note that we use the type 'vki_time_t'.  This is a copy of the kernel
98 type, with 'vki_' prefixed.  Our copies of such types are kept in the
99 appropriate vki*.h file(s).  We don't include kernel headers or glibc headers
100 directly.
103 Writing your own syscall wrappers (see below for ioctl wrappers)
104 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
105 If Valgrind tells you that system call NNN is unimplemented, do the 
106 following:
108 1.  Find out the name of the system call:
110        grep NNN /usr/include/asm/unistd*.h
112     This should tell you something like  __NR_mysyscallname.
113     Copy this entry to include/vki/vki-scnums-$(VG_PLATFORM).h.
115     If you can't find the system call in /usr/include, try looking in the
116     strace source code (https://github.com/strace/strace). Some syscalls/ioctls
117     are not defined explicitly, but strace may have already figured it out.
120 2.  Do 'man 2 mysyscallname' to get some idea of what the syscall
121     does.  Note that the actual kernel interface can differ from this,
122     so you might also want to check a version of the Linux kernel
123     source.
125     NOTE: any syscall which has something to do with signals or
126     threads is probably "special", and needs more careful handling.
127     Post something to valgrind-developers if you aren't sure.
130 3.  Add a case to the already-huge collection of wrappers in 
131     the coregrind/m_syswrap/syswrap-*.c files. 
132     For each in-memory parameter which is read or written by
133     the syscall, do one of
134     
135       PRE_MEM_READ( ... )
136       PRE_MEM_RASCIIZ( ... ) 
137       PRE_MEM_WRITE( ... ) 
138       
139     for  that parameter.  Then do the syscall.  Then, if the syscall
140     succeeds, issue suitable POST_MEM_WRITE( ... ) calls.
141     (There's no need for POST_MEM_READ calls.)
143     Also, add it to the syscall_table[] array; use one of GENX_, GENXY
144     LINX_, LINXY, PLAX_, PLAXY.
145     GEN* for generic syscalls (in syswrap-generic.c), LIN* for linux
146     specific ones (in syswrap-linux.c) and PLA* for the platform
147     dependent ones (in syswrap-$(PLATFORM)-linux.c).
148     The *XY variant if it requires a PRE() and POST() function, and
149     the *X_ variant if it only requires a PRE()
150     function.  
151     
152     If you find this difficult, read the wrappers for other syscalls
153     for ideas.  A good tip is to look for the wrapper for a syscall
154     which has a similar behaviour to yours, and use it as a 
155     starting point.
157     If you need structure definitions and/or constants for your syscall,
158     copy them from the kernel headers into include/vki.h and co., with
159     the appropriate vki_*/VKI_* name mangling.  Don't #include any
160     kernel headers.  And certainly don't #include any glibc headers.
162     Test it.
164     Note that a common error is to call POST_MEM_WRITE( ... )
165     with 0 (NULL) as the first (address) argument.  This usually means
166     your logic is slightly inadequate.  It's a sufficiently common bug
167     that there's a built-in check for it, and you'll get a "probably
168     sanity check failure" for the syscall wrapper you just made, if this
169     is the case.
172 4.  Once happy, send us the patch.  Pretty please.
177 Writing your own ioctl wrappers
178 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
180 Is pretty much the same as writing syscall wrappers, except that all
181 the action happens within PRE(ioctl) and POST(ioctl).
183 There's a default case, sometimes it isn't correct and you have to write a
184 more specific case to get the right behaviour.
186 As above, please create a bug report and attach the patch as described
187 on http://www.valgrind.org.
190 Writing your own door call wrappers (Solaris only)
191 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
193 Unlike syscalls or ioctls, door calls transfer data between two userspace
194 programs, albeit through a kernel interface. Programs may use completely
195 proprietary semantics in the data buffers passed between them.
196 Therefore it may not be possible to capture these semantics within
197 a Valgrind door call or door return wrapper.
199 Nevertheless, for system or well-known door services it would be beneficial
200 to have a door call and a door return wrapper. Writing such wrapper is pretty
201 much the same as writing ioctl wrappers. Please take a few moments to study
202 the following picture depicting how a door client and a door server interact
203 through the kernel interface in a typical scenario:
206 door client thread          kernel       door server thread
207 invokes door_call()                     invokes door_return()
208 -------------------------------------------------------------------
209                                <----  PRE(sys_door, DOOR_RETURN)
210 PRE(sys_door, DOOR_CALL)  --->
211                                ---->  POST(sys_door, DOOR_RETURN)
212                                            ----> server_procedure()
213                                            <----
214                                <----  PRE(sys_door, DOOR_RETURN)
215 POST(sys_door, DOOR_CALL) <---
217 The first PRE(sys_door, DOOR_RETURN) is invoked with data_ptr=NULL
218 and data_size=0. That's because it has not received any data from
219 a door call, yet.
221 Semantics are described by the following functions
222 in coregring/m_syswrap/syswrap-solaris.c module:
223 o For a door call wrapper the following attributes of 'params' argument:
224   - data_ptr (and associated data_size) as input buffer (request);
225       described in door_call_pre_mem_params_data()
226   - rbuf (and associated rsize) as output buffer (response);
227       described in door_call_post_mem_params_rbuf()
228 o For a door return wrapper the following parameters:
229   - data_ptr (and associated data_size) as input buffer (request);
230       described in door_return_post_mem_data()
231   - data_ptr (and associated data_size) as output buffer (response);
232       described in door_return_pre_mem_data()
234 There's a default case which may not be correct and you have to write a
235 more specific case to get the right behaviour. Unless Valgrind's option
236 '--sim-hints=lax-doors' is specified, the default case also spits a warning.
238 As above, please create a bug report and attach the patch as described
239 on http://www.valgrind.org.