1 /* Target-vector operations for controlling win32 child processes, for GDB. 2 Copyright 1995, 1996 Free Software Foundation, Inc. 3 Contributed by Cygnus Support. 4 5 This file is part of GDB. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without eve nthe implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20 */ 21 22 /* by Steve Chamberlain, sac@cygnus.com */ 23 24 /* We assume we're being built with and will be used for cygwin32. */ 25 26 #include "defs.h" 27 #include "frame.h" /* required by inferior.h */ 28 #include "inferior.h" 29 #include "target.h" 30 #include "wait.h" 31 #include "gdbcore.h" 32 #include "command.h" 33 #include <signal.h> 34 #include <sys/types.h> 35 #include <fcntl.h> 36 #include <stdlib.h> 37 38 #ifdef _MSC_VER 39 #include "windefs.h" 40 #else /* other WIN32 compiler */ 41 #include <windows.h> 42 #endif 43 44 #include "buildsym.h" 45 #include "symfile.h" 46 #include "objfiles.h" 47 #include "gdb_string.h" 48 #include "gdbthread.h" 49 #include "gdbcmd.h" 50 #include <sys/param.h> 51 #include <unistd.h> 52 53 #define CHECK(x) check (x, __FILE__,__LINE__) 54 #define DEBUG_EXEC(x) if (debug_exec) printf x 55 #define DEBUG_EVENTS(x) if (debug_events) printf x 56 #define DEBUG_MEM(x) if (debug_memory) printf x 57 #define DEBUG_EXCEPT(x) if (debug_exceptions) printf x 58 59 /* Forward declaration */ 60 extern struct target_ops child_ops; 61 62 static void child_stop PARAMS ((void)); 63 64 /* The most recently read context. Inspect ContextFlags to see what 65 bits are valid. */ 66 67 static CONTEXT context; 68 69 /* The process and thread handles for the above context. */ 70 71 static HANDLE current_process; 72 static HANDLE current_thread; 73 static int current_process_id; 74 static int current_thread_id; 75 76 /* Counts of things. */ 77 static int exception_count = 0; 78 static int event_count = 0; 79 80 /* User options. */ 81 static int new_console = 0; 82 static int new_group = 0; 83 static int debug_exec = 0; /* show execution */ 84 static int debug_events = 0; /* show events from kernel */ 85 static int debug_memory = 0; /* show target memory accesses */ 86 static int debug_exceptions = 0; /* show target exceptions */ 87 88 /* This vector maps GDB's idea of a register's number into an address 89 in the win32 exception context vector. 90 91 It also contains the bit mask needed to load the register in question. 92 93 One day we could read a reg, we could inspect the context we 94 already have loaded, if it doesn't have the bit set that we need, 95 we read that set of registers in using GetThreadContext. If the 96 context already contains what we need, we just unpack it. Then to 97 write a register, first we have to ensure that the context contains 98 the other regs of the group, and then we copy the info in and set 99 out bit. */ 100 101 struct regmappings 102 { 103 char *incontext; 104 int mask; 105 }; 106 107 static const struct regmappings mappings[] = 108 { 109 #ifdef __PPC__ 110 {(char *) &context.Gpr0, CONTEXT_INTEGER}, 111 {(char *) &context.Gpr1, CONTEXT_INTEGER}, 112 {(char *) &context.Gpr2, CONTEXT_INTEGER}, 113 {(char *) &context.Gpr3, CONTEXT_INTEGER}, 114 {(char *) &context.Gpr4, CONTEXT_INTEGER}, 115 {(char *) &context.Gpr5, CONTEXT_INTEGER}, 116 {(char *) &context.Gpr6, CONTEXT_INTEGER}, 117 {(char *) &context.Gpr7, CONTEXT_INTEGER}, 118 119 {(char *) &context.Gpr8, CONTEXT_INTEGER}, 120 {(char *) &context.Gpr9, CONTEXT_INTEGER}, 121 {(char *) &context.Gpr10, CONTEXT_INTEGER}, 122 {(char *) &context.Gpr11, CONTEXT_INTEGER}, 123 {(char *) &context.Gpr12, CONTEXT_INTEGER}, 124 {(char *) &context.Gpr13, CONTEXT_INTEGER}, 125 {(char *) &context.Gpr14, CONTEXT_INTEGER}, 126 {(char *) &context.Gpr15, CONTEXT_INTEGER}, 127 128 {(char *) &context.Gpr16, CONTEXT_INTEGER}, 129 {(char *) &context.Gpr17, CONTEXT_INTEGER}, 130 {(char *) &context.Gpr18, CONTEXT_INTEGER}, 131 {(char *) &context.Gpr19, CONTEXT_INTEGER}, 132 {(char *) &context.Gpr20, CONTEXT_INTEGER}, 133 {(char *) &context.Gpr21, CONTEXT_INTEGER}, 134 {(char *) &context.Gpr22, CONTEXT_INTEGER}, 135 {(char *) &context.Gpr23, CONTEXT_INTEGER}, 136 137 {(char *) &context.Gpr24, CONTEXT_INTEGER}, 138 {(char *) &context.Gpr25, CONTEXT_INTEGER}, 139 {(char *) &context.Gpr26, CONTEXT_INTEGER}, 140 {(char *) &context.Gpr27, CONTEXT_INTEGER}, 141 {(char *) &context.Gpr28, CONTEXT_INTEGER}, 142 {(char *) &context.Gpr29, CONTEXT_INTEGER}, 143 {(char *) &context.Gpr30, CONTEXT_INTEGER}, 144 {(char *) &context.Gpr31, CONTEXT_INTEGER}, 145 146 {(char *) &context.Fpr0, CONTEXT_FLOATING_POINT}, 147 {(char *) &context.Fpr1, CONTEXT_FLOATING_POINT}, 148 {(char *) &context.Fpr2, CONTEXT_FLOATING_POINT}, 149 {(char *) &context.Fpr3, CONTEXT_FLOATING_POINT}, 150 {(char *) &context.Fpr4, CONTEXT_FLOATING_POINT}, 151 {(char *) &context.Fpr5, CONTEXT_FLOATING_POINT}, 152 {(char *) &context.Fpr6, CONTEXT_FLOATING_POINT}, 153 {(char *) &context.Fpr7, CONTEXT_FLOATING_POINT}, 154 155 {(char *) &context.Fpr8, CONTEXT_FLOATING_POINT}, 156 {(char *) &context.Fpr9, CONTEXT_FLOATING_POINT}, 157 {(char *) &context.Fpr10, CONTEXT_FLOATING_POINT}, 158 {(char *) &context.Fpr11, CONTEXT_FLOATING_POINT}, 159 {(char *) &context.Fpr12, CONTEXT_FLOATING_POINT}, 160 {(char *) &context.Fpr13, CONTEXT_FLOATING_POINT}, 161 {(char *) &context.Fpr14, CONTEXT_FLOATING_POINT}, 162 {(char *) &context.Fpr15, CONTEXT_FLOATING_POINT}, 163 164 {(char *) &context.Fpr16, CONTEXT_FLOATING_POINT}, 165 {(char *) &context.Fpr17, CONTEXT_FLOATING_POINT}, 166 {(char *) &context.Fpr18, CONTEXT_FLOATING_POINT}, 167 {(char *) &context.Fpr19, CONTEXT_FLOATING_POINT}, 168 {(char *) &context.Fpr20, CONTEXT_FLOATING_POINT}, 169 {(char *) &context.Fpr21, CONTEXT_FLOATING_POINT}, 170 {(char *) &context.Fpr22, CONTEXT_FLOATING_POINT}, 171 {(char *) &context.Fpr23, CONTEXT_FLOATING_POINT}, 172 173 {(char *) &context.Fpr24, CONTEXT_FLOATING_POINT}, 174 {(char *) &context.Fpr25, CONTEXT_FLOATING_POINT}, 175 {(char *) &context.Fpr26, CONTEXT_FLOATING_POINT}, 176 {(char *) &context.Fpr27, CONTEXT_FLOATING_POINT}, 177 {(char *) &context.Fpr28, CONTEXT_FLOATING_POINT}, 178 {(char *) &context.Fpr29, CONTEXT_FLOATING_POINT}, 179 {(char *) &context.Fpr30, CONTEXT_FLOATING_POINT}, 180 {(char *) &context.Fpr31, CONTEXT_FLOATING_POINT}, 181 182 {(char *) &context.Iar, CONTEXT_CONTROL}, 183 {(char *) &context.Msr, CONTEXT_CONTROL}, 184 {(char *) &context.Cr, CONTEXT_INTEGER}, 185 {(char *) &context.Lr, CONTEXT_CONTROL}, 186 {(char *) &context.Ctr, CONTEXT_CONTROL}, 187 188 {(char *) &context.Xer, CONTEXT_INTEGER}, 189 {0,0}, /* MQ, but there isn't one */ 190 #else 191 {(char *) &context.Eax, CONTEXT_INTEGER}, 192 {(char *) &context.Ecx, CONTEXT_INTEGER}, 193 {(char *) &context.Edx, CONTEXT_INTEGER}, 194 {(char *) &context.Ebx, CONTEXT_INTEGER}, 195 {(char *) &context.Esp, CONTEXT_CONTROL}, 196 {(char *) &context.Ebp, CONTEXT_CONTROL}, 197 {(char *) &context.Esi, CONTEXT_INTEGER}, 198 {(char *) &context.Edi, CONTEXT_INTEGER}, 199 {(char *) &context.Eip, CONTEXT_CONTROL}, 200 {(char *) &context.EFlags, CONTEXT_CONTROL}, 201 {(char *) &context.SegCs, CONTEXT_SEGMENTS}, 202 {(char *) &context.SegSs, CONTEXT_SEGMENTS}, 203 {(char *) &context.SegDs, CONTEXT_SEGMENTS}, 204 {(char *) &context.SegEs, CONTEXT_SEGMENTS}, 205 {(char *) &context.SegFs, CONTEXT_SEGMENTS}, 206 {(char *) &context.SegGs, CONTEXT_SEGMENTS}, 207 {&context.FloatSave.RegisterArea[0 * 10], CONTEXT_FLOATING_POINT}, 208 {&context.FloatSave.RegisterArea[1 * 10], CONTEXT_FLOATING_POINT}, 209 {&context.FloatSave.RegisterArea[2 * 10], CONTEXT_FLOATING_POINT}, 210 {&context.FloatSave.RegisterArea[3 * 10], CONTEXT_FLOATING_POINT}, 211 {&context.FloatSave.RegisterArea[4 * 10], CONTEXT_FLOATING_POINT}, 212 {&context.FloatSave.RegisterArea[5 * 10], CONTEXT_FLOATING_POINT}, 213 {&context.FloatSave.RegisterArea[6 * 10], CONTEXT_FLOATING_POINT}, 214 {&context.FloatSave.RegisterArea[7 * 10], CONTEXT_FLOATING_POINT}, 215 #endif 216 }; 217 218 /* This vector maps the target's idea of an exception (extracted 219 from the DEBUG_EVENT structure) to GDB's idea. */ 220 221 struct xlate_exception 222 { 223 int them; 224 enum target_signal us; 225 }; 226 227 static const struct xlate_exception 228 xlate[] = 229 { 230 {EXCEPTION_ACCESS_VIOLATION, TARGET_SIGNAL_SEGV}, 231 {STATUS_STACK_OVERFLOW, TARGET_SIGNAL_SEGV}, 232 {EXCEPTION_BREAKPOINT, TARGET_SIGNAL_TRAP}, 233 {DBG_CONTROL_C, TARGET_SIGNAL_INT}, 234 {EXCEPTION_SINGLE_STEP, TARGET_SIGNAL_TRAP}, 235 {-1, -1}}; 236 237 static void 238 check (BOOL ok, const char *file, int line) 239 { 240 if (!ok) 241 printf_filtered ("error return %s:%d was %d\n", file, line, GetLastError ()); 242 } 243 244 static void 245 child_fetch_inferior_registers (int r) 246 { 247 if (r < 0) 248 { 249 for (r = 0; r < NUM_REGS; r++) 250 child_fetch_inferior_registers (r); 251 } 252 else 253 { 254 supply_register (r, mappings[r].incontext); 255 } 256 } 257 258 static void 259 child_store_inferior_registers (int r) 260 { 261 if (r < 0) 262 { 263 for (r = 0; r < NUM_REGS; r++) 264 child_store_inferior_registers (r); 265 } 266 else 267 { 268 read_register_gen (r, mappings[r].incontext); 269 } 270 } 271 272 273 /* Wait for child to do something. Return pid of child, or -1 in case 274 of error; store status through argument pointer OURSTATUS. */ 275 276 static int 277 handle_load_dll (char *eventp) 278 { 279 DEBUG_EVENT * event = (DEBUG_EVENT *)eventp; 280 DWORD dll_name_ptr; 281 DWORD done; 282 283 ReadProcessMemory (current_process, 284 (DWORD) event->u.LoadDll.lpImageName, 285 (char *) &dll_name_ptr, 286 sizeof (dll_name_ptr), &done); 287 288 /* See if we could read the address of a string, and that the 289 address isn't null. */ 290 291 if (done == sizeof (dll_name_ptr) && dll_name_ptr) 292 { 293 char *dll_name, *dll_basename; 294 struct objfile *objfile; 295 char unix_dll_name[MAX_PATH]; 296 int size = event->u.LoadDll.fUnicode ? sizeof (WCHAR) : sizeof (char); 297 int len = 0; 298 char b[2]; 299 do 300 { 301 ReadProcessMemory (current_process, 302 dll_name_ptr + len * size, 303 &b, 304 size, 305 &done); 306 len++; 307 } 308 while ((b[0] != 0 || b[size - 1] != 0) && done == size); 309 310 dll_name = alloca (len); 311 312 if (event->u.LoadDll.fUnicode) 313 { 314 WCHAR *unicode_dll_name = (WCHAR *) alloca (len * sizeof (WCHAR)); 315 ReadProcessMemory (current_process, 316 dll_name_ptr, 317 unicode_dll_name, 318 len * sizeof (WCHAR), 319 &done); 320 321 WideCharToMultiByte (CP_ACP, 0, 322 unicode_dll_name, len, 323 dll_name, len, 0, 0); 324 } 325 else 326 { 327 ReadProcessMemory (current_process, 328 dll_name_ptr, 329 dll_name, 330 len, 331 &done); 332 } 333 334 /* FIXME: Can we delete this call? */ 335 cygwin32_conv_to_posix_path (dll_name, unix_dll_name); 336 337 /* FIXME!! It would be nice to define one symbol which pointed to the 338 front of the dll if we can't find any symbols. */ 339 340 if (!(dll_basename = strrchr(dll_name, '\\'))) 341 dll_basename = strrchr(dll_name, '/'); 342 343 ALL_OBJFILES(objfile) 344 { 345 char *objfile_basename; 346 if (!(objfile_basename = strrchr(objfile->name, '\\'))) 347 objfile_basename = strrchr(objfile->name, '/'); 348 349 if (dll_basename && objfile_basename && 350 strcmp(dll_basename+1, objfile_basename+1) == 0) 351 { 352 printf_unfiltered ("%s (symbols previously loaded)\n", 353 dll_basename + 1); 354 return 1; 355 } 356 } 357 358 context.ContextFlags = CONTEXT_FULL | CONTEXT_FLOATING_POINT; 359 GetThreadContext (current_thread, &context); 360 361 /* The symbols in a dll are offset by 0x1000, which is the 362 the offset from 0 of the first byte in an image - because 363 of the file header and the section alignment. 364 365 FIXME: Is this the real reason that we need the 0x1000 ? */ 366 367 368 symbol_file_add (unix_dll_name, 0, 369 (int) event->u.LoadDll.lpBaseOfDll + 0x1000, 0, 0, 0); 370 371 printf_unfiltered ("%x:%s\n", event->u.LoadDll.lpBaseOfDll, 372 unix_dll_name); 373 } 374 return 1; 375 } 376 377 378 static void 379 handle_exception (DEBUG_EVENT * event, struct target_waitstatus *ourstatus) 380 { 381 int i; 382 int done = 0; 383 ourstatus->kind = TARGET_WAITKIND_STOPPED; 384 385 386 switch (event->u.Exception.ExceptionRecord.ExceptionCode) 387 { 388 case EXCEPTION_ACCESS_VIOLATION: 389 DEBUG_EXCEPT (("gdb: Target exception ACCESS_VIOLATION at 0x%08x\n", 390 event->u.Exception.ExceptionRecord.ExceptionAddress)); 391 ourstatus->value.sig = TARGET_SIGNAL_SEGV; 392 break; 393 case STATUS_STACK_OVERFLOW: 394 DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08x\n", 395 event->u.Exception.ExceptionRecord.ExceptionAddress)); 396 ourstatus->value.sig = TARGET_SIGNAL_SEGV; 397 break; 398 case EXCEPTION_BREAKPOINT: 399 DEBUG_EXCEPT (("gdb: Target exception BREAKPOINT at 0x%08x\n", 400 event->u.Exception.ExceptionRecord.ExceptionAddress)); 401 ourstatus->value.sig = TARGET_SIGNAL_TRAP; 402 break; 403 case DBG_CONTROL_C: 404 DEBUG_EXCEPT (("gdb: Target exception CONTROL_C at 0x%08x\n", 405 event->u.Exception.ExceptionRecord.ExceptionAddress)); 406 ourstatus->value.sig = TARGET_SIGNAL_INT; 407 break; 408 case EXCEPTION_SINGLE_STEP: 409 DEBUG_EXCEPT (("gdb: Target exception SINGLE_STEP at 0x%08x\n", 410 event->u.Exception.ExceptionRecord.ExceptionAddress)); 411 ourstatus->value.sig = TARGET_SIGNAL_TRAP; 412 break; 413 default: 414 printf_unfiltered ("gdb: unknown target exception 0x%08x at 0x%08x\n", 415 event->u.Exception.ExceptionRecord.ExceptionCode, 416 event->u.Exception.ExceptionRecord.ExceptionAddress); 417 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN; 418 break; 419 } 420 context.ContextFlags = CONTEXT_FULL | CONTEXT_FLOATING_POINT; 421 GetThreadContext (current_thread, &context); 422 exception_count++; 423 } 424 425 static int 426 child_wait (int pid, struct target_waitstatus *ourstatus) 427 { 428 /* We loop when we get a non-standard exception rather than return 429 with a SPURIOUS because resume can try and step or modify things, 430 which needs a current_thread. But some of these exceptions mark 431 the birth or death of threads, which mean that the current thread 432 isn't necessarily what you think it is. */ 433 434 while (1) 435 { 436 DEBUG_EVENT event; 437 BOOL t = WaitForDebugEvent (&event, INFINITE); 438 char *p; 439 440 event_count++; 441 442 current_thread_id = event.dwThreadId; 443 current_process_id = event.dwProcessId; 444 445 switch (event.dwDebugEventCode) 446 { 447 case CREATE_THREAD_DEBUG_EVENT: 448 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n", 449 event.dwProcessId, event.dwThreadId, 450 "CREATE_THREAD_DEBUG_EVENT")); 451 break; 452 case EXIT_THREAD_DEBUG_EVENT: 453 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n", 454 event.dwProcessId, event.dwThreadId, 455 "EXIT_THREAD_DEBUG_EVENT")); 456 break; 457 case CREATE_PROCESS_DEBUG_EVENT: 458 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n", 459 event.dwProcessId, event.dwThreadId, 460 "CREATE_PROCESS_DEBUG_EVENT")); 461 break; 462 463 case EXIT_PROCESS_DEBUG_EVENT: 464 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n", 465 event.dwProcessId, event.dwThreadId, 466 "EXIT_PROCESS_DEBUG_EVENT")); 467 ourstatus->kind = TARGET_WAITKIND_EXITED; 468 ourstatus->value.integer = event.u.ExitProcess.dwExitCode; 469 CloseHandle (current_process); 470 CloseHandle (current_thread); 471 return current_process_id; 472 break; 473 474 case LOAD_DLL_DEBUG_EVENT: 475 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n", 476 event.dwProcessId, event.dwThreadId, 477 "LOAD_DLL_DEBUG_EVENT")); 478 catch_errors (handle_load_dll, 479 (char*) &event, 480 "\n[failed reading symbols from DLL]\n", 481 RETURN_MASK_ALL); 482 registers_changed(); /* mark all regs invalid */ 483 break; 484 case UNLOAD_DLL_DEBUG_EVENT: 485 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n", 486 event.dwProcessId, event.dwThreadId, 487 "UNLOAD_DLL_DEBUG_EVENT")); 488 break; /* FIXME: don't know what to do here */ 489 case EXCEPTION_DEBUG_EVENT: 490 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n", 491 event.dwProcessId, event.dwThreadId, 492 "EXCEPTION_DEBUG_EVENT")); 493 handle_exception (&event, ourstatus); 494 return current_process_id; 495 496 case OUTPUT_DEBUG_STRING_EVENT: /* message from the kernel */ 497 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n", 498 event.dwProcessId, event.dwThreadId, 499 "OUTPUT_DEBUG_STRING_EVENT")); 500 if (target_read_string 501 ((CORE_ADDR) event.u.DebugString.lpDebugStringData, 502 &p, 1024, 0) && p && *p) 503 { 504 warning(p); 505 free(p); 506 } 507 break; 508 default: 509 printf_unfiltered ("gdb: kernel event for pid=%d tid=%d\n", 510 event.dwProcessId, event.dwThreadId); 511 printf_unfiltered (" unknown event code %d\n", 512 event.dwDebugEventCode); 513 break; 514 } 515 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%d, ctid=%d, DBG_CONTINUE);\n", 516 current_process_id, current_thread_id)); 517 CHECK (ContinueDebugEvent (current_process_id, 518 current_thread_id, 519 DBG_CONTINUE)); 520 } 521 } 522 523 /* Attach to process PID, then initialize for debugging it. */ 524 525 static void 526 child_attach (args, from_tty) 527 char *args; 528 int from_tty; 529 { 530 BOOL ok; 531 532 if (!args) 533 error_no_arg ("process-id to attach"); 534 535 current_process_id = strtoul (args, 0, 0); 536 537 ok = DebugActiveProcess (current_process_id); 538 539 if (!ok) 540 error ("Can't attach to process."); 541 542 exception_count = 0; 543 event_count = 0; 544 545 if (from_tty) 546 { 547 char *exec_file = (char *) get_exec_file (0); 548 549 if (exec_file) 550 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file, 551 target_pid_to_str (current_process_id)); 552 else 553 printf_unfiltered ("Attaching to %s\n", 554 target_pid_to_str (current_process_id)); 555 556 gdb_flush (gdb_stdout); 557 } 558 559 inferior_pid = current_process_id; 560 push_target (&child_ops); 561 } 562 563 static void 564 child_detach (args, from_tty) 565 char *args; 566 int from_tty; 567 { 568 if (from_tty) 569 { 570 char *exec_file = get_exec_file (0); 571 if (exec_file == 0) 572 exec_file = ""; 573 printf_unfiltered ("Detaching from program: %s %s\n", exec_file, 574 target_pid_to_str (inferior_pid)); 575 gdb_flush (gdb_stdout); 576 } 577 inferior_pid = 0; 578 unpush_target (&child_ops); 579 } 580 581 /* Print status information about what we're accessing. */ 582 583 static void 584 child_files_info (ignore) 585 struct target_ops *ignore; 586 { 587 printf_unfiltered ("\tUsing the running image of %s %s.\n", 588 attach_flag ? "attached" : "child", target_pid_to_str (inferior_pid)); 589 } 590 591 /* ARGSUSED */ 592 static void 593 child_open (arg, from_tty) 594 char *arg; 595 int from_tty; 596 { 597 error ("Use the \"run\" command to start a Unix child process."); 598 } 599 600 /* Start an inferior win32 child process and sets inferior_pid to its pid. 601 EXEC_FILE is the file to run. 602 ALLARGS is a string containing the arguments to the program. 603 ENV is the environment vector to pass. Errors reported with error(). */ 604 605 static void 606 child_create_inferior (exec_file, allargs, env) 607 char *exec_file; 608 char *allargs; 609 char **env; 610 { 611 char real_path[MAXPATHLEN]; 612 char *winenv; 613 char *temp; 614 int envlen; 615 int i; 616 617 STARTUPINFO si; 618 PROCESS_INFORMATION pi; 619 struct target_waitstatus dummy; 620 BOOL ret; 621 DWORD flags; 622 char *args; 623 624 if (!exec_file) 625 { 626 error ("No executable specified, use `target exec'.\n"); 627 } 628 629 memset (&si, 0, sizeof (si)); 630 si.cb = sizeof (si); 631 632 cygwin32_conv_to_win32_path (exec_file, real_path); 633 634 flags = DEBUG_ONLY_THIS_PROCESS; 635 636 if (new_group) 637 flags |= CREATE_NEW_PROCESS_GROUP; 638 639 if (new_console) 640 flags |= CREATE_NEW_CONSOLE; 641 642 args = alloca (strlen (real_path) + strlen (allargs) + 2); 643 644 strcpy (args, real_path); 645 646 strcat (args, " "); 647 strcat (args, allargs); 648 649 /* Prepare the environment vars for CreateProcess. */ 650 { 651 /* This code use to assume all env vars were file names and would 652 translate them all to win32 style. That obviously doesn't work in the 653 general case. The current rule is that we only translate PATH. 654 We need to handle PATH because we're about to call CreateProcess and 655 it uses PATH to find DLL's. Fortunately PATH has a well-defined value 656 in both posix and win32 environments. cygwin.dll will change it back 657 to posix style if necessary. */ 658 659 static const char *conv_path_names[] = 660 { 661 "PATH=", 662 0 663 }; 664 665 /* CreateProcess takes the environment list as a null terminated set of 666 strings (i.e. two nulls terminate the list). */ 667 668 /* Get total size for env strings. */ 669 for (envlen = 0, i = 0; env[i] && *env[i]; i++) 670 { 671 int j, len; 672 673 for (j = 0; conv_path_names[j]; j++) 674 { 675 len = strlen (conv_path_names[j]); 676 if (strncmp (conv_path_names[j], env[i], len) == 0) 677 { 678 if (cygwin32_posix_path_list_p (env[i] + len)) 679 envlen += len 680 + cygwin32_posix_to_win32_path_list_buf_size (env[i] + len); 681 else 682 envlen += strlen (env[i]) + 1; 683 break; 684 } 685 } 686 if (conv_path_names[j] == NULL) 687 envlen += strlen (env[i]) + 1; 688 } 689 690 winenv = alloca (envlen + 1); 691 692 /* Copy env strings into new buffer. */ 693 for (temp = winenv, i = 0; env[i] && *env[i]; i++) 694 { 695 int j, len; 696 697 for (j = 0; conv_path_names[j]; j++) 698 { 699 len = strlen (conv_path_names[j]); 700 if (strncmp (conv_path_names[j], env[i], len) == 0) 701 { 702 if (cygwin32_posix_path_list_p (env[i] + len)) 703 { 704 memcpy (temp, env[i], len); 705 cygwin32_posix_to_win32_path_list (env[i] + len, temp + len); 706 } 707 else 708 strcpy (temp, env[i]); 709 break; 710 } 711 } 712 if (conv_path_names[j] == NULL) 713 strcpy (temp, env[i]); 714 715 temp += strlen (temp) + 1; 716 } 717 718 /* Final nil string to terminate new env. */ 719 *temp = 0; 720 } 721 722 ret = CreateProcess (0, 723 args, /* command line */ 724 NULL, /* Security */ 725 NULL, /* thread */ 726 TRUE, /* inherit handles */ 727 flags, /* start flags */ 728 winenv, 729 NULL, /* current directory */ 730 &si, 731 &pi); 732 if (!ret) 733 error ("Error creating process %s, (error %d)\n", exec_file, GetLastError()); 734 735 exception_count = 0; 736 event_count = 0; 737 738 inferior_pid = pi.dwProcessId; 739 current_process = pi.hProcess; 740 current_thread = pi.hThread; 741 current_process_id = pi.dwProcessId; 742 current_thread_id = pi.dwThreadId; 743 push_target (&child_ops); 744 init_thread_list (); 745 init_wait_for_inferior (); 746 clear_proceed_status (); 747 target_terminal_init (); 748 target_terminal_inferior (); 749 750 /* Ignore the first trap */ 751 child_wait (inferior_pid, &dummy); 752 753 proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0); 754 } 755 756 static void 757 child_mourn_inferior () 758 { 759 unpush_target (&child_ops); 760 generic_mourn_inferior (); 761 } 762 763 /* Send a SIGINT to the process group. This acts just like the user typed a 764 ^C on the controlling terminal. */ 765 766 static void 767 child_stop () 768 { 769 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n")); 770 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, 0)); 771 registers_changed(); /* refresh register state */ 772 } 773 774 int 775 child_xfer_memory (CORE_ADDR memaddr, char *our, int len, 776 int write, struct target_ops *target) 777 { 778 DWORD done; 779 if (write) 780 { 781 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08x\n", 782 len, memaddr)); 783 WriteProcessMemory (current_process, memaddr, our, len, &done); 784 FlushInstructionCache (current_process, memaddr, len); 785 } 786 else 787 { 788 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08x\n", 789 len, memaddr)); 790 ReadProcessMemory (current_process, memaddr, our, len, &done); 791 } 792 return done; 793 } 794 795 void 796 child_kill_inferior (void) 797 { 798 CHECK (TerminateProcess (current_process, 0)); 799 CHECK (CloseHandle (current_process)); 800 CHECK (CloseHandle (current_thread)); 801 target_mourn_inferior(); /* or just child_mourn_inferior? */ 802 } 803 804 void 805 child_resume (int pid, int step, enum target_signal signal) 806 { 807 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, signal=%d);\n", 808 pid, step, signal)); 809 810 if (step) 811 { 812 #ifdef __PPC__ 813 warning ("Single stepping not done.\n"); 814 #endif 815 #ifdef i386 816 /* Single step by setting t bit */ 817 child_fetch_inferior_registers (PS_REGNUM); 818 context.EFlags |= FLAG_TRACE_BIT; 819 #endif 820 } 821 822 if (context.ContextFlags) 823 { 824 CHECK (SetThreadContext (current_thread, &context)); 825 context.ContextFlags = 0; 826 } 827 828 if (signal) 829 { 830 fprintf_unfiltered (gdb_stderr, "Can't send signals to the child.\n"); 831 } 832 833 DEBUG_EVENTS (("gdb: ContinueDebugEvent (cpid=%d, ctid=%d, DBG_CONTINUE);\n", 834 current_process_id, current_thread_id)); 835 CHECK (ContinueDebugEvent (current_process_id, 836 current_thread_id, 837 DBG_CONTINUE)); 838 } 839 840 static void 841 child_prepare_to_store () 842 { 843 /* Do nothing, since we can store individual regs */ 844 } 845 846 static int 847 child_can_run () 848 { 849 return 1; 850 } 851 852 static void 853 child_close () 854 { 855 DEBUG_EVENTS (("gdb: child_close, inferior_pid=%d\n", inferior_pid)); 856 } 857 858 struct target_ops child_ops = 859 { 860 "child", /* to_shortname */ 861 "Win32 child process", /* to_longname */ 862 "Win32 child process (started by the \"run\" command).", /* to_doc */ 863 child_open, /* to_open */ 864 child_close, /* to_close */ 865 child_attach, /* to_attach */ 866 child_detach, /* to_detach */ 867 child_resume, /* to_resume */ 868 child_wait, /* to_wait */ 869 child_fetch_inferior_registers,/* to_fetch_registers */ 870 child_store_inferior_registers,/* to_store_registers */ 871 child_prepare_to_store, /* to_child_prepare_to_store */ 872 child_xfer_memory, /* to_xfer_memory */ 873 child_files_info, /* to_files_info */ 874 memory_insert_breakpoint, /* to_insert_breakpoint */ 875 memory_remove_breakpoint, /* to_remove_breakpoint */ 876 terminal_init_inferior, /* to_terminal_init */ 877 terminal_inferior, /* to_terminal_inferior */ 878 terminal_ours_for_output, /* to_terminal_ours_for_output */ 879 terminal_ours, /* to_terminal_ours */ 880 child_terminal_info, /* to_terminal_info */ 881 child_kill_inferior, /* to_kill */ 882 0, /* to_load */ 883 0, /* to_lookup_symbol */ 884 child_create_inferior, /* to_create_inferior */ 885 child_mourn_inferior, /* to_mourn_inferior */ 886 child_can_run, /* to_can_run */ 887 0, /* to_notice_signals */ 888 0, /* to_thread_alive */ 889 child_stop, /* to_stop */ 890 process_stratum, /* to_stratum */ 891 0, /* to_next */ 892 1, /* to_has_all_memory */ 893 1, /* to_has_memory */ 894 1, /* to_has_stack */ 895 1, /* to_has_registers */ 896 1, /* to_has_execution */ 897 0, /* to_sections */ 898 0, /* to_sections_end */ 899 OPS_MAGIC /* to_magic */ 900 }; 901 902 void 903 _initialize_inftarg () 904 { 905 struct cmd_list_element *c; 906 907 add_show_from_set 908 (add_set_cmd ("new-console", class_support, var_boolean, 909 (char *) &new_console, 910 "Set creation of new console when creating child process.", 911 &setlist), 912 &showlist); 913 914 add_show_from_set 915 (add_set_cmd ("new-group", class_support, var_boolean, 916 (char *) &new_group, 917 "Set creation of new group when creating child process.", 918 &setlist), 919 &showlist); 920 921 add_show_from_set 922 (add_set_cmd ("debugexec", class_support, var_boolean, 923 (char *) &debug_exec, 924 "Set whether to display execution in child process.", 925 &setlist), 926 &showlist); 927 928 add_show_from_set 929 (add_set_cmd ("debugevents", class_support, var_boolean, 930 (char *) &debug_events, 931 "Set whether to display kernel events in child process.", 932 &setlist), 933 &showlist); 934 935 add_show_from_set 936 (add_set_cmd ("debugmemory", class_support, var_boolean, 937 (char *) &debug_memory, 938 "Set whether to display memory accesses in child process.", 939 &setlist), 940 &showlist); 941 942 add_show_from_set 943 (add_set_cmd ("debugexceptions", class_support, var_boolean, 944 (char *) &debug_exceptions, 945 "Set whether to display kernel exceptions in child process.", 946 &setlist), 947 &showlist); 948 949 add_target (&child_ops); 950 } 951