1 /*--------------------------------------------------------------------*/ 2 /*--- Implementation of vgdb invoker subsystem on Solaris */ 3 /* via /proc filesystem and control messages. ---*/ 4 /*--------------------------------------------------------------------*/ 5 6 /* 7 This file is part of Valgrind, a dynamic binary instrumentation 8 framework. 9 10 Copyright (C) 2014-2015 Ivo Raisr <ivosh (at) ivosh.net> 11 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. 16 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. 21 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. 26 27 The GNU General Public License is contained in the file COPYING. 28 */ 29 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: 34 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. 40 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: 45 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. 62 */ 63 64 #include "vgdb.h" 65 66 #include <assert.h> 67 #include <errno.h> 68 #include <string.h> 69 70 typedef Addr CORE_ADDR; 71 72 typedef struct { 73 long cmd; 74 union { 75 long flags; 76 prgregset_t regs; 77 } arg; 78 } ctl_t; 79 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; 84 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) 91 { 92 char procname[PATH_MAX]; 93 snprintf(procname, sizeof(procname), "/proc/%d/as", pid); 94 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; 101 } 102 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); 109 } 110 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; 119 } 120 121 DEBUG(1, "Written ok.\n"); 122 close(as_fd); 123 return 0; 124 } 125 126 /* Attaches to a process identified by pid and stops all threads. */ 127 static Bool attach(pid_t pid) 128 { 129 char procname[PATH_MAX]; 130 snprintf(procname, sizeof(procname), "/proc/%d/ctl", pid); 131 132 DEBUG(1, "Attaching to pid %d.\n", pid); 133 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; 139 } 140 141 DEBUG(1, "Setting run-on-last-close-flag (PR_RLC) to pid %d.\n", pid); 142 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; 152 } 153 154 DEBUG(1, "Stopping process %d.\n", pid); 155 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; 163 } 164 165 DEBUG(1, "Process %d stopped.\n", pid); 166 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; 173 } 174 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; 181 } 182 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; 189 } 190 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; 197 } 198 199 close(status_fd); 200 return True; 201 } 202 203 static void detach(pid_t pid) 204 { 205 if (ctl_fd != -1) { 206 close(ctl_fd); 207 ctl_fd = -1; 208 } 209 210 DEBUG(1, "Detached from pid %d.\n", pid); 211 } 212 213 /* Gets the registers of the first thread. */ 214 static Bool get_regs(pid_t pid, prgregset_t *regs) 215 { 216 char procname[PATH_MAX]; 217 snprintf(procname, sizeof(procname), "/proc/%d/lwp/1/lwpstatus", pid); 218 219 DEBUG(1, "Getting registers from the first thread of process %d.\n", pid); 220 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; 226 } 227 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; 234 } 235 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]); 240 } 241 PDEBUG(3, "\n"); 242 243 memcpy(regs, &status.pr_reg, sizeof(prgregset_t)); 244 close(status_fd); 245 return True; 246 } 247 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. 251 */ 252 static Bool setup_stack_frame(pid_t pid, prgregset_t *regs) 253 { 254 DEBUG(1, "Setting up new stack frame of process %d.\n", pid); 255 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. 259 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; 265 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 273 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; 278 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; 289 } 290 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; 302 } 303 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 319 320 #else 321 I_die_here : architecture missing in vgdb-invoker-solaris.c 322 #endif 323 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; 330 331 /* Give check argument in rdi - according to C/amd64 ABI. */ 332 (*regs)[REG_RDI] = check; 333 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; 345 } 346 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); 356 } 357 358 DEBUG(1, "New stack frame set up for process %d.\n", pid); 359 return True; 360 } 361 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. 370 */ 371 static Bool invoke_agent(pid_t pid, prgregset_t *regs, id_t *agent_lwpid) 372 { 373 assert(ctl_fd != -1); 374 375 DEBUG(1, "Creating an agent thread within process %d.\n", pid); 376 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; 386 } 387 388 DEBUG(1, "Obtaining agent thread lwpid for process %d.\n", pid); 389 390 char procname[PATH_MAX]; 391 snprintf(procname, sizeof(procname), 392 "/proc/%d/lwp/agent/lwpstatus", pid); 393 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; 400 } 401 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; 408 } 409 410 close(status_fd); 411 *agent_lwpid = status.pr_lwpid; 412 413 snprintf(procname, sizeof(procname), 414 "/proc/%d/lwp/agent/lwpctl", pid); 415 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; 422 } 423 424 DEBUG(1, "Resuming the agent thread for process %d.\n", pid); 425 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; 437 } 438 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; 443 } 444 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) 448 { 449 char procname[PATH_MAX]; 450 snprintf(procname, sizeof(procname), "/proc/%d/lwp/agent/lwpctl", pid); 451 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; 459 } 460 ERROR(errno, "Failed to open agent control file %s.\n", procname); 461 return False; 462 } 463 464 DEBUG(1, "Waiting for agent thread %d to exit.\n", agent_lwpid); 465 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; 480 } 481 } 482 483 close(agent_ctl_fd); 484 return True; 485 } 486 487 Bool invoker_invoke_gdbserver(pid_t pid) 488 { 489 if (attach(pid) != True) { 490 return False; 491 } 492 493 prgregset_t regs; 494 if (get_regs(pid, ®s) != True) { 495 detach(pid); 496 return False; 497 } 498 499 if (setup_stack_frame(pid, ®s) != True) { 500 detach(pid); 501 return False; 502 } 503 504 id_t agent_lwpid; 505 if (invoke_agent(pid, ®s, &agent_lwpid) != True) { 506 detach(pid); 507 return False; 508 } 509 510 if (wait_for_agent_exit(pid, agent_lwpid) != True) { 511 detach(pid); 512 return False; 513 } 514 515 detach(pid); 516 return True; 517 } 518 519 void invoker_cleanup_restore_and_detach(void *v_pid) 520 { 521 detach(*(int *) v_pid); 522 } 523 524 void invoker_restrictions_msg(void) 525 { 526 } 527 528 void invoker_valgrind_dying(void) 529 { 530 } 531