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-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
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
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
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.
70 typedef Addr CORE_ADDR
;
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);
99 ERROR(error
, "Failed to open %s.\n", procname
);
103 if (debuglevel
>= 1) {
104 DEBUG(1, "Writing bytes '");
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
)) {
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
);
121 DEBUG(1, "Written ok.\n");
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);
137 ERROR(errno
, "Failed to open %s.\n", procname
);
141 DEBUG(1, "Setting run-on-last-close-flag (PR_RLC) to pid %d.\n", pid
);
143 /* Set run-on-last-close flag. */
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");
154 DEBUG(1, "Stopping process %d.\n", pid
);
156 /* Stop the whole process - all threads. */
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");
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);
171 ERROR(errno
, "Failed to open %s.\n", procname
);
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
);
183 if (pstatus
.pr_flags
& PR_RLC
) {
184 DEBUG(2, "Process %d has run-on-last-close flag set. Good.\n", pid
);
186 ERROR(0, "Process %d does not have run-on-last-close flag set!\n", pid
);
191 if (pstatus
.pr_lwp
.pr_flags
& PR_STOPPED
) {
192 DEBUG(3, "Process %d seems to be stopped. Good.\n", pid
);
194 ERROR(0, "Process %d is not stopped!\n", pid
);
203 static void detach(pid_t pid
)
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);
224 ERROR(errno
, "Failed to open file %s.\n", procname
);
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
);
236 DEBUG(3, "Registers of thread %d from process %d: ", status
.pr_lwpid
, pid
);
238 for (i
= 0; i
< _NGREG
; i
++) {
239 PDEBUG(3, "%u: %#lx, ", i
, (unsigned long) status
.pr_reg
[i
]);
243 memcpy(regs
, &status
.pr_reg
, sizeof(prgregset_t
));
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
264 const Addr bad_return
= 0;
267 Addr sp
= (*regs
)[UESP
];
268 #elif defined(VGA_amd64)
269 Addr sp
= (*regs
)[REG_RSP
];
271 I_die_here
: (sp
) architecture missing in vgdb
-invoker
-solaris
.c
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. */
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
);
285 ERROR(error
, "Failed to push check argument to process %d memory.\n",
292 DEBUG(1, "Pushing bad_return return address to process %d memory.\n",
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
);
298 ERROR(error
, "Failed to push bad_return return address to process %d "
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
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
;
317 I_die_here
: not x86
or amd64 in x86
/amd64 section
/
321 I_die_here
: architecture missing in vgdb
-invoker
-solaris
.c
324 } else if (shared64
!= NULL
) {
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. */
336 DEBUG(1, "Pushing bad_return return address to process %d memory.\n",
338 int error
= write_memory(pid
, sp
, &bad_return
,
341 ERROR(error
, "Failed to push bad_return return address to process %d "
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
;
352 I_die_here
: architecture missing in vgdb
-invoker
-solaris
.c
358 DEBUG(1, "New stack frame set up for process %d.\n", pid
);
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. */
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");
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);
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
);
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
);
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
);
424 DEBUG(1, "Resuming the agent thread for process %d.\n", pid
);
426 /* Resume the agent thread. */
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");
439 DEBUG(1, "Agent thread lwpid %d now running within process %d.\n",
445 /* Waits until the agent thread running inside the inferior
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
);
460 ERROR(errno
, "Failed to open agent control file %s.\n", procname
);
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. */
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",
477 ERROR(errno
, "Failed to write to agent_ctl_fd: PCWSTOP.\n");
487 Bool
invoker_invoke_gdbserver(pid_t pid
)
489 if (attach(pid
) != True
) {
494 if (get_regs(pid
, ®s
) != True
) {
499 if (setup_stack_frame(pid
, ®s
) != True
) {
505 if (invoke_agent(pid
, ®s
, &agent_lwpid
) != True
) {
510 if (wait_for_agent_exit(pid
, agent_lwpid
) != 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)