Fix bad gdbserver_tests heap usage tests stderr output.
[valgrind.git] / coregrind / vgdb-invoker-solaris.c
blob019441bcfa240f12f9bbbacc8a18f0ecb08f381d
1 /*--------------------------------------------------------------------*/
2 /*--- Implementation of vgdb invoker subsystem on Solaris */
3 /* via /proc filesystem and control messages. ---*/
4 /*--------------------------------------------------------------------*/
6 /*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
10 Copyright (C) 2014-2015 Ivo Raisr <ivosh@ivosh.net>
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License as
14 published by the Free Software Foundation; either version 2 of the
15 License, or (at your option) any later version.
17 This program is distributed in the hope that it will be useful, but
18 WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
25 02111-1307, USA.
27 The GNU General Public License is contained in the file COPYING.
30 /* This module implements vgdb-invoker subsystem as per vgdb.h
31 on Solaris. It differs significantly from the other ptrace-based
32 implementation found in vgdb-invoker-ptrace.c. However the goal
33 is the same - to work on the following scenario:
35 - A valgrind process (referred to also as an inferior process)
36 is remotely debugged with gdb.
37 - All threads of the inferior process are stuck in blocking
38 syscalls.
39 - Therefore no thread can process packets received from gdb.
41 When module vgdb.c detects this situation then it calls
42 function invoker_invoke_gdbserver() within the context of
43 invoke_gdbserver_in_valgrind_thread thread. The steps of
44 interaction between vgdb and m_gdbserver module are as follows:
46 1. Function invoker_invoke_gdbserver() attaches to the inferior
47 process and stops all threads.
48 2. It gets registers of the first thread and modifies them
49 and the stack so that a call to "invoke_gdbserver" function
50 is arranged along with a function parameter.
51 3. Then it creates an agent thread within the inferior process
52 with these modified registers and waits until the agent thread
53 exits.
54 4. Meanwhile in the inferior process function
55 VG_(invoke_gdbserver)() is invoked within the context of the
56 agent thread; all other threads are still stopped.
57 5. The agent thread processes packets from gdb relayed by vgdb.
58 6. Eventually processing is finished and the agent thread exits
59 in function give_control_back_to_vgdb().
60 7. vgdb then detaches from the inferior process and thus resumes
61 all the stopped threads.
64 #include "vgdb.h"
66 #include <assert.h>
67 #include <errno.h>
68 #include <string.h>
70 typedef Addr CORE_ADDR;
72 typedef struct {
73 long cmd;
74 union {
75 long flags;
76 prgregset_t regs;
77 } arg;
78 } ctl_t;
80 /* Process control file /proc/<pid>/ctl.
81 Once this file is closed, PR_RLC flag takes effect and
82 inferior process resumes automatically. */
83 static int ctl_fd = -1;
85 /* Copy LEN bytes of data from vgdb memory at MYADDR
86 to valgrind memory at MEMADDR.
87 On failure (cannot write the valgrind memory)
88 returns the value of errno. */
89 static int write_memory(pid_t pid, CORE_ADDR memaddr,
90 const void *myaddr, size_t len)
92 char procname[PATH_MAX];
93 snprintf(procname, sizeof(procname), "/proc/%d/as", pid);
95 /* Open the process address-space file. */
96 int as_fd = open(procname, O_WRONLY, 0);
97 if (as_fd < 0) {
98 int error = errno;
99 ERROR(error, "Failed to open %s.\n", procname);
100 return error;
103 if (debuglevel >= 1) {
104 DEBUG(1, "Writing bytes '");
105 size_t i;
106 for (i = 0; i < len; i++)
107 PDEBUG(1, "%02x", ((const unsigned char *) myaddr)[i]);
108 PDEBUG(1, "' to address %#lx.\n", memaddr);
111 ssize_t written = pwrite(as_fd, myaddr, len, memaddr);
112 if ((written < 0) || (written != len)) {
113 int error = errno;
114 ERROR(error, "Failed to write to file %s, memory block of %zu"
115 " bytes at %#lx to %#lx.\n",
116 procname, len, (Addr) myaddr, memaddr);
117 close(as_fd);
118 return error;
121 DEBUG(1, "Written ok.\n");
122 close(as_fd);
123 return 0;
126 /* Attaches to a process identified by pid and stops all threads. */
127 static Bool attach(pid_t pid)
129 char procname[PATH_MAX];
130 snprintf(procname, sizeof(procname), "/proc/%d/ctl", pid);
132 DEBUG(1, "Attaching to pid %d.\n", pid);
134 /* Open the process control file. */
135 ctl_fd = open(procname, O_WRONLY, 0);
136 if (ctl_fd < 0) {
137 ERROR(errno, "Failed to open %s.\n", procname);
138 return False;
141 DEBUG(1, "Setting run-on-last-close-flag (PR_RLC) to pid %d.\n", pid);
143 /* Set run-on-last-close flag. */
144 ctl_t ctl;
145 ctl.cmd = PCSET;
146 ctl.arg.flags = PR_RLC;
147 size_t bytes = sizeof(ctl.cmd) + sizeof(ctl.arg.flags);
148 ssize_t written = write(ctl_fd, (void *) &ctl, bytes);
149 if ((written < 0) || (written != bytes)) {
150 ERROR(errno, "Failed to write to ctl_fd: PCSET + PR_RLC.\n");
151 return False;
154 DEBUG(1, "Stopping process %d.\n", pid);
156 /* Stop the whole process - all threads. */
157 ctl.cmd = PCSTOP;
158 bytes = sizeof(ctl.cmd);
159 written = write(ctl_fd, (void *) &ctl, bytes);
160 if ((written < 0) || (written != bytes)) {
161 ERROR(errno, "Failed to write to ctl_fd: PCSTOP.\n");
162 return False;
165 DEBUG(1, "Process %d stopped.\n", pid);
167 /* Now confirm it is actually the case. */
168 snprintf(procname, sizeof(procname), "/proc/%d/status", pid);
169 int status_fd = open(procname, O_RDONLY, 0);
170 if (status_fd < 0) {
171 ERROR(errno, "Failed to open %s.\n", procname);
172 return False;
175 pstatus_t pstatus;
176 bytes = read(status_fd, &pstatus, sizeof(pstatus));
177 if ((bytes < 0) || (bytes != sizeof(pstatus))) {
178 ERROR(errno, "Failed to read from %s.\n", procname);
179 close(status_fd);
180 return False;
183 if (pstatus.pr_flags & PR_RLC) {
184 DEBUG(2, "Process %d has run-on-last-close flag set. Good.\n", pid);
185 } else {
186 ERROR(0, "Process %d does not have run-on-last-close flag set!\n", pid);
187 close(status_fd);
188 return False;
191 if (pstatus.pr_lwp.pr_flags & PR_STOPPED) {
192 DEBUG(3, "Process %d seems to be stopped. Good.\n", pid);
193 } else {
194 ERROR(0, "Process %d is not stopped!\n", pid);
195 close(status_fd);
196 return False;
199 close(status_fd);
200 return True;
203 static void detach(pid_t pid)
205 if (ctl_fd != -1) {
206 close(ctl_fd);
207 ctl_fd = -1;
210 DEBUG(1, "Detached from pid %d.\n", pid);
213 /* Gets the registers of the first thread. */
214 static Bool get_regs(pid_t pid, prgregset_t *regs)
216 char procname[PATH_MAX];
217 snprintf(procname, sizeof(procname), "/proc/%d/lwp/1/lwpstatus", pid);
219 DEBUG(1, "Getting registers from the first thread of process %d.\n", pid);
221 /* Open the first thread's status file. */
222 int status_fd = open(procname, O_RDONLY, 0);
223 if (status_fd < 0) {
224 ERROR(errno, "Failed to open file %s.\n", procname);
225 return False;
228 lwpstatus_t status;
229 ssize_t bytes = read(status_fd, &status, sizeof(status));
230 if ((bytes < 0) || (bytes != sizeof(status))) {
231 ERROR(errno, "Failed to read from %s.\n", procname);
232 close(status_fd);
233 return False;
236 DEBUG(3, "Registers of thread %d from process %d: ", status.pr_lwpid, pid);
237 unsigned int i;
238 for (i = 0; i < _NGREG; i++) {
239 PDEBUG(3, "%u: %#lx, ", i, (unsigned long) status.pr_reg[i]);
241 PDEBUG(3, "\n");
243 memcpy(regs, &status.pr_reg, sizeof(prgregset_t));
244 close(status_fd);
245 return True;
248 /* Modifies the register set so that a new stack frame is created
249 for "invoke_gdbserver" function with an extra argument.
250 The argument is written to the stack of the first thread.
252 static Bool setup_stack_frame(pid_t pid, prgregset_t *regs)
254 DEBUG(1, "Setting up new stack frame of process %d.\n", pid);
256 /* A specific int value is passed to invoke_gdbserver(), to check
257 everything goes according to the plan. */
258 const int check = 0x8BADF00D; // ate bad food.
260 /* A bad return address will be pushed on the stack.
261 Function invoke_gdbserver() cannot return. If it ever returns,
262 a NULL address pushed on the stack should ensure this is
263 detected. */
264 const Addr bad_return = 0;
266 #if defined(VGA_x86)
267 Addr sp = (*regs)[UESP];
268 #elif defined(VGA_amd64)
269 Addr sp = (*regs)[REG_RSP];
270 #else
271 I_die_here : (sp) architecture missing in vgdb-invoker-solaris.c
272 #endif
274 if (shared32 != NULL) {
275 /* vgdb speaking with a 32bit executable. */
276 #if defined(VGA_x86) || defined(VGA_amd64)
277 const size_t regsize = 4;
279 /* Push check argument on the stack - according to C/ia32 ABI. */
280 sp = sp - regsize;
281 DEBUG(1, "Pushing check argument to process %d memory.\n", pid);
282 assert(regsize == sizeof(check));
283 int error = write_memory(pid, sp, &check, regsize);
284 if (error != 0) {
285 ERROR(error, "Failed to push check argument to process %d memory.\n",
286 pid);
287 detach(pid);
288 return False;
291 sp = sp - regsize;
292 DEBUG(1, "Pushing bad_return return address to process %d memory.\n",
293 pid);
294 /* Note that even for a 64 bits vgdb, only 4 bytes
295 of NULL bad_return are written. */
296 error = write_memory(pid, sp, &bad_return, regsize);
297 if (error != 0) {
298 ERROR(error, "Failed to push bad_return return address to process %d "
299 "memory.\n", pid);
300 detach(pid);
301 return False;
304 #if defined(VGA_x86)
305 /* Set EBP, ESP, EIP to invoke gdbserver.
306 vgdb is 32bits, speaking with a 32bits process. */
307 (*regs)[EBP] = sp; // bp set to sp
308 (*regs)[UESP] = sp;
309 (*regs)[EIP] = shared32->invoke_gdbserver;
310 #elif defined(VGA_amd64)
311 /* Set RBP, RSP, RIP to invoke gdbserver.
312 vgdb is 64bits, speaking with a 32bits process. */
313 (*regs)[REG_RBP] = sp; // bp set to sp
314 (*regs)[REG_RSP] = sp;
315 (*regs)[REG_RIP] = shared32->invoke_gdbserver;
316 #else
317 I_die_here : not x86 or amd64 in x86/amd64 section/
318 #endif
320 #else
321 I_die_here : architecture missing in vgdb-invoker-solaris.c
322 #endif
324 } else if (shared64 != NULL) {
325 #if defined(VGA_x86)
326 assert(0); /* 64bits process with a 32bits vgdb - no way */
327 #elif defined(VGA_amd64)
328 /* 64bits vgdb speaking with a 64 bit process. */
329 const int regsize = 8;
331 /* Give check argument in rdi - according to C/amd64 ABI. */
332 (*regs)[REG_RDI] = check;
334 /* Push return address on stack: return to breakaddr. */
335 sp = sp - regsize;
336 DEBUG(1, "Pushing bad_return return address to process %d memory.\n",
337 pid);
338 int error = write_memory(pid, sp, &bad_return,
339 sizeof(bad_return));
340 if (error != 0) {
341 ERROR(error, "Failed to push bad_return return address to process %d "
342 "memory.\n", pid);
343 detach(pid);
344 return False;
347 /* set RBP, RSP, RIP to invoke gdbserver */
348 (*regs)[REG_RBP] = sp; // bp set to sp
349 (*regs)[REG_RSP] = sp;
350 (*regs)[REG_RIP] = shared64->invoke_gdbserver;
351 #else
352 I_die_here: architecture missing in vgdb-invoker-solaris.c
353 #endif
354 } else {
355 assert(0);
358 DEBUG(1, "New stack frame set up for process %d.\n", pid);
359 return True;
362 /* Creates and starts an agent thread within the inferior process.
363 The agent thread is created stopped and with its held signal set
364 (the signal mask) having all signals except SIGKILL and SIGSTOP
365 blocked. All these signals need to remain blocked while the agent
366 thread is running because valgrind syscall/signal machinery expects
367 that (remember: all valgrind threads are blocked in VgTs_WaitSys
368 - that is the reason why we are invoking the agent, after all).
369 It is necessary to resume the agent thread afterwards.
371 static Bool invoke_agent(pid_t pid, prgregset_t *regs, id_t *agent_lwpid)
373 assert(ctl_fd != -1);
375 DEBUG(1, "Creating an agent thread within process %d.\n", pid);
377 /* Create the agent thread. */
378 ctl_t ctl;
379 ctl.cmd = PCAGENT;
380 memcpy(&ctl.arg.regs, regs, sizeof(prgregset_t));
381 size_t bytes = sizeof(ctl.cmd) + sizeof(ctl.arg.regs);
382 ssize_t written = write(ctl_fd, (void *) &ctl, bytes);
383 if ((written < 0) || (written != bytes)) {
384 ERROR(errno, "Failed to write to ctl_fd: PCAGENT.\n");
385 return False;
388 DEBUG(1, "Obtaining agent thread lwpid for process %d.\n", pid);
390 char procname[PATH_MAX];
391 snprintf(procname, sizeof(procname),
392 "/proc/%d/lwp/agent/lwpstatus", pid);
394 int status_fd = open(procname, O_RDONLY, 0);
395 if (status_fd < 0) {
396 /* Operation failed but there is no way to get rid of the agent
397 thread from outside. We are doomed... */
398 ERROR(errno, "Failed to open file %s.\n", procname);
399 return False;
402 lwpstatus_t status;
403 bytes = read(status_fd, &status, sizeof(status));
404 if ((bytes < 0) || (bytes != sizeof(status))) {
405 ERROR(errno, "Failed to read from %s.\n", procname);
406 close(status_fd);
407 return False;
410 close(status_fd);
411 *agent_lwpid = status.pr_lwpid;
413 snprintf(procname, sizeof(procname),
414 "/proc/%d/lwp/agent/lwpctl", pid);
416 int agent_ctl_fd = open(procname, O_WRONLY, 0);
417 if (agent_ctl_fd < 0) {
418 /* Resuming failed but there is no way to get rid of the agent
419 thread from outside. We are doomed... */
420 ERROR(errno, "Failed to open file %s.\n", procname);
421 return False;
424 DEBUG(1, "Resuming the agent thread for process %d.\n", pid);
426 /* Resume the agent thread. */
427 ctl.cmd = PCRUN;
428 ctl.arg.flags = 0;
429 bytes = sizeof(ctl.cmd) + sizeof(ctl.arg.flags);
430 written = write(agent_ctl_fd, (void *) &ctl, bytes);
431 if ((written < 0) || (written != bytes)) {
432 /* Resuming failed but there is no way to get rid of the agent
433 thread from outside. We are doomed... */
434 ERROR(errno, "Failed to write to agent_ctl_fd: PCRUN 0.\n");
435 close(agent_ctl_fd);
436 return False;
439 DEBUG(1, "Agent thread lwpid %d now running within process %d.\n",
440 *agent_lwpid, pid);
441 close(agent_ctl_fd);
442 return True;
445 /* Waits until the agent thread running inside the inferior
446 process exits. */
447 static Bool wait_for_agent_exit(pid_t pid, id_t agent_lwpid)
449 char procname[PATH_MAX];
450 snprintf(procname, sizeof(procname), "/proc/%d/lwp/agent/lwpctl", pid);
452 int agent_ctl_fd = open(procname, O_WRONLY, 0);
453 if (agent_ctl_fd < 0) {
454 if (errno == ENOENT) {
455 DEBUG(1, "Agent control file %s no longer exists. This means "
456 "agent thread %d exited meanwhile.\n",
457 procname, agent_lwpid);
458 return True;
460 ERROR(errno, "Failed to open agent control file %s.\n", procname);
461 return False;
464 DEBUG(1, "Waiting for agent thread %d to exit.\n", agent_lwpid);
466 /* Wait until the agent thread stops. This covers also the case
467 when the thread exited. */
468 ctl_t ctl;
469 ctl.cmd = PCWSTOP;
470 size_t bytes = sizeof(ctl.cmd);
471 ssize_t written = write(agent_ctl_fd, (void *) &ctl, bytes);
472 if ((written < 0) || (written != bytes)) {
473 if (errno == ENOENT) {
474 DEBUG(1, "Agent thread lwpid %d has now exited in process %d.\n",
475 agent_lwpid, pid);
476 } else {
477 ERROR(errno, "Failed to write to agent_ctl_fd: PCWSTOP.\n");
478 close(agent_ctl_fd);
479 return False;
483 close(agent_ctl_fd);
484 return True;
487 Bool invoker_invoke_gdbserver(pid_t pid)
489 if (attach(pid) != True) {
490 return False;
493 prgregset_t regs;
494 if (get_regs(pid, &regs) != True) {
495 detach(pid);
496 return False;
499 if (setup_stack_frame(pid, &regs) != True) {
500 detach(pid);
501 return False;
504 id_t agent_lwpid;
505 if (invoke_agent(pid, &regs, &agent_lwpid) != True) {
506 detach(pid);
507 return False;
510 if (wait_for_agent_exit(pid, agent_lwpid) != True) {
511 detach(pid);
512 return False;
515 detach(pid);
516 return True;
519 void invoker_cleanup_restore_and_detach(void *v_pid)
521 detach(*(int *) v_pid);
524 void invoker_restrictions_msg(void)
528 void invoker_valgrind_dying(void)