blob: 603295bbd956581762142ba6070d68ef726a27f7 [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
nethercote98ae6da2004-01-19 19:32:30 +000066The first thing we do happens before the syscall occurs, in the PRE() function:
bartf4775492008-04-26 10:47:29 +000067tell the tool the return type of the syscall, that the syscall has one
68argument, the type of the argument and that the argument is being read from a
69register:
70
71 PRE_REG_READ1(long, "time", int *, t);
72
73Next, if a non-NULL buffer is passed in as the argument, tell the tool that the
nethercote98ae6da2004-01-19 19:32:30 +000074buffer is about to be written to:
sewardjde4a1d02002-03-22 01:27:54 +000075
bartf4775492008-04-26 10:47:29 +000076 if (ARG1 != 0) {
77 PRE_MEM_WRITE( "time", ARG1, sizeof(vki_time_t) );
njn75b31b32003-06-12 11:24:10 +000078 }
sewardjde4a1d02002-03-22 01:27:54 +000079
nethercote98ae6da2004-01-19 19:32:30 +000080Finally, the really important bit, after the syscall occurs, in the POST()
81function: if, and only if, the system call was successful, tell the tool that
82the memory was written:
sewardjde4a1d02002-03-22 01:27:54 +000083
bartf4775492008-04-26 10:47:29 +000084 if (ARG1 != 0) {
85 POST_MEM_WRITE( ARG1, sizeof(vki_time_t) );
njn75b31b32003-06-12 11:24:10 +000086 }
sewardjde4a1d02002-03-22 01:27:54 +000087
fitzhardinge603e8c52004-01-19 22:02:43 +000088The POST() function won't be called if the syscall failed, so you
89don't need to worry about checking that in the POST() function.
90(Note: this is sometimes a bug; some syscalls do return results when
91they "fail" - for example, nanosleep returns the amount of unslept
92time if interrupted. TODO: add another per-syscall flag for this
93case.)
sewardjde4a1d02002-03-22 01:27:54 +000094
nethercoteef0c7662004-11-06 15:38:43 +000095Note that we use the type 'vki_time_t'. This is a copy of the kernel
96type, with 'vki_' prefixed. Our copies of such types are kept in the
97appropriate vki*.h file(s). We don't include kernel headers or glibc headers
98directly.
99
sewardjde4a1d02002-03-22 01:27:54 +0000100
101Writing your own syscall wrappers (see below for ioctl wrappers)
102~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
103If Valgrind tells you that system call NNN is unimplemented, do the
104following:
105
1061. Find out the name of the system call:
107
108 grep NNN /usr/include/asm/unistd.h
109
110 This should tell you something like __NR_mysyscallname.
njn71043fe2007-03-10 00:52:54 +0000111 Copy this entry to include/vki/vki-scnums-$(VG_PLATFORM).h.
sewardjde4a1d02002-03-22 01:27:54 +0000112
nethercoteef0c7662004-11-06 15:38:43 +0000113
sewardjde4a1d02002-03-22 01:27:54 +00001142. Do 'man 2 mysyscallname' to get some idea of what the syscall
fitzhardinge603e8c52004-01-19 22:02:43 +0000115 does. Note that the actual kernel interface can differ from this,
116 so you might also want to check a version of the Linux kernel
117 source.
118
119 NOTE: any syscall which has something to do with signals or
120 threads is probably "special", and needs more careful handling.
121 Post something to valgrind-developers if you aren't sure.
sewardjde4a1d02002-03-22 01:27:54 +0000122
123
1243. Add a case to the already-huge collection of wrappers in
tom645de782005-10-05 08:27:08 +0000125 the coregrind/m_syswrap/syswrap-*.c files.
126 For each in-memory parameter which is read or written by
127 the syscall, do one of
njn75b31b32003-06-12 11:24:10 +0000128
nethercoteef0c7662004-11-06 15:38:43 +0000129 PRE_MEM_READ( ... )
130 PRE_MEM_RASCIIZ( ... )
131 PRE_MEM_WRITE( ... )
njn75b31b32003-06-12 11:24:10 +0000132
133 for that parameter. Then do the syscall. Then, if the syscall
nethercoteef0c7662004-11-06 15:38:43 +0000134 succeeds, issue suitable POST_MEM_WRITE( ... ) calls.
135 (There's no need for POST_MEM_READ calls.)
nethercote98ae6da2004-01-19 19:32:30 +0000136
tom645de782005-10-05 08:27:08 +0000137 Also, add it to the syscall_table[] array; use one of GENX_, GENXY
138 LINX_, LINXY, PLAX_, PLAXY.
139 GEN* for generic syscalls (in syswrap-generic.c), LIN* for linux
140 specific ones (in syswrap-linux.c) and PLA* for the platform
141 dependant ones (in syswrap-$(PLATFORM)-linux.c).
142 The *XY variant if it requires a PRE() and POST() function, and
143 the *X_ variant if it only requires a PRE()
bartf4775492008-04-26 10:47:29 +0000144 function.
njn75b31b32003-06-12 11:24:10 +0000145
sewardjde4a1d02002-03-22 01:27:54 +0000146 If you find this difficult, read the wrappers for other syscalls
147 for ideas. A good tip is to look for the wrapper for a syscall
148 which has a similar behaviour to yours, and use it as a
149 starting point.
150
nethercote73b526f2004-10-31 18:48:21 +0000151 If you need structure definitions and/or constants for your syscall,
152 copy them from the kernel headers into include/vki.h and co., with
153 the appropriate vki_*/VKI_* name mangling. Don't #include any
154 kernel headers. And certainly don't #include any glibc headers.
sewardjde4a1d02002-03-22 01:27:54 +0000155
156 Test it.
157
nethercoteef0c7662004-11-06 15:38:43 +0000158 Note that a common error is to call POST_MEM_WRITE( ... )
njn75b31b32003-06-12 11:24:10 +0000159 with 0 (NULL) as the first (address) argument. This usually means
160 your logic is slightly inadequate. It's a sufficiently common bug
161 that there's a built-in check for it, and you'll get a "probably
162 sanity check failure" for the syscall wrapper you just made, if this
163 is the case.
sewardjde4a1d02002-03-22 01:27:54 +0000164
sewardjde4a1d02002-03-22 01:27:54 +0000165
nethercote98ae6da2004-01-19 19:32:30 +00001664. Once happy, send us the patch. Pretty please.
sewardjde4a1d02002-03-22 01:27:54 +0000167
168
169
170
171Writing your own ioctl wrappers
172~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
fitzhardinge603e8c52004-01-19 22:02:43 +0000173
174Is pretty much the same as writing syscall wrappers, except that all
175the action happens within PRE(ioctl) and POST(ioctl).
sewardjde4a1d02002-03-22 01:27:54 +0000176
njn75b31b32003-06-12 11:24:10 +0000177There's a default case, sometimes it isn't correct and you have to write a
178more specific case to get the right behaviour.
sewardjde4a1d02002-03-22 01:27:54 +0000179
nethercote98ae6da2004-01-19 19:32:30 +0000180As above, please create a bug report and attach the patch as described
njn272b2162005-05-17 03:22:38 +0000181on http://www.valgrind.org.
sewardjde4a1d02002-03-22 01:27:54 +0000182