blob: 33e56f0418123ef211b8bb36d9d08144545eaefa [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
nethercote98ae6da2004-01-19 19:32:30 +000081The POST() function won't be called if the syscall failed, so you don't need
82to worry about checking that in the POST() function.
sewardjde4a1d02002-03-22 01:27:54 +000083
84
85Writing your own syscall wrappers (see below for ioctl wrappers)
86~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
87If Valgrind tells you that system call NNN is unimplemented, do the
88following:
89
901. Find out the name of the system call:
91
92 grep NNN /usr/include/asm/unistd.h
93
94 This should tell you something like __NR_mysyscallname.
95
96
972. Do 'man 2 mysyscallname' to get some idea of what the syscall
98 does.
99
100
1013. Add a case to the already-huge collection of wrappers in
njn39209d42003-06-13 15:02:29 +0000102 coregrind/vg_syscalls.c. For each in-memory parameter which is
103 read or written by the syscall, do one of
njn75b31b32003-06-12 11:24:10 +0000104
105 SYSCALL_TRACK( pre_mem_read, ... )
106 SYSCALL_TRACK( pre_mem_read_asciiz, ... )
107 SYSCALL_TRACK( pre_mem_write, ... )
108
109 for that parameter. Then do the syscall. Then, if the syscall
110 succeeds, issue suitable VG_TRACK( post_mem_write, ... ) calls.
111 (There's no need for post_mem_read calls.)
nethercote98ae6da2004-01-19 19:32:30 +0000112
113 Also, add it to the sys_info[] array; use SYSBA if it requires a PRE()
114 and POST() function, and SYSB_ if it only requires a PRE() function.
115 The 2nd arg of these macros indicate if the syscall is blocking.
njn75b31b32003-06-12 11:24:10 +0000116
sewardjde4a1d02002-03-22 01:27:54 +0000117 If you find this difficult, read the wrappers for other syscalls
118 for ideas. A good tip is to look for the wrapper for a syscall
119 which has a similar behaviour to yours, and use it as a
120 starting point.
121
122 If you have to #include headers for structure definitions,
123 put your #includes into vg_unsafe.h.
124
125 Test it.
126
njn75b31b32003-06-12 11:24:10 +0000127 Note that a common error is to call VG_TRACK( post_mem_write, ... )
128 with 0 (NULL) as the first (address) argument. This usually means
129 your logic is slightly inadequate. It's a sufficiently common bug
130 that there's a built-in check for it, and you'll get a "probably
131 sanity check failure" for the syscall wrapper you just made, if this
132 is the case.
sewardjde4a1d02002-03-22 01:27:54 +0000133
sewardjde4a1d02002-03-22 01:27:54 +0000134
nethercote98ae6da2004-01-19 19:32:30 +00001354. Once happy, send us the patch. Pretty please.
sewardjde4a1d02002-03-22 01:27:54 +0000136
137
138
139
140Writing your own ioctl wrappers
141~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
142Is pretty much the same as writing syscall wrappers.
143
njn75b31b32003-06-12 11:24:10 +0000144There's a default case, sometimes it isn't correct and you have to write a
145more specific case to get the right behaviour.
sewardjde4a1d02002-03-22 01:27:54 +0000146
nethercote98ae6da2004-01-19 19:32:30 +0000147As above, please create a bug report and attach the patch as described
mueller30c956a2004-01-02 23:27:29 +0000148on http://valgrind.kde.org/bugs.html
sewardjde4a1d02002-03-22 01:27:54 +0000149