blob: de88a83e70ab234b4a8bdb9253465edafff2e349 [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); */
nethercote98ae6da2004-01-19 19:32:30 +000052 MAYBE_PRINTF("time ( %p )\n",arg1);
njn75b31b32003-06-12 11:24:10 +000053 if (arg1 != (UInt)NULL) {
nethercote98ae6da2004-01-19 19:32:30 +000054 SYSCALL_TRACK( pre_mem_write, tid, "time", arg1, sizeof(time_t) );
njn75b31b32003-06-12 11:24:10 +000055 }
nethercote98ae6da2004-01-19 19:32:30 +000056 }
57
58 POST(time)
59 {
60 if (arg1 != (UInt)NULL) {
njn75b31b32003-06-12 11:24:10 +000061 VG_TRACK( post_mem_write, arg1, sizeof(time_t) );
62 }
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
njn75b31b32003-06-12 11:24:10 +000069 if (arg1 != (UInt)NULL) {
70 SYSCALL_TRACK( pre_mem_write, tst, "time", arg1, sizeof(time_t) );
71 }
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) {
njn75b31b32003-06-12 11:24:10 +000078 VG_TRACK( post_mem_write, arg1, sizeof(time_t) );
79 }
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
88
89Writing your own syscall wrappers (see below for ioctl wrappers)
90~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
91If Valgrind tells you that system call NNN is unimplemented, do the
92following:
93
941. Find out the name of the system call:
95
96 grep NNN /usr/include/asm/unistd.h
97
98 This should tell you something like __NR_mysyscallname.
nethercotef94fe2f2004-09-10 14:23:59 +000099 Copy this entry to coregrind/$(VG_PLATFORM)/vki_unistd.h.
sewardjde4a1d02002-03-22 01:27:54 +0000100
1012. Do 'man 2 mysyscallname' to get some idea of what the syscall
fitzhardinge603e8c52004-01-19 22:02:43 +0000102 does. Note that the actual kernel interface can differ from this,
103 so you might also want to check a version of the Linux kernel
104 source.
105
106 NOTE: any syscall which has something to do with signals or
107 threads is probably "special", and needs more careful handling.
108 Post something to valgrind-developers if you aren't sure.
sewardjde4a1d02002-03-22 01:27:54 +0000109
110
1113. Add a case to the already-huge collection of wrappers in
njn39209d42003-06-13 15:02:29 +0000112 coregrind/vg_syscalls.c. For each in-memory parameter which is
113 read or written by the syscall, do one of
njn75b31b32003-06-12 11:24:10 +0000114
115 SYSCALL_TRACK( pre_mem_read, ... )
116 SYSCALL_TRACK( pre_mem_read_asciiz, ... )
117 SYSCALL_TRACK( pre_mem_write, ... )
118
119 for that parameter. Then do the syscall. Then, if the syscall
120 succeeds, issue suitable VG_TRACK( post_mem_write, ... ) calls.
121 (There's no need for post_mem_read calls.)
nethercote98ae6da2004-01-19 19:32:30 +0000122
fitzhardinge603e8c52004-01-19 22:02:43 +0000123 Also, add it to the sys_info[] array; use SYSBA if it requires a
124 PRE() and POST() function, and SYSB_ if it only requires a PRE()
125 function. The 2nd arg of these macros indicate if the syscall
126 could possibly block.
njn75b31b32003-06-12 11:24:10 +0000127
sewardjde4a1d02002-03-22 01:27:54 +0000128 If you find this difficult, read the wrappers for other syscalls
129 for ideas. A good tip is to look for the wrapper for a syscall
130 which has a similar behaviour to yours, and use it as a
131 starting point.
132
nethercote73b526f2004-10-31 18:48:21 +0000133 If you need structure definitions and/or constants for your syscall,
134 copy them from the kernel headers into include/vki.h and co., with
135 the appropriate vki_*/VKI_* name mangling. Don't #include any
136 kernel headers. And certainly don't #include any glibc headers.
sewardjde4a1d02002-03-22 01:27:54 +0000137
138 Test it.
139
njn75b31b32003-06-12 11:24:10 +0000140 Note that a common error is to call VG_TRACK( post_mem_write, ... )
141 with 0 (NULL) as the first (address) argument. This usually means
142 your logic is slightly inadequate. It's a sufficiently common bug
143 that there's a built-in check for it, and you'll get a "probably
144 sanity check failure" for the syscall wrapper you just made, if this
145 is the case.
sewardjde4a1d02002-03-22 01:27:54 +0000146
sewardjde4a1d02002-03-22 01:27:54 +0000147
nethercote98ae6da2004-01-19 19:32:30 +00001484. Once happy, send us the patch. Pretty please.
sewardjde4a1d02002-03-22 01:27:54 +0000149
150
151
152
153Writing your own ioctl wrappers
154~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
fitzhardinge603e8c52004-01-19 22:02:43 +0000155
156Is pretty much the same as writing syscall wrappers, except that all
157the action happens within PRE(ioctl) and POST(ioctl).
sewardjde4a1d02002-03-22 01:27:54 +0000158
njn75b31b32003-06-12 11:24:10 +0000159There's a default case, sometimes it isn't correct and you have to write a
160more specific case to get the right behaviour.
sewardjde4a1d02002-03-22 01:27:54 +0000161
nethercote98ae6da2004-01-19 19:32:30 +0000162As above, please create a bug report and attach the patch as described
mueller30c956a2004-01-02 23:27:29 +0000163on http://valgrind.kde.org/bugs.html
sewardjde4a1d02002-03-22 01:27:54 +0000164