1 /*--------------------------------------------------------------------*/
2 /*--- Implementation of vgdb invoker subsystem on Solaris */
3 /* via /proc filesystem and control messages. ---*/
4 /*--------------------------------------------------------------------*/
7 This file is part of Valgrind, a dynamic binary instrumentation
10 Copyright (C) 2014-2017 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, see <http://www.gnu.org/licenses/>.
25 The GNU General Public License is contained in the file COPYING.
28 /* This module implements vgdb-invoker subsystem as per vgdb.h
29 on Solaris. It differs significantly from the other ptrace-based
30 implementation found in vgdb-invoker-ptrace.c. However the goal
31 is the same - to work on the following scenario:
33 - A valgrind process (referred to also as an inferior process)
34 is remotely debugged with gdb.
35 - All threads of the inferior process are stuck in blocking
37 - Therefore no thread can process packets received from gdb.
39 When module vgdb.c detects this situation then it calls
40 function invoker_invoke_gdbserver() within the context of
41 invoke_gdbserver_in_valgrind_thread thread. The steps of
42 interaction between vgdb and m_gdbserver module are as follows:
44 1. Function invoker_invoke_gdbserver() attaches to the inferior
45 process and stops all threads.
46 2. It gets registers of the first thread and modifies them
47 and the stack so that a call to "invoke_gdbserver" function
48 is arranged along with a function parameter.
49 3. Then it creates an agent thread within the inferior process
50 with these modified registers and waits until the agent thread
52 4. Meanwhile in the inferior process function
53 VG_(invoke_gdbserver)() is invoked within the context of the
54 agent thread; all other threads are still stopped.
55 5. The agent thread processes packets from gdb relayed by vgdb.
56 6. Eventually processing is finished and the agent thread exits
57 in function give_control_back_to_vgdb().
58 7. vgdb then detaches from the inferior process and thus resumes
59 all the stopped threads.
68 typedef Addr CORE_ADDR
;
78 /* Process control file /proc/<pid>/ctl.
79 Once this file is closed, PR_RLC flag takes effect and
80 inferior process resumes automatically. */
81 static int ctl_fd
= -1;
83 /* Copy LEN bytes of data from vgdb memory at MYADDR
84 to valgrind memory at MEMADDR.
85 On failure (cannot write the valgrind memory)
86 returns the value of errno. */
87 static int write_memory(pid_t pid
, CORE_ADDR memaddr
,
88 const void *myaddr
, size_t len
)
90 char procname
[PATH_MAX
];
91 snprintf(procname
, sizeof(procname
), "/proc/%d/as", pid
);
93 /* Open the process address-space file. */
94 int as_fd
= open(procname
, O_WRONLY
, 0);
97 ERROR(error
, "Failed to open %s.\n", procname
);
101 if (debuglevel
>= 1) {
102 DEBUG(1, "Writing bytes '");
104 for (i
= 0; i
< len
; i
++)
105 PDEBUG(1, "%02x", ((const unsigned char *) myaddr
)[i
]);
106 PDEBUG(1, "' to address %#lx.\n", memaddr
);
109 ssize_t written
= pwrite(as_fd
, myaddr
, len
, memaddr
);
110 if ((written
< 0) || (written
!= len
)) {
112 ERROR(error
, "Failed to write to file %s, memory block of %zu"
113 " bytes at %#lx to %#lx.\n",
114 procname
, len
, (Addr
) myaddr
, memaddr
);
119 DEBUG(1, "Written ok.\n");
124 /* Attaches to a process identified by pid and stops all threads. */
125 static Bool
attach(pid_t pid
)
127 char procname
[PATH_MAX
];
128 snprintf(procname
, sizeof(procname
), "/proc/%d/ctl", pid
);
130 DEBUG(1, "Attaching to pid %d.\n", pid
);
132 /* Open the process control file. */
133 ctl_fd
= open(procname
, O_WRONLY
, 0);
135 ERROR(errno
, "Failed to open %s.\n", procname
);
139 DEBUG(1, "Setting run-on-last-close-flag (PR_RLC) to pid %d.\n", pid
);
141 /* Set run-on-last-close flag. */
144 ctl
.arg
.flags
= PR_RLC
;
145 size_t bytes
= sizeof(ctl
.cmd
) + sizeof(ctl
.arg
.flags
);
146 ssize_t written
= write(ctl_fd
, (void *) &ctl
, bytes
);
147 if ((written
< 0) || (written
!= bytes
)) {
148 ERROR(errno
, "Failed to write to ctl_fd: PCSET + PR_RLC.\n");
152 DEBUG(1, "Stopping process %d.\n", pid
);
154 /* Stop the whole process - all threads. */
156 bytes
= sizeof(ctl
.cmd
);
157 written
= write(ctl_fd
, (void *) &ctl
, bytes
);
158 if ((written
< 0) || (written
!= bytes
)) {
159 ERROR(errno
, "Failed to write to ctl_fd: PCSTOP.\n");
163 DEBUG(1, "Process %d stopped.\n", pid
);
165 /* Now confirm it is actually the case. */
166 snprintf(procname
, sizeof(procname
), "/proc/%d/status", pid
);
167 int status_fd
= open(procname
, O_RDONLY
, 0);
169 ERROR(errno
, "Failed to open %s.\n", procname
);
174 ssize_t nread
= read(status_fd
, &pstatus
, sizeof(pstatus
));
175 if ((nread
< 0) || (nread
!= sizeof(pstatus
))) {
176 ERROR(errno
, "Failed to read from %s.\n", procname
);
181 if (pstatus
.pr_flags
& PR_RLC
) {
182 DEBUG(2, "Process %d has run-on-last-close flag set. Good.\n", pid
);
184 ERROR(0, "Process %d does not have run-on-last-close flag set!\n", pid
);
189 if (pstatus
.pr_lwp
.pr_flags
& PR_STOPPED
) {
190 DEBUG(3, "Process %d seems to be stopped. Good.\n", pid
);
192 ERROR(0, "Process %d is not stopped!\n", pid
);
201 static void detach(pid_t pid
)
208 DEBUG(1, "Detached from pid %d.\n", pid
);
211 /* Gets the registers of the first thread. */
212 static Bool
get_regs(pid_t pid
, prgregset_t
*regs
)
214 char procname
[PATH_MAX
];
215 snprintf(procname
, sizeof(procname
), "/proc/%d/lwp/1/lwpstatus", pid
);
217 DEBUG(1, "Getting registers from the first thread of process %d.\n", pid
);
219 /* Open the first thread's status file. */
220 int status_fd
= open(procname
, O_RDONLY
, 0);
222 ERROR(errno
, "Failed to open file %s.\n", procname
);
227 ssize_t bytes
= read(status_fd
, &status
, sizeof(status
));
228 if ((bytes
< 0) || (bytes
!= sizeof(status
))) {
229 ERROR(errno
, "Failed to read from %s.\n", procname
);
234 DEBUG(3, "Registers of thread %d from process %d: ", status
.pr_lwpid
, pid
);
236 for (i
= 0; i
< _NGREG
; i
++) {
237 PDEBUG(3, "%u: %#lx, ", i
, (unsigned long) status
.pr_reg
[i
]);
241 memcpy(regs
, &status
.pr_reg
, sizeof(prgregset_t
));
246 /* Modifies the register set so that a new stack frame is created
247 for "invoke_gdbserver" function with an extra argument.
248 The argument is written to the stack of the first thread.
250 static Bool
setup_stack_frame(pid_t pid
, prgregset_t
*regs
)
252 DEBUG(1, "Setting up new stack frame of process %d.\n", pid
);
254 /* A specific int value is passed to invoke_gdbserver(), to check
255 everything goes according to the plan. */
256 const int check
= 0x8BADF00D; // ate bad food.
258 /* A bad return address will be pushed on the stack.
259 Function invoke_gdbserver() cannot return. If it ever returns,
260 a NULL address pushed on the stack should ensure this is
262 const Addr bad_return
= 0;
265 Addr sp
= (*regs
)[UESP
];
266 #elif defined(VGA_amd64)
267 Addr sp
= (*regs
)[REG_RSP
];
269 I_die_here
: (sp
) architecture missing in vgdb
-invoker
-solaris
.c
272 if (shared32
!= NULL
) {
273 /* vgdb speaking with a 32bit executable. */
274 #if defined(VGA_x86) || defined(VGA_amd64)
275 const size_t regsize
= 4;
277 /* Push check argument on the stack - according to C/ia32 ABI. */
279 DEBUG(1, "Pushing check argument to process %d memory.\n", pid
);
280 assert(regsize
== sizeof(check
));
281 int error
= write_memory(pid
, sp
, &check
, regsize
);
283 ERROR(error
, "Failed to push check argument to process %d memory.\n",
290 DEBUG(1, "Pushing bad_return return address to process %d memory.\n",
292 /* Note that even for a 64 bits vgdb, only 4 bytes
293 of NULL bad_return are written. */
294 error
= write_memory(pid
, sp
, &bad_return
, regsize
);
296 ERROR(error
, "Failed to push bad_return return address to process %d "
303 /* Set EBP, ESP, EIP to invoke gdbserver.
304 vgdb is 32bits, speaking with a 32bits process. */
305 (*regs
)[EBP
] = sp
; // bp set to sp
307 (*regs
)[EIP
] = shared32
->invoke_gdbserver
;
308 #elif defined(VGA_amd64)
309 /* Set RBP, RSP, RIP to invoke gdbserver.
310 vgdb is 64bits, speaking with a 32bits process. */
311 (*regs
)[REG_RBP
] = sp
; // bp set to sp
312 (*regs
)[REG_RSP
] = sp
;
313 (*regs
)[REG_RIP
] = shared32
->invoke_gdbserver
;
315 I_die_here
: not x86
or amd64 in x86
/amd64 section
/
319 I_die_here
: architecture missing in vgdb
-invoker
-solaris
.c
322 } else if (shared64
!= NULL
) {
324 assert(0); /* 64bits process with a 32bits vgdb - no way */
325 #elif defined(VGA_amd64)
326 /* 64bits vgdb speaking with a 64 bit process. */
327 const int regsize
= 8;
329 /* Give check argument in rdi - according to C/amd64 ABI. */
330 (*regs
)[REG_RDI
] = check
;
332 /* Push return address on stack: return to breakaddr. */
334 DEBUG(1, "Pushing bad_return return address to process %d memory.\n",
336 int error
= write_memory(pid
, sp
, &bad_return
,
339 ERROR(error
, "Failed to push bad_return return address to process %d "
345 /* set RBP, RSP, RIP to invoke gdbserver */
346 (*regs
)[REG_RBP
] = sp
; // bp set to sp
347 (*regs
)[REG_RSP
] = sp
;
348 (*regs
)[REG_RIP
] = shared64
->invoke_gdbserver
;
350 I_die_here
: architecture missing in vgdb
-invoker
-solaris
.c
356 DEBUG(1, "New stack frame set up for process %d.\n", pid
);
360 /* Creates and starts an agent thread within the inferior process.
361 The agent thread is created stopped and with its held signal set
362 (the signal mask) having all signals except SIGKILL and SIGSTOP
363 blocked. All these signals need to remain blocked while the agent
364 thread is running because valgrind syscall/signal machinery expects
365 that (remember: all valgrind threads are blocked in VgTs_WaitSys
366 - that is the reason why we are invoking the agent, after all).
367 It is necessary to resume the agent thread afterwards.
369 static Bool
invoke_agent(pid_t pid
, prgregset_t
*regs
, id_t
*agent_lwpid
)
371 assert(ctl_fd
!= -1);
373 DEBUG(1, "Creating an agent thread within process %d.\n", pid
);
375 /* Create the agent thread. */
378 memcpy(&ctl
.arg
.regs
, regs
, sizeof(prgregset_t
));
379 size_t bytes
= sizeof(ctl
.cmd
) + sizeof(ctl
.arg
.regs
);
380 ssize_t written
= write(ctl_fd
, (void *) &ctl
, bytes
);
381 if ((written
< 0) || (written
!= bytes
)) {
382 ERROR(errno
, "Failed to write to ctl_fd: PCAGENT.\n");
386 DEBUG(1, "Obtaining agent thread lwpid for process %d.\n", pid
);
388 char procname
[PATH_MAX
];
389 snprintf(procname
, sizeof(procname
),
390 "/proc/%d/lwp/agent/lwpstatus", pid
);
392 int status_fd
= open(procname
, O_RDONLY
, 0);
394 /* Operation failed but there is no way to get rid of the agent
395 thread from outside. We are doomed... */
396 ERROR(errno
, "Failed to open file %s.\n", procname
);
401 ssize_t nread
= read(status_fd
, &status
, sizeof(status
));
402 if ((nread
< 0) || (nread
!= sizeof(status
))) {
403 ERROR(errno
, "Failed to read from %s.\n", procname
);
409 *agent_lwpid
= status
.pr_lwpid
;
411 snprintf(procname
, sizeof(procname
),
412 "/proc/%d/lwp/agent/lwpctl", pid
);
414 int agent_ctl_fd
= open(procname
, O_WRONLY
, 0);
415 if (agent_ctl_fd
< 0) {
416 /* Resuming failed but there is no way to get rid of the agent
417 thread from outside. We are doomed... */
418 ERROR(errno
, "Failed to open file %s.\n", procname
);
422 DEBUG(1, "Resuming the agent thread for process %d.\n", pid
);
424 /* Resume the agent thread. */
427 bytes
= sizeof(ctl
.cmd
) + sizeof(ctl
.arg
.flags
);
428 written
= write(agent_ctl_fd
, (void *) &ctl
, bytes
);
429 if ((written
< 0) || (written
!= bytes
)) {
430 /* Resuming failed but there is no way to get rid of the agent
431 thread from outside. We are doomed... */
432 ERROR(errno
, "Failed to write to agent_ctl_fd: PCRUN 0.\n");
437 DEBUG(1, "Agent thread lwpid %d now running within process %d.\n",
443 /* Waits until the agent thread running inside the inferior
445 static Bool
wait_for_agent_exit(pid_t pid
, id_t agent_lwpid
)
447 char procname
[PATH_MAX
];
448 snprintf(procname
, sizeof(procname
), "/proc/%d/lwp/agent/lwpctl", pid
);
450 int agent_ctl_fd
= open(procname
, O_WRONLY
, 0);
451 if (agent_ctl_fd
< 0) {
452 if (errno
== ENOENT
) {
453 DEBUG(1, "Agent control file %s no longer exists. This means "
454 "agent thread %d exited meanwhile.\n",
455 procname
, agent_lwpid
);
458 ERROR(errno
, "Failed to open agent control file %s.\n", procname
);
462 DEBUG(1, "Waiting for agent thread %d to exit.\n", agent_lwpid
);
464 /* Wait until the agent thread stops. This covers also the case
465 when the thread exited. */
468 size_t bytes
= sizeof(ctl
.cmd
);
469 ssize_t written
= write(agent_ctl_fd
, (void *) &ctl
, bytes
);
470 if ((written
< 0) || (written
!= bytes
)) {
471 if (errno
== ENOENT
) {
472 DEBUG(1, "Agent thread lwpid %d has now exited in process %d.\n",
475 ERROR(errno
, "Failed to write to agent_ctl_fd: PCWSTOP.\n");
485 Bool
invoker_invoke_gdbserver(pid_t pid
)
487 if (attach(pid
) != True
) {
492 if (get_regs(pid
, ®s
) != True
) {
497 if (setup_stack_frame(pid
, ®s
) != True
) {
503 if (invoke_agent(pid
, ®s
, &agent_lwpid
) != True
) {
508 if (wait_for_agent_exit(pid
, agent_lwpid
) != True
) {
517 void invoker_cleanup_restore_and_detach(void *v_pid
)
519 detach(*(int *) v_pid
);
522 void invoker_restrictions_msg(void)
526 void invoker_valgrind_dying(void)