Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2319 lines
58 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Process and thread routines.
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997-2001.
  6. //
  7. //----------------------------------------------------------------------------
  8. #include "ntsdp.hpp"
  9. ULONG g_NextProcessUserId;
  10. ULONG g_AllProcessFlags;
  11. ULONG g_NumberProcesses;
  12. ULONG g_TotalNumberThreads;
  13. ULONG g_MaxThreadsInProcess;
  14. PPROCESS_INFO g_ProcessHead;
  15. PPROCESS_INFO g_CurrentProcess;
  16. // Thread specified in thread commands. Used for specific
  17. // thread stepping and execution.
  18. PTHREAD_INFO g_SelectedThread;
  19. ULONG g_SelectExecutionThread;
  20. PTHREAD_INFO g_RegContextThread;
  21. ULONG g_RegContextProcessor = -1;
  22. PTHREAD_INFO g_RegContextSaved;
  23. ULONG64 g_SaveImplicitThread;
  24. ULONG64 g_SaveImplicitProcess;
  25. ULONG g_AllPendingFlags;
  26. PPROCESS_INFO
  27. FindProcessByUserId(
  28. ULONG Id
  29. )
  30. {
  31. PPROCESS_INFO Process;
  32. Process = g_ProcessHead;
  33. while (Process && Process->UserId != Id)
  34. {
  35. Process = Process->Next;
  36. }
  37. return Process;
  38. }
  39. PTHREAD_INFO
  40. FindThreadByUserId(
  41. PPROCESS_INFO Process,
  42. ULONG Id
  43. )
  44. {
  45. PTHREAD_INFO Thread;
  46. if (Process != NULL)
  47. {
  48. for (Thread = Process->ThreadHead;
  49. Thread != NULL;
  50. Thread = Thread->Next)
  51. {
  52. if (Thread->UserId == Id)
  53. {
  54. return Thread;
  55. }
  56. }
  57. }
  58. else
  59. {
  60. for (Process = g_ProcessHead;
  61. Process != NULL;
  62. Process = Process->Next)
  63. {
  64. for (Thread = Process->ThreadHead;
  65. Thread != NULL;
  66. Thread = Thread->Next)
  67. {
  68. if (Thread->UserId == Id)
  69. {
  70. return Thread;
  71. }
  72. }
  73. }
  74. }
  75. return NULL;
  76. }
  77. PPROCESS_INFO
  78. FindProcessBySystemId(
  79. ULONG Id
  80. )
  81. {
  82. PPROCESS_INFO Process;
  83. Process = g_ProcessHead;
  84. while (Process && Process->SystemId != Id)
  85. {
  86. Process = Process->Next;
  87. }
  88. return Process;
  89. }
  90. PTHREAD_INFO
  91. FindThreadBySystemId(
  92. PPROCESS_INFO Process,
  93. ULONG Id
  94. )
  95. {
  96. PTHREAD_INFO Thread;
  97. if (Process != NULL)
  98. {
  99. for (Thread = Process->ThreadHead;
  100. Thread != NULL;
  101. Thread = Thread->Next)
  102. {
  103. if (Thread->SystemId == Id)
  104. {
  105. return Thread;
  106. }
  107. }
  108. }
  109. else
  110. {
  111. for (Process = g_ProcessHead;
  112. Process != NULL;
  113. Process = Process->Next)
  114. {
  115. for (Thread = Process->ThreadHead;
  116. Thread != NULL;
  117. Thread = Thread->Next)
  118. {
  119. if (Thread->SystemId == Id)
  120. {
  121. return Thread;
  122. }
  123. }
  124. }
  125. }
  126. return NULL;
  127. }
  128. PPROCESS_INFO
  129. FindProcessByHandle(
  130. ULONG64 Handle
  131. )
  132. {
  133. PPROCESS_INFO Process;
  134. Process = g_ProcessHead;
  135. while (Process && Process->FullHandle != Handle)
  136. {
  137. Process = Process->Next;
  138. }
  139. return Process;
  140. }
  141. PTHREAD_INFO
  142. FindThreadByHandle(
  143. PPROCESS_INFO Process,
  144. ULONG64 Handle
  145. )
  146. {
  147. PTHREAD_INFO Thread;
  148. if (Process != NULL)
  149. {
  150. for (Thread = Process->ThreadHead;
  151. Thread != NULL;
  152. Thread = Thread->Next)
  153. {
  154. if (Thread->Handle == Handle)
  155. {
  156. return Thread;
  157. }
  158. }
  159. }
  160. else
  161. {
  162. for (Process = g_ProcessHead;
  163. Process != NULL;
  164. Process = Process->Next)
  165. {
  166. for (Thread = Process->ThreadHead;
  167. Thread != NULL;
  168. Thread = Thread->Next)
  169. {
  170. if (Thread->Handle == Handle)
  171. {
  172. return Thread;
  173. }
  174. }
  175. }
  176. }
  177. return NULL;
  178. }
  179. ULONG
  180. FindNextThreadUserId(void)
  181. {
  182. //
  183. // In a dump threads are never deleted so we don't
  184. // have to worry about trying to reuse low thread IDs.
  185. // Just do a simple incremental ID so that large numbers
  186. // of threads can be created quickly.
  187. //
  188. if (IS_DUMP_TARGET())
  189. {
  190. return g_TotalNumberThreads;
  191. }
  192. ULONG UserId = 0;
  193. // Find the lowest unused thread ID across all threads
  194. // in all processes. Thread user IDs are kept unique
  195. // across all threads to prevent user confusion and also
  196. // to give extensions a unique ID for threads.
  197. for (;;)
  198. {
  199. PPROCESS_INFO Process;
  200. PTHREAD_INFO Thread;
  201. // Search all threads to see if the current ID is in use.
  202. for (Process = g_ProcessHead;
  203. Process != NULL;
  204. Process = Process->Next)
  205. {
  206. for (Thread = Process->ThreadHead;
  207. Thread != NULL;
  208. Thread = Thread->Next)
  209. {
  210. if (Thread->UserId == UserId)
  211. {
  212. break;
  213. }
  214. }
  215. if (Thread != NULL)
  216. {
  217. break;
  218. }
  219. }
  220. if (Process != NULL)
  221. {
  222. // A thread is already using the current ID.
  223. // Try the next one.
  224. UserId++;
  225. }
  226. else
  227. {
  228. break;
  229. }
  230. }
  231. return UserId;
  232. }
  233. PPROCESS_INFO
  234. AddProcess(
  235. ULONG SystemId,
  236. ULONG64 Handle,
  237. ULONG InitialThreadSystemId,
  238. ULONG64 InitialThreadHandle,
  239. ULONG64 InitialThreadDataOffset,
  240. ULONG64 StartOffset,
  241. ULONG Flags,
  242. ULONG Options,
  243. ULONG InitialThreadFlags
  244. )
  245. {
  246. PPROCESS_INFO ProcessNew;
  247. PPROCESS_INFO Process;
  248. ProcessNew = (PPROCESS_INFO)calloc(1, sizeof(PROCESS_INFO));
  249. if (!ProcessNew)
  250. {
  251. ErrOut("memory allocation failed\n");
  252. return NULL;
  253. }
  254. if (AddThread(ProcessNew, InitialThreadSystemId, InitialThreadHandle,
  255. InitialThreadDataOffset, StartOffset,
  256. InitialThreadFlags) == NULL)
  257. {
  258. free(ProcessNew);
  259. return NULL;
  260. }
  261. // Process IDs always increase with time to
  262. // prevent reuse of IDs. New processes are
  263. // therefore always at the end of the sorted
  264. // ID list.
  265. if (g_ProcessHead == NULL)
  266. {
  267. ProcessNew->Next = g_ProcessHead;
  268. g_ProcessHead = ProcessNew;
  269. }
  270. else
  271. {
  272. Process = g_ProcessHead;
  273. while (Process->Next)
  274. {
  275. Process = Process->Next;
  276. }
  277. ProcessNew->Next = NULL;
  278. Process->Next = ProcessNew;
  279. }
  280. ProcessNew->UserId = g_NextProcessUserId++;
  281. ProcessNew->SystemId = SystemId;
  282. ProcessNew->FullHandle = Handle;
  283. ProcessNew->Handle = (HANDLE)(ULONG_PTR)Handle;
  284. ProcessNew->InitialBreak = IS_KERNEL_TARGET() ||
  285. (g_EngOptions & DEBUG_ENGOPT_INITIAL_BREAK) != 0;
  286. ProcessNew->InitialBreakWx86 =
  287. (g_EngOptions & DEBUG_ENGOPT_INITIAL_BREAK) != 0;
  288. ProcessNew->Flags = Flags;
  289. ProcessNew->Options = Options;
  290. g_AllProcessFlags |= Flags;
  291. g_NumberProcesses++;
  292. g_Sym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
  293. g_Sym->MaxNameLength = MAX_SYMBOL_LEN;
  294. g_SymStart->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
  295. g_SymStart->MaxNameLength = MAX_SYMBOL_LEN;
  296. SymInitialize( ProcessNew->Handle, NULL, FALSE );
  297. SymRegisterCallback64( ProcessNew->Handle, SymbolCallbackFunction, 0 );
  298. if (IS_USER_TARGET() &&
  299. g_TargetMachineType != IMAGE_FILE_MACHINE_I386)
  300. {
  301. SymRegisterFunctionEntryCallback64
  302. (ProcessNew->Handle, TargetInfo::DynamicFunctionTableCallback,
  303. (ULONG_PTR)g_TargetMachine);
  304. }
  305. SetSymbolSearchPath(ProcessNew);
  306. return ProcessNew;
  307. }
  308. PTHREAD_INFO
  309. AddThread(
  310. PPROCESS_INFO Process,
  311. ULONG SystemId,
  312. ULONG64 Handle,
  313. ULONG64 DataOffset,
  314. ULONG64 StartOffset,
  315. ULONG Flags
  316. )
  317. {
  318. PTHREAD_INFO ThreadCurrent;
  319. PTHREAD_INFO ThreadAfter;
  320. PTHREAD_INFO ThreadNew;
  321. ULONG UserId;
  322. ThreadNew = (PTHREAD_INFO)calloc(1, sizeof(THREAD_INFO));
  323. if (!ThreadNew)
  324. {
  325. ErrOut("memory allocation failed\n");
  326. return NULL;
  327. }
  328. UserId = FindNextThreadUserId();
  329. // Insert the thread into the process's thread list in
  330. // sorted order.
  331. ThreadCurrent = NULL;
  332. for (ThreadAfter = Process->ThreadHead;
  333. ThreadAfter != NULL;
  334. ThreadAfter = ThreadAfter->Next)
  335. {
  336. if (ThreadAfter->UserId > UserId)
  337. {
  338. break;
  339. }
  340. ThreadCurrent = ThreadAfter;
  341. }
  342. ThreadNew->Next = ThreadAfter;
  343. if (ThreadCurrent == NULL)
  344. {
  345. Process->ThreadHead = ThreadNew;
  346. }
  347. else
  348. {
  349. ThreadCurrent->Next = ThreadNew;
  350. }
  351. ThreadNew->Process = Process;
  352. Process->NumberThreads++;
  353. ThreadNew->UserId = UserId;
  354. ThreadNew->SystemId = SystemId;
  355. ThreadNew->Handle = Handle;
  356. ThreadNew->StartAddress = StartOffset;
  357. ThreadNew->Frozen = ThreadNew->Exited = FALSE;
  358. ThreadNew->DataOffset = DataOffset;
  359. ThreadNew->Flags = Flags;
  360. g_TotalNumberThreads++;
  361. if (Process->NumberThreads > g_MaxThreadsInProcess)
  362. {
  363. g_MaxThreadsInProcess = Process->NumberThreads;
  364. }
  365. return ThreadNew;
  366. }
  367. void
  368. DeleteThread(PTHREAD_INFO Thread)
  369. {
  370. Thread->Process->NumberThreads--;
  371. if (Thread->Process->CurrentThread == Thread)
  372. {
  373. Thread->Process->CurrentThread = NULL;
  374. }
  375. RemoveThreadBreakpoints(Thread);
  376. if (Thread->Flags & ENG_PROC_THREAD_CLOSE_HANDLE)
  377. {
  378. DBG_ASSERT(IS_LIVE_USER_TARGET());
  379. ((UserTargetInfo*)g_Target)->m_Services->CloseHandle(Thread->Handle);
  380. }
  381. free(Thread);
  382. PPROCESS_INFO Process;
  383. g_TotalNumberThreads--;
  384. g_MaxThreadsInProcess = 0;
  385. for (Process = g_ProcessHead;
  386. Process != NULL;
  387. Process = Process->Next)
  388. {
  389. if (Process->NumberThreads > g_MaxThreadsInProcess)
  390. {
  391. g_MaxThreadsInProcess = Process->NumberThreads;
  392. }
  393. }
  394. }
  395. void
  396. UpdateAllProcessFlags(void)
  397. {
  398. PPROCESS_INFO Process;
  399. g_AllProcessFlags = 0;
  400. for (Process = g_ProcessHead;
  401. Process != NULL;
  402. Process = Process->Next)
  403. {
  404. g_AllProcessFlags |= Process->Flags;
  405. }
  406. }
  407. void
  408. DeleteProcess(PPROCESS_INFO Process)
  409. {
  410. PDEBUG_IMAGE_INFO Image;
  411. PTHREAD_INFO Thread;
  412. while (Process->ThreadHead != NULL)
  413. {
  414. Thread = Process->ThreadHead;
  415. Process->ThreadHead = Thread->Next;
  416. DeleteThread(Thread);
  417. }
  418. // Suppress notifications until all images are deleted.
  419. g_EngNotify++;
  420. while (Image = Process->ImageHead)
  421. {
  422. Process->ImageHead = Image->Next;
  423. DelImage(Process, Image);
  424. }
  425. SymCleanup(Process->Handle);
  426. g_EngNotify--;
  427. NotifyChangeSymbolState(DEBUG_CSS_UNLOADS, 0, Process);
  428. RemoveProcessBreakpoints(Process);
  429. if (Process->Flags & ENG_PROC_THREAD_CLOSE_HANDLE)
  430. {
  431. DBG_ASSERT(IS_LIVE_USER_TARGET());
  432. ((UserTargetInfo*)g_Target)->m_Services->
  433. CloseHandle(Process->FullHandle);
  434. }
  435. free(Process);
  436. g_NumberProcesses--;
  437. UpdateAllProcessFlags();
  438. }
  439. void
  440. RemoveAndDeleteProcess(PPROCESS_INFO Process, PPROCESS_INFO Prev)
  441. {
  442. if (Prev == NULL)
  443. {
  444. g_ProcessHead = Process->Next;
  445. }
  446. else
  447. {
  448. Prev->Next = Process->Next;
  449. }
  450. DeleteProcess(Process);
  451. }
  452. BOOL
  453. DeleteExitedInfos(void)
  454. {
  455. PPROCESS_INFO Process;
  456. PPROCESS_INFO ProcessNext;
  457. PPROCESS_INFO ProcessPrev;
  458. BOOL DeletedSomething = FALSE;
  459. ProcessPrev = NULL;
  460. for (Process = g_ProcessHead;
  461. Process != NULL;
  462. Process = ProcessNext)
  463. {
  464. ProcessNext = Process->Next;
  465. if (Process->Exited)
  466. {
  467. RemoveAndDeleteProcess(Process, ProcessPrev);
  468. DeletedSomething = TRUE;
  469. }
  470. else
  471. {
  472. PTHREAD_INFO Thread;
  473. PTHREAD_INFO ThreadPrev;
  474. PTHREAD_INFO ThreadNext;
  475. ThreadPrev = NULL;
  476. for (Thread = Process->ThreadHead;
  477. Thread != NULL;
  478. Thread = ThreadNext)
  479. {
  480. ThreadNext = Thread->Next;
  481. if (Thread->Exited)
  482. {
  483. DeleteThread(Thread);
  484. DeletedSomething = TRUE;
  485. if (ThreadPrev == NULL)
  486. {
  487. Process->ThreadHead = ThreadNext;
  488. }
  489. else
  490. {
  491. ThreadPrev->Next = ThreadNext;
  492. }
  493. }
  494. else
  495. {
  496. ThreadPrev = Thread;
  497. }
  498. }
  499. PDEBUG_IMAGE_INFO Image;
  500. PDEBUG_IMAGE_INFO ImagePrev;
  501. PDEBUG_IMAGE_INFO ImageNext;
  502. ImagePrev = NULL;
  503. for (Image = Process->ImageHead;
  504. Image != NULL;
  505. Image = ImageNext)
  506. {
  507. ImageNext = Image->Next;
  508. if (Image->Unloaded)
  509. {
  510. ULONG64 ImageBase = Image->BaseOfImage;
  511. // Delay notification until the image
  512. // is cleaned up and the image list
  513. // repaired.
  514. g_EngNotify++;
  515. DelImage(Process, Image);
  516. g_EngNotify--;
  517. DeletedSomething = TRUE;
  518. if (ImagePrev == NULL)
  519. {
  520. Process->ImageHead = ImageNext;
  521. }
  522. else
  523. {
  524. ImagePrev->Next = ImageNext;
  525. }
  526. NotifyChangeSymbolState(DEBUG_CSS_UNLOADS, ImageBase,
  527. Process);
  528. }
  529. else
  530. {
  531. ImagePrev = Image;
  532. }
  533. }
  534. ProcessPrev = Process;
  535. }
  536. }
  537. return DeletedSomething;
  538. }
  539. void
  540. OutputProcessInfo(
  541. char *s
  542. )
  543. {
  544. PPROCESS_INFO pProcess;
  545. PTHREAD_INFO pThread;
  546. PDEBUG_IMAGE_INFO pImage;
  547. // Kernel mode only has a virtual process and threads right
  548. // now so it isn't particularly interesting.
  549. if (IS_KERNEL_TARGET())
  550. {
  551. return;
  552. }
  553. VerbOut("OUTPUT_PROCESS: %s\n",s);
  554. pProcess = g_ProcessHead;
  555. while (pProcess)
  556. {
  557. VerbOut("id: %x Handle: %I64x index: %d\n",
  558. pProcess->SystemId,
  559. pProcess->FullHandle,
  560. pProcess->UserId);
  561. pThread = pProcess->ThreadHead;
  562. while (pThread)
  563. {
  564. VerbOut(" id: %x hThread: %I64x index: %d addr: %s\n",
  565. pThread->SystemId,
  566. pThread->Handle,
  567. pThread->UserId,
  568. FormatAddr64(pThread->StartAddress));
  569. pThread = pThread->Next;
  570. }
  571. pImage = pProcess->ImageHead;
  572. while (pImage)
  573. {
  574. VerbOut(" hFile: %I64x base: %s\n",
  575. (ULONG64)((ULONG_PTR)pImage->File),
  576. FormatAddr64(pImage->BaseOfImage));
  577. pImage = pImage->Next;
  578. }
  579. pProcess = pProcess->Next;
  580. }
  581. }
  582. /*** ChangeRegContext - change thread register context
  583. *
  584. * Purpose:
  585. * Update the current register context to the thread specified.
  586. * The NULL value implies no context. Update pActiveThread
  587. * to point to the thread in context.
  588. *
  589. * Input:
  590. * pNewContext - pointer to new thread context (NULL if none).
  591. *
  592. * Output:
  593. * None.
  594. *
  595. * Exceptions:
  596. * failed register context call (get or set)
  597. *
  598. * Notes:
  599. * Call with NULL argument to flush current register context
  600. * before continuing with program.
  601. *
  602. *************************************************************************/
  603. void
  604. ChangeRegContext (
  605. PTHREAD_INFO pThreadNew
  606. )
  607. {
  608. if (pThreadNew != g_RegContextThread)
  609. {
  610. // Flush any old thread context.
  611. // We need to be careful when flushing context to
  612. // NT4 boxes at the initial module load because the
  613. // system is in a very fragile state and writing
  614. // back the context generally causes a bugcheck 50.
  615. if (g_RegContextThread != NULL && g_RegContextThread->Handle != NULL &&
  616. (IS_USER_TARGET() || g_ActualSystemVersion != NT_SVER_NT4 ||
  617. g_LastEventType != DEBUG_EVENT_LOAD_MODULE))
  618. {
  619. HRESULT Hr;
  620. Hr = g_Machine->SetContext();
  621. if (Hr == S_OK &&
  622. g_Machine != g_TargetMachine)
  623. {
  624. // If we're flushing register context we need to make
  625. // sure that all machines involved are flushed so
  626. // that context information actually gets sent to
  627. // the target.
  628. Hr = g_TargetMachine->SetContext();
  629. }
  630. if (Hr != S_OK)
  631. {
  632. ErrOut("MachineInfo::SetContext failed - pThread: %N "
  633. "Handle: %I64x Id: %x - Error == 0x%X\n",
  634. g_RegContextThread,
  635. g_RegContextThread->Handle,
  636. g_RegContextThread->SystemId,
  637. Hr);
  638. }
  639. }
  640. g_RegContextThread = pThreadNew;
  641. if (g_RegContextThread != NULL)
  642. {
  643. g_RegContextProcessor =
  644. VIRTUAL_THREAD_INDEX(g_RegContextThread->Handle);
  645. }
  646. else
  647. {
  648. g_RegContextProcessor = -1;
  649. }
  650. g_LastSelector = -1;
  651. // We've now selected a new source of processor data so
  652. // all machines, both emulated and direct, must be invalidated.
  653. for (ULONG i = 0; i < MACHIDX_COUNT; i++)
  654. {
  655. g_AllMachines[i]->InvalidateContext();
  656. }
  657. }
  658. }
  659. void
  660. FlushRegContext(void)
  661. {
  662. PTHREAD_INFO CurThread = g_RegContextThread;
  663. ChangeRegContext(NULL);
  664. ChangeRegContext(CurThread);
  665. }
  666. void
  667. SetCurrentThread(PTHREAD_INFO Thread, BOOL Hidden)
  668. {
  669. BOOL Changed =
  670. (!g_CurrentProcess && Thread) ||
  671. (g_CurrentProcess && !Thread) ||
  672. g_CurrentProcess->CurrentThread != Thread;
  673. ChangeRegContext(Thread);
  674. if (Thread != NULL)
  675. {
  676. g_CurrentProcess = Thread->Process;
  677. }
  678. else
  679. {
  680. g_CurrentProcess = NULL;
  681. }
  682. if (g_CurrentProcess != NULL)
  683. {
  684. g_CurrentProcess->CurrentThread = Thread;
  685. }
  686. // We're switching processors so invalidate
  687. // the implicit data pointers so they get refreshed.
  688. ResetImplicitData();
  689. // In kernel targets update the page directory for the current
  690. // processor's page directory base value so that virtual
  691. // memory mappings are done according to the current processor
  692. // state. This only applies to full dumps because triage
  693. // dumps only have a single processor, so there's nothing to
  694. // switch, and summary dumps only guarantee that the crashing
  695. // processor's page directory page is saved. A user can
  696. // still manually change the directory through .context if
  697. // they wish.
  698. if (IS_KERNEL_TARGET() && IS_KERNEL_FULL_DUMP())
  699. {
  700. if (g_TargetMachine->SetDefaultPageDirectories(PAGE_DIR_ALL) != S_OK)
  701. {
  702. WarnOut("WARNING: Unable to reset page directories\n");
  703. }
  704. }
  705. if (!Hidden && Changed)
  706. {
  707. if (Thread != NULL)
  708. {
  709. g_Machine->GetPC(&g_AssemDefault);
  710. g_UnasmDefault = g_AssemDefault;
  711. }
  712. NotifyChangeEngineState(DEBUG_CES_CURRENT_THREAD,
  713. Thread != NULL ? Thread->UserId : DEBUG_ANY_ID,
  714. TRUE);
  715. }
  716. }
  717. void
  718. SetCurrentProcessorThread(ULONG Processor, BOOL Hidden)
  719. {
  720. //
  721. // Switch to the thread representing a particular processor.
  722. // This only works with the kernel virtual threads.
  723. //
  724. DBG_ASSERT(IS_KERNEL_TARGET());
  725. PTHREAD_INFO Thread = FindThreadBySystemId(g_CurrentProcess,
  726. VIRTUAL_THREAD_ID(Processor));
  727. DBG_ASSERT(Thread != NULL);
  728. SetCurrentThread(Thread, Hidden);
  729. }
  730. void
  731. SaveSetCurrentProcessorThread(ULONG Processor)
  732. {
  733. // This is only used for kd sessions to conserve
  734. // bandwidth when temporarily switching processors.
  735. DBG_ASSERT(IS_KERNEL_TARGET());
  736. g_RegContextSaved = g_RegContextThread;
  737. g_Machine->KdSaveProcessorState();
  738. g_RegContextThread = NULL;
  739. g_SaveImplicitThread = g_ImplicitThreadData;
  740. g_SaveImplicitProcess = g_ImplicitProcessData;
  741. // Don't notify on this change as it is only temporary.
  742. g_EngNotify++;
  743. SetCurrentProcessorThread(Processor, TRUE);
  744. g_EngNotify--;
  745. }
  746. void
  747. RestoreCurrentProcessorThread(void)
  748. {
  749. // This is only used for kd sessions to conserve
  750. // bandwidth when temporarily switching processors.
  751. DBG_ASSERT(IS_KERNEL_TARGET());
  752. g_Machine->KdRestoreProcessorState();
  753. if (g_RegContextSaved != NULL)
  754. {
  755. g_RegContextProcessor =
  756. VIRTUAL_THREAD_INDEX(g_RegContextSaved->Handle);
  757. }
  758. else
  759. {
  760. g_RegContextProcessor = -1;
  761. }
  762. g_LastSelector = -1;
  763. g_RegContextThread = g_RegContextSaved;
  764. g_ImplicitThreadData = g_SaveImplicitThread;
  765. g_ImplicitProcessData = g_SaveImplicitProcess;
  766. // Don't notify on this change as it was only temporary.
  767. g_EngNotify++;
  768. SetCurrentThread(g_RegContextThread, TRUE);
  769. g_EngNotify--;
  770. }
  771. #define BUFFER_THREADS 64
  772. void
  773. SuspendAllThreads(void)
  774. {
  775. if (IS_DUMP_TARGET() || IS_KERNEL_TARGET())
  776. {
  777. // Nothing to do.
  778. return;
  779. }
  780. PPROCESS_INFO Process;
  781. PTHREAD_INFO Thread;
  782. ULONG64 Threads[BUFFER_THREADS];
  783. ULONG Counts[BUFFER_THREADS];
  784. PULONG StoreCounts[BUFFER_THREADS];
  785. ULONG Buffered;
  786. ULONG i;
  787. Buffered = 0;
  788. Process = g_ProcessHead;
  789. while (Process != NULL)
  790. {
  791. Thread = Process->ThreadHead;
  792. while (Thread != NULL)
  793. {
  794. if (!Process->Exited &&
  795. !Thread->Exited &&
  796. Thread->Handle != 0)
  797. {
  798. #ifdef DBG_SUSPEND
  799. dprintf("** suspending thread id: %x handle: %I64x\n",
  800. Thread->SystemId, Thread->Handle);
  801. #endif
  802. if (Thread->InternalFreezeCount > 0)
  803. {
  804. Thread->InternalFreezeCount--;
  805. }
  806. else if (Thread->FreezeCount > 0)
  807. {
  808. dprintf("thread %d can execute\n", Thread->UserId);
  809. Thread->FreezeCount--;
  810. }
  811. else
  812. {
  813. if (Buffered == BUFFER_THREADS)
  814. {
  815. if ((((UserTargetInfo*)g_Target)->m_Services->
  816. SuspendThreads(Buffered, Threads,
  817. Counts)) != S_OK)
  818. {
  819. WarnOut("SuspendThread failed\n");
  820. }
  821. for (i = 0; i < Buffered; i++)
  822. {
  823. *StoreCounts[i] = Counts[i];
  824. }
  825. Buffered = 0;
  826. }
  827. Threads[Buffered] = Thread->Handle;
  828. StoreCounts[Buffered] = &Thread->SuspendCount;
  829. Buffered++;
  830. }
  831. }
  832. Thread = Thread->Next;
  833. }
  834. Process = Process->Next;
  835. }
  836. if (Buffered > 0)
  837. {
  838. if ((((UserTargetInfo*)g_Target)->m_Services->
  839. SuspendThreads(Buffered, Threads, Counts)) != S_OK)
  840. {
  841. WarnOut("SuspendThread failed\n");
  842. }
  843. for (i = 0; i < Buffered; i++)
  844. {
  845. *StoreCounts[i] = Counts[i];
  846. }
  847. }
  848. }
  849. BOOL
  850. ResumeAllThreads(void)
  851. {
  852. PPROCESS_INFO Process;
  853. PTHREAD_INFO Thread;
  854. if (IS_DUMP_TARGET())
  855. {
  856. // Nothing to do.
  857. return TRUE;
  858. }
  859. else if (IS_KERNEL_TARGET())
  860. {
  861. // Wipe out all thread data offsets since the set
  862. // of threads on the processors after execution will
  863. // not be the same.
  864. for (Thread = g_ProcessHead->ThreadHead;
  865. Thread != NULL;
  866. Thread = Thread->Next)
  867. {
  868. Thread->DataOffset = 0;
  869. }
  870. return TRUE;
  871. }
  872. BOOL EventActive = FALSE;
  873. BOOL EventAlive = FALSE;
  874. ULONG64 Threads[BUFFER_THREADS];
  875. ULONG Counts[BUFFER_THREADS];
  876. PULONG StoreCounts[BUFFER_THREADS];
  877. ULONG Buffered;
  878. ULONG i;
  879. Buffered = 0;
  880. Process = g_ProcessHead;
  881. while (Process != NULL)
  882. {
  883. Thread = Process->ThreadHead;
  884. while (Thread != NULL)
  885. {
  886. if (!Process->Exited &&
  887. !Thread->Exited &&
  888. Thread->Handle != 0)
  889. {
  890. if (Process == g_EventProcess)
  891. {
  892. EventAlive = TRUE;
  893. }
  894. #ifdef DBG_SUSPEND
  895. dprintf("** resuming thread id: %x handle: %I64x\n",
  896. Thread->SystemId, Thread->Handle);
  897. #endif
  898. if ((g_EngStatus & ENG_STATUS_STOP_SESSION) == 0 &&
  899. Process == g_EventProcess &&
  900. ((g_SelectExecutionThread != SELTHREAD_ANY &&
  901. Thread != g_SelectedThread) ||
  902. (g_SelectExecutionThread == SELTHREAD_ANY &&
  903. Thread->Frozen)))
  904. {
  905. if (g_SelectExecutionThread != SELTHREAD_INTERNAL_THREAD)
  906. {
  907. dprintf("thread %d not executing\n", Thread->UserId);
  908. Thread->FreezeCount++;
  909. }
  910. else
  911. {
  912. Thread->InternalFreezeCount++;
  913. }
  914. }
  915. else
  916. {
  917. if (Process == g_EventProcess)
  918. {
  919. EventActive = TRUE;
  920. }
  921. if (Buffered == BUFFER_THREADS)
  922. {
  923. if ((((UserTargetInfo*)g_Target)->m_Services->
  924. ResumeThreads(Buffered, Threads,
  925. Counts)) != S_OK)
  926. {
  927. WarnOut("ResumeThread failed\n");
  928. }
  929. for (i = 0; i < Buffered; i++)
  930. {
  931. *StoreCounts[i] = Counts[i];
  932. }
  933. Buffered = 0;
  934. }
  935. Threads[Buffered] = Thread->Handle;
  936. StoreCounts[Buffered] = &Thread->SuspendCount;
  937. Buffered++;
  938. }
  939. }
  940. Thread = Thread->Next;
  941. }
  942. Process = Process->Next;
  943. }
  944. if (Buffered > 0)
  945. {
  946. if ((((UserTargetInfo*)g_Target)->m_Services->
  947. ResumeThreads(Buffered, Threads, Counts)) != S_OK)
  948. {
  949. WarnOut("ResumeThread failed\n");
  950. }
  951. for (i = 0; i < Buffered; i++)
  952. {
  953. *StoreCounts[i] = Counts[i];
  954. }
  955. }
  956. if (EventAlive && !EventActive)
  957. {
  958. ErrOut("No active threads to run in event process %d\n",
  959. g_EventProcess->UserId);
  960. return FALSE;
  961. }
  962. return TRUE;
  963. }
  964. void
  965. parseProcessCmds (
  966. void
  967. )
  968. {
  969. UCHAR ch;
  970. PPROCESS_INFO pProcess;
  971. ULONG UserId;
  972. ch = PeekChar();
  973. if (ch == '\0' || ch == ';')
  974. {
  975. fnOutputProcessInfo(NULL);
  976. }
  977. else
  978. {
  979. pProcess = g_CurrentProcess;
  980. g_CurCmd++;
  981. if (ch == '.')
  982. {
  983. ;
  984. }
  985. else if (ch == '#')
  986. {
  987. pProcess = g_EventProcess;
  988. }
  989. else if (ch == '*')
  990. {
  991. pProcess = NULL;
  992. }
  993. else if (ch >= '0' && ch <= '9')
  994. {
  995. UserId = 0;
  996. do
  997. {
  998. UserId = UserId * 10 + ch - '0';
  999. ch = *g_CurCmd++;
  1000. } while (ch >= '0' && ch <= '9');
  1001. g_CurCmd--;
  1002. pProcess = FindProcessByUserId(UserId);
  1003. if (pProcess == NULL)
  1004. {
  1005. error(BADPROCESS);
  1006. }
  1007. }
  1008. else
  1009. {
  1010. g_CurCmd--;
  1011. }
  1012. ch = PeekChar();
  1013. if (ch == '\0' || ch == ';')
  1014. {
  1015. fnOutputProcessInfo(pProcess);
  1016. }
  1017. else
  1018. {
  1019. g_CurCmd++;
  1020. if (tolower(ch) == 's')
  1021. {
  1022. if (pProcess == NULL)
  1023. {
  1024. error(BADPROCESS);
  1025. }
  1026. if (pProcess->CurrentThread == NULL)
  1027. {
  1028. pProcess->CurrentThread = pProcess->ThreadHead;
  1029. if (pProcess->CurrentThread == NULL)
  1030. {
  1031. error(BADPROCESS);
  1032. }
  1033. }
  1034. SetPromptThread(pProcess->CurrentThread,
  1035. SPT_DEFAULT_OCI_FLAGS);
  1036. }
  1037. else
  1038. {
  1039. g_CurCmd--;
  1040. }
  1041. }
  1042. }
  1043. }
  1044. void
  1045. SetPromptThread(
  1046. PTHREAD_INFO pThread,
  1047. ULONG uOciFlags
  1048. )
  1049. {
  1050. SetCurrentThread(pThread, FALSE);
  1051. ResetCurrentScope();
  1052. OutCurInfo(uOciFlags, g_Machine->m_AllMask,
  1053. DEBUG_OUTPUT_PROMPT_REGISTERS);
  1054. // Assem/unasm defaults already reset so just update
  1055. // the dump default from them.
  1056. g_DumpDefault = g_AssemDefault;
  1057. }
  1058. void
  1059. fnOutputProcessInfo (
  1060. PPROCESS_INFO pProcessOut
  1061. )
  1062. {
  1063. PPROCESS_INFO pProcess;
  1064. pProcess = g_ProcessHead;
  1065. while (pProcess)
  1066. {
  1067. if (pProcessOut == NULL || pProcessOut == pProcess)
  1068. {
  1069. char CurMark;
  1070. PSTR DebugKind;
  1071. if (pProcess == g_CurrentProcess)
  1072. {
  1073. CurMark = '.';
  1074. }
  1075. else if (pProcess == g_EventProcess)
  1076. {
  1077. CurMark = '#';
  1078. }
  1079. else
  1080. {
  1081. CurMark = ' ';
  1082. }
  1083. DebugKind = "child";
  1084. if (pProcess->Exited)
  1085. {
  1086. DebugKind = "exited";
  1087. }
  1088. else if (pProcess->Flags & ENG_PROC_ATTACHED)
  1089. {
  1090. DebugKind = (pProcess->Flags & ENG_PROC_SYSTEM) ?
  1091. "system" : "attach";
  1092. }
  1093. else if (pProcess->Flags & ENG_PROC_CREATED)
  1094. {
  1095. DebugKind = "create";
  1096. }
  1097. else if (pProcess->Flags & ENG_PROC_EXAMINED)
  1098. {
  1099. DebugKind = "examine";
  1100. }
  1101. dprintf("%c%3ld\tid: %lx\t%s\tname: %s\n",
  1102. CurMark,
  1103. pProcess->UserId,
  1104. pProcess->SystemId,
  1105. DebugKind,
  1106. pProcess->ExecutableImage != NULL ?
  1107. pProcess->ExecutableImage->ImagePath :
  1108. (pProcess->ImageHead != NULL ?
  1109. pProcess->ImageHead->ImagePath :
  1110. "?NoImage?")
  1111. );
  1112. }
  1113. pProcess = pProcess->Next;
  1114. }
  1115. }
  1116. void
  1117. SuspendResumeThreads(PPROCESS_INFO Process, BOOL Susp, PTHREAD_INFO Match)
  1118. {
  1119. PTHREAD_INFO Thrd;
  1120. if (Process == NULL)
  1121. {
  1122. ErrOut("SuspendResumeThreads given a NULL process\n");
  1123. return;
  1124. }
  1125. for (Thrd = Process->ThreadHead;
  1126. Thrd != NULL;
  1127. Thrd = Thrd->Next)
  1128. {
  1129. if (Match != NULL && Match != Thrd)
  1130. {
  1131. continue;
  1132. }
  1133. HRESULT Status;
  1134. ULONG Count;
  1135. if (Susp)
  1136. {
  1137. Status = ((UserTargetInfo*)g_Target)->m_Services->
  1138. SuspendThreads(1, &Thrd->Handle, &Count);
  1139. }
  1140. else
  1141. {
  1142. Status = ((UserTargetInfo*)g_Target)->m_Services->
  1143. ResumeThreads(1, &Thrd->Handle, &Count);
  1144. }
  1145. if (Status != S_OK)
  1146. {
  1147. ErrOut("Operation failed for thread %d, 0x%X\n",
  1148. Thrd->UserId, Status);
  1149. }
  1150. else
  1151. {
  1152. Thrd->SuspendCount = Count;
  1153. }
  1154. }
  1155. }
  1156. void
  1157. parseThreadCmds (
  1158. DebugClient* Client
  1159. )
  1160. {
  1161. CHAR ch;
  1162. PTHREAD_INFO pThread, Thrd, OrigThread;
  1163. ULONG UserId;
  1164. ULONG64 value1;
  1165. ULONG64 value3;
  1166. ULONG value4;
  1167. ADDR value2;
  1168. STACK_TRACE_TYPE traceType;
  1169. BOOL fFreezeThread = FALSE;
  1170. PCHAR Tmp;
  1171. ch = PeekChar();
  1172. if (ch == '\0' || ch == ';')
  1173. {
  1174. fnOutputThreadInfo(NULL);
  1175. }
  1176. else
  1177. {
  1178. g_CurCmd++;
  1179. pThread = g_CurrentProcess->CurrentThread;
  1180. fFreezeThread = TRUE;
  1181. if (ch == '.')
  1182. {
  1183. // Current thread is the default.
  1184. }
  1185. else if (ch == '#')
  1186. {
  1187. pThread = g_EventThread;
  1188. }
  1189. else if (ch == '*')
  1190. {
  1191. pThread = NULL;
  1192. fFreezeThread = FALSE;
  1193. }
  1194. else if (ch >= '0' && ch <= '9')
  1195. {
  1196. UserId = 0;
  1197. do
  1198. {
  1199. UserId = UserId * 10 + ch - '0';
  1200. ch = *g_CurCmd++;
  1201. }
  1202. while (ch >= '0' && ch <= '9');
  1203. g_CurCmd--;
  1204. pThread = FindThreadByUserId(g_CurrentProcess, UserId);
  1205. if (pThread == NULL)
  1206. {
  1207. error(BADTHREAD);
  1208. }
  1209. }
  1210. else
  1211. {
  1212. g_CurCmd--;
  1213. }
  1214. ch = PeekChar();
  1215. if (ch == '\0' || ch == ';')
  1216. {
  1217. fnOutputThreadInfo(pThread);
  1218. }
  1219. else
  1220. {
  1221. g_CurCmd++;
  1222. switch (ch = (CHAR)tolower(ch))
  1223. {
  1224. case 'b':
  1225. ch = (CHAR)tolower(*g_CurCmd);
  1226. g_CurCmd++;
  1227. if (ch != 'p' && ch != 'a' && ch != 'u')
  1228. {
  1229. if (ch == '\0' || ch == ';')
  1230. {
  1231. g_CurCmd--;
  1232. }
  1233. error(SYNTAX);
  1234. }
  1235. ParseBpCmd(Client, ch, pThread);
  1236. break;
  1237. case 'e':
  1238. Tmp = g_CurCmd;
  1239. OrigThread = g_CurrentProcess->CurrentThread;
  1240. for (Thrd = g_CurrentProcess->ThreadHead;
  1241. Thrd;
  1242. Thrd = Thrd->Next)
  1243. {
  1244. if (pThread == NULL || Thrd == pThread)
  1245. {
  1246. g_CurCmd = Tmp;
  1247. SetCurrentThread(Thrd, TRUE);
  1248. ProcessCommands(Client, TRUE);
  1249. if (g_EngStatus & ENG_STATUS_USER_INTERRUPT)
  1250. {
  1251. g_EngStatus &= ~ENG_STATUS_USER_INTERRUPT;
  1252. break;
  1253. }
  1254. }
  1255. }
  1256. SetCurrentThread(OrigThread, TRUE);
  1257. break;
  1258. case 'f':
  1259. case 'u':
  1260. if (pThread == NULL)
  1261. {
  1262. pThread = g_CurrentProcess->ThreadHead;
  1263. while (pThread)
  1264. {
  1265. pThread->Frozen = (BOOL)(ch == 'f');
  1266. pThread = pThread->Next;
  1267. }
  1268. }
  1269. else
  1270. {
  1271. pThread->Frozen = (BOOL)(ch == 'f');
  1272. }
  1273. break;
  1274. case 'g':
  1275. if (pThread)
  1276. {
  1277. ChangeRegContext(pThread);
  1278. }
  1279. parseGoCmd(pThread, fFreezeThread);
  1280. ChangeRegContext(g_CurrentProcess->CurrentThread);
  1281. break;
  1282. case 'k':
  1283. if (pThread == NULL)
  1284. {
  1285. Tmp = g_CurCmd;
  1286. for (pThread = g_CurrentProcess->ThreadHead;
  1287. pThread;
  1288. pThread = pThread->Next)
  1289. {
  1290. g_CurCmd = Tmp;
  1291. dprintf("\n");
  1292. fnOutputThreadInfo(pThread);
  1293. ChangeRegContext(pThread);
  1294. value1 = 0;
  1295. if (g_EffMachine == IMAGE_FILE_MACHINE_I386)
  1296. {
  1297. value3 = GetRegVal64(X86_EIP);
  1298. }
  1299. else
  1300. {
  1301. value3 = 0;
  1302. }
  1303. ParseStackTrace(&traceType,
  1304. &value2,
  1305. &value1,
  1306. &value3,
  1307. &value4);
  1308. DoStackTrace( value2.off,
  1309. value1,
  1310. value3,
  1311. value4,
  1312. traceType );
  1313. if (g_EngStatus & ENG_STATUS_USER_INTERRUPT)
  1314. {
  1315. break;
  1316. }
  1317. }
  1318. }
  1319. else
  1320. {
  1321. ChangeRegContext(pThread);
  1322. value1 = 0;
  1323. if (g_EffMachine == IMAGE_FILE_MACHINE_I386)
  1324. {
  1325. value3 = GetRegVal64(X86_EIP);
  1326. }
  1327. else
  1328. {
  1329. value3 = 0;
  1330. }
  1331. ParseStackTrace(&traceType,
  1332. &value2,
  1333. &value1,
  1334. &value3,
  1335. &value4);
  1336. DoStackTrace( value2.off,
  1337. value1,
  1338. value3,
  1339. value4,
  1340. traceType );
  1341. }
  1342. ChangeRegContext(g_CurrentProcess->CurrentThread);
  1343. break;
  1344. case 'm':
  1345. case 'n':
  1346. SuspendResumeThreads(g_CurrentProcess, ch == 'n', pThread);
  1347. break;
  1348. case 'p':
  1349. case 't':
  1350. if (pThread)
  1351. {
  1352. ChangeRegContext(pThread);
  1353. }
  1354. parseStepTrace(pThread, fFreezeThread, ch);
  1355. ChangeRegContext(g_CurrentProcess->CurrentThread);
  1356. break;
  1357. case 'r':
  1358. if (pThread == NULL)
  1359. {
  1360. Tmp = g_CurCmd;
  1361. for (pThread = g_CurrentProcess->ThreadHead;
  1362. pThread;
  1363. pThread = pThread->Next)
  1364. {
  1365. g_CurCmd = Tmp;
  1366. ChangeRegContext(pThread);
  1367. ParseRegCmd();
  1368. }
  1369. }
  1370. else
  1371. {
  1372. ChangeRegContext(pThread);
  1373. ParseRegCmd();
  1374. }
  1375. ChangeRegContext(g_CurrentProcess->CurrentThread);
  1376. break;
  1377. case 's':
  1378. if (pThread == NULL)
  1379. {
  1380. error(BADTHREAD);
  1381. }
  1382. SetPromptThread(pThread, SPT_DEFAULT_OCI_FLAGS);
  1383. break;
  1384. default:
  1385. error(SYNTAX);
  1386. }
  1387. }
  1388. }
  1389. }
  1390. void
  1391. fnOutputThreadInfo (
  1392. PTHREAD_INFO pThreadOut
  1393. )
  1394. {
  1395. PTHREAD_INFO pThread;
  1396. pThread = g_CurrentProcess != NULL ? g_CurrentProcess->ThreadHead : NULL;
  1397. while (pThread)
  1398. {
  1399. if (pThreadOut == NULL || pThreadOut == pThread)
  1400. {
  1401. ULONG64 DataOffset;
  1402. HRESULT Status;
  1403. char CurMark;
  1404. Status =
  1405. g_Target->GetThreadInfoDataOffset(pThread, NULL, &DataOffset);
  1406. if (Status != S_OK)
  1407. {
  1408. WarnOut("Unable to get thread data for thread %u\n",
  1409. pThread->UserId);
  1410. DataOffset = 0;
  1411. }
  1412. if (pThread == g_CurrentProcess->CurrentThread)
  1413. {
  1414. CurMark = '.';
  1415. }
  1416. else if (pThread == g_EventThread)
  1417. {
  1418. CurMark = '#';
  1419. }
  1420. else
  1421. {
  1422. CurMark = ' ';
  1423. }
  1424. dprintf("%c%3ld id: %lx.%lx Suspend: %d Teb %s ",
  1425. CurMark,
  1426. pThread->UserId,
  1427. g_CurrentProcess->SystemId,
  1428. pThread->SystemId,
  1429. pThread->SuspendCount,
  1430. FormatAddr64(DataOffset)
  1431. );
  1432. if (pThread->Frozen)
  1433. {
  1434. dprintf("Frozen");
  1435. }
  1436. else
  1437. {
  1438. dprintf("Unfrozen");
  1439. }
  1440. if (pThread->Name[0])
  1441. {
  1442. dprintf(" \"%s\"", pThread->Name);
  1443. }
  1444. dprintf("\n");
  1445. }
  1446. if (CheckUserInterrupt())
  1447. {
  1448. break;
  1449. }
  1450. pThread = pThread->Next;
  1451. }
  1452. }
  1453. //----------------------------------------------------------------------------
  1454. //
  1455. // Process creation and attach functions.
  1456. //
  1457. //----------------------------------------------------------------------------
  1458. void
  1459. AddPendingProcess(PPENDING_PROCESS Pending)
  1460. {
  1461. Pending->Next = g_ProcessPending;
  1462. g_ProcessPending = Pending;
  1463. g_AllPendingFlags |= Pending->Flags;
  1464. }
  1465. void
  1466. RemovePendingProcess(PPENDING_PROCESS Pending)
  1467. {
  1468. PPENDING_PROCESS Prev, Cur;
  1469. ULONG AllFlags = 0;
  1470. Prev = NULL;
  1471. for (Cur = g_ProcessPending; Cur != NULL; Cur = Cur->Next)
  1472. {
  1473. if (Cur == Pending)
  1474. {
  1475. break;
  1476. }
  1477. Prev = Cur;
  1478. AllFlags |= Cur->Flags;
  1479. }
  1480. if (Cur == NULL)
  1481. {
  1482. DBG_ASSERT(Cur != NULL);
  1483. return;
  1484. }
  1485. Cur = Cur->Next;
  1486. if (Prev == NULL)
  1487. {
  1488. g_ProcessPending = Cur;
  1489. }
  1490. else
  1491. {
  1492. Prev->Next = Cur;
  1493. }
  1494. DiscardPendingProcess(Pending);
  1495. while (Cur != NULL)
  1496. {
  1497. AllFlags |= Cur->Flags;
  1498. Cur = Cur->Next;
  1499. }
  1500. g_AllPendingFlags = AllFlags;
  1501. }
  1502. void
  1503. DiscardPendingProcess(PPENDING_PROCESS Pending)
  1504. {
  1505. DBG_ASSERT(IS_LIVE_USER_TARGET());
  1506. PUSER_DEBUG_SERVICES Services = ((UserTargetInfo*)g_Target)->m_Services;
  1507. if (Pending->InitialThreadHandle)
  1508. {
  1509. Services->CloseHandle(Pending->InitialThreadHandle);
  1510. }
  1511. if (Pending->Handle)
  1512. {
  1513. Services->CloseHandle(Pending->Handle);
  1514. }
  1515. delete Pending;
  1516. }
  1517. void
  1518. DiscardPendingProcesses(void)
  1519. {
  1520. while (g_ProcessPending != NULL)
  1521. {
  1522. PPENDING_PROCESS Next = g_ProcessPending->Next;
  1523. DiscardPendingProcess(g_ProcessPending);
  1524. g_ProcessPending = Next;
  1525. }
  1526. g_AllPendingFlags = 0;
  1527. }
  1528. PPENDING_PROCESS
  1529. FindPendingProcessByFlags(ULONG Flags)
  1530. {
  1531. PPENDING_PROCESS Cur;
  1532. for (Cur = g_ProcessPending; Cur != NULL; Cur = Cur->Next)
  1533. {
  1534. if (Cur->Flags & Flags)
  1535. {
  1536. return Cur;
  1537. }
  1538. }
  1539. return NULL;
  1540. }
  1541. PPENDING_PROCESS
  1542. FindPendingProcessById(ULONG Id)
  1543. {
  1544. PPENDING_PROCESS Cur;
  1545. for (Cur = g_ProcessPending; Cur != NULL; Cur = Cur->Next)
  1546. {
  1547. if (Cur->Id == Id)
  1548. {
  1549. return Cur;
  1550. }
  1551. }
  1552. return NULL;
  1553. }
  1554. void
  1555. VerifyPendingProcesses(void)
  1556. {
  1557. DBG_ASSERT(IS_LIVE_USER_TARGET());
  1558. PUSER_DEBUG_SERVICES Services = ((UserTargetInfo*)g_Target)->m_Services;
  1559. PPENDING_PROCESS Cur;
  1560. Restart:
  1561. for (Cur = g_ProcessPending; Cur != NULL; Cur = Cur->Next)
  1562. {
  1563. ULONG ExitCode;
  1564. if (Cur->Handle &&
  1565. Services->GetProcessExitCode(Cur->Handle, &ExitCode) == S_OK)
  1566. {
  1567. ErrOut("Process %d exited before attach completed\n", Cur->Id);
  1568. RemovePendingProcess(Cur);
  1569. goto Restart;
  1570. }
  1571. }
  1572. }
  1573. void
  1574. AddExamineToPendingAttach(void)
  1575. {
  1576. PPENDING_PROCESS Cur;
  1577. for (Cur = g_ProcessPending; Cur != NULL; Cur = Cur->Next)
  1578. {
  1579. if (Cur->Flags & ENG_PROC_ATTACHED)
  1580. {
  1581. Cur->Flags |= ENG_PROC_EXAMINED;
  1582. g_AllPendingFlags |= ENG_PROC_EXAMINED;
  1583. }
  1584. }
  1585. }
  1586. HRESULT
  1587. StartAttachProcess(ULONG ProcessId, ULONG AttachFlags,
  1588. PPENDING_PROCESS* Pending)
  1589. {
  1590. HRESULT Status;
  1591. PPENDING_PROCESS Pend;
  1592. DBG_ASSERT(IS_LIVE_USER_TARGET());
  1593. if (GetCurrentThreadId() != g_SessionThread)
  1594. {
  1595. ErrOut("Can only attach from the primary thread\n");
  1596. return E_UNEXPECTED;
  1597. }
  1598. if (ProcessId == GetCurrentProcessId())
  1599. {
  1600. ErrOut("Can't debug the current process\n");
  1601. return E_INVALIDARG;
  1602. }
  1603. Pend = new PENDING_PROCESS;
  1604. if (Pend == NULL)
  1605. {
  1606. ErrOut("Unable to allocate memory\n");
  1607. return E_OUTOFMEMORY;
  1608. }
  1609. if ((AttachFlags & DEBUG_ATTACH_NONINVASIVE) == 0)
  1610. {
  1611. if ((Status = ((UserTargetInfo*)g_Target)->m_Services->
  1612. AttachProcess(ProcessId, AttachFlags,
  1613. &Pend->Handle, &Pend->Options)) != S_OK)
  1614. {
  1615. ErrOut("Cannot debug pid %ld, %s\n \"%s\"\n",
  1616. ProcessId, FormatStatusCode(Status), FormatStatus(Status));
  1617. delete Pend;
  1618. return Status;
  1619. }
  1620. Pend->Flags = ENG_PROC_ATTACHED;
  1621. if (AttachFlags & DEBUG_ATTACH_EXISTING)
  1622. {
  1623. Pend->Flags |= ENG_PROC_ATTACH_EXISTING;
  1624. }
  1625. if (ProcessId == CSRSS_PROCESS_ID)
  1626. {
  1627. if (IS_LOCAL_USER_TARGET())
  1628. {
  1629. g_EngOptions |= DEBUG_ENGOPT_DISALLOW_NETWORK_PATHS |
  1630. DEBUG_ENGOPT_IGNORE_DBGHELP_VERSION;
  1631. g_EngOptions &= ~DEBUG_ENGOPT_ALLOW_NETWORK_PATHS;
  1632. }
  1633. Pend->Flags |= ENG_PROC_SYSTEM;
  1634. }
  1635. }
  1636. else
  1637. {
  1638. Pend->Handle = 0;
  1639. Pend->Flags = ENG_PROC_EXAMINED;
  1640. Pend->Options = DEBUG_PROCESS_ONLY_THIS_PROCESS;
  1641. }
  1642. Pend->Id = ProcessId;
  1643. Pend->InitialThreadId = 0;
  1644. Pend->InitialThreadHandle = 0;
  1645. AddPendingProcess(Pend);
  1646. *Pending = Pend;
  1647. return S_OK;
  1648. }
  1649. HRESULT
  1650. StartCreateProcess(PSTR CommandLine, ULONG CreateFlags,
  1651. PPENDING_PROCESS* Pending)
  1652. {
  1653. HRESULT Status;
  1654. PPENDING_PROCESS Pend;
  1655. DBG_ASSERT(IS_LIVE_USER_TARGET());
  1656. if ((CreateFlags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS)) == 0)
  1657. {
  1658. return E_INVALIDARG;
  1659. }
  1660. if (GetCurrentThreadId() != g_SessionThread)
  1661. {
  1662. ErrOut("Can only use .create from the primary thread\n");
  1663. return E_UNEXPECTED;
  1664. }
  1665. Pend = new PENDING_PROCESS;
  1666. if (Pend == NULL)
  1667. {
  1668. ErrOut("Unable to allocate memory\n");
  1669. return E_OUTOFMEMORY;
  1670. }
  1671. dprintf("CommandLine: %s\n", CommandLine);
  1672. if ((Status = ((UserTargetInfo*)g_Target)->m_Services->
  1673. CreateProcess(CommandLine, CreateFlags,
  1674. &Pend->Id, &Pend->InitialThreadId,
  1675. &Pend->Handle, &Pend->InitialThreadHandle)) != S_OK)
  1676. {
  1677. ErrOut("Cannot execute '%s', %s\n \"%s\"\n",
  1678. CommandLine, FormatStatusCode(Status),
  1679. FormatStatusArgs(Status, &CommandLine));
  1680. delete Pend;
  1681. }
  1682. else
  1683. {
  1684. Pend->Flags = ENG_PROC_CREATED;
  1685. Pend->Options = (CreateFlags & DEBUG_ONLY_THIS_PROCESS) ?
  1686. DEBUG_PROCESS_ONLY_THIS_PROCESS : 0;
  1687. AddPendingProcess(Pend);
  1688. *Pending = Pend;
  1689. }
  1690. return Status;
  1691. }
  1692. void
  1693. MarkProcessExited(PPROCESS_INFO Process)
  1694. {
  1695. Process->Exited = TRUE;
  1696. g_EngDefer |= ENG_DEFER_DELETE_EXITED;
  1697. }
  1698. HRESULT
  1699. TerminateProcess(PPROCESS_INFO Process)
  1700. {
  1701. DBG_ASSERT(IS_LIVE_USER_TARGET());
  1702. PUSER_DEBUG_SERVICES Services = ((UserTargetInfo*)g_Target)->m_Services;
  1703. HRESULT Status = S_OK;
  1704. if (!Process->Exited)
  1705. {
  1706. if ((Process->Flags & ENG_PROC_EXAMINED) == 0 &&
  1707. (Status = Services->TerminateProcess(Process->FullHandle,
  1708. E_FAIL)) != S_OK)
  1709. {
  1710. ErrOut("TerminateProcess failed, %s\n",
  1711. FormatStatusCode(Status));
  1712. }
  1713. else
  1714. {
  1715. MarkProcessExited(Process);
  1716. }
  1717. }
  1718. return Status;
  1719. }
  1720. HRESULT
  1721. TerminateProcesses(void)
  1722. {
  1723. DBG_ASSERT(IS_LIVE_USER_TARGET());
  1724. HRESULT Status;
  1725. PUSER_DEBUG_SERVICES Services = ((UserTargetInfo*)g_Target)->m_Services;
  1726. Status = PrepareForSeparation();
  1727. if (Status != S_OK)
  1728. {
  1729. ErrOut("Unable to prepare process for termination, %s\n",
  1730. FormatStatusCode(Status));
  1731. return Status;
  1732. }
  1733. PPROCESS_INFO Process;
  1734. for (Process = g_ProcessHead;
  1735. Process != NULL;
  1736. Process = Process->Next)
  1737. {
  1738. if ((Status = TerminateProcess(Process)) != S_OK)
  1739. {
  1740. goto Exit;
  1741. }
  1742. }
  1743. if (g_EngDefer & ENG_DEFER_CONTINUE_EVENT)
  1744. {
  1745. // The event's process may just been terminated so don't
  1746. // check for failures.
  1747. Services->ContinueEvent(DBG_CONTINUE);
  1748. }
  1749. DiscardLastEvent();
  1750. DEBUG_EVENT64 Event;
  1751. ULONG EventUsed;
  1752. BOOL AnyLeft;
  1753. BOOL AnyExited;
  1754. for (;;)
  1755. {
  1756. while (Services->WaitForEvent(0, &Event, sizeof(Event),
  1757. &EventUsed) == S_OK)
  1758. {
  1759. // Check for process exit events so we can
  1760. // mark the process infos as exited.
  1761. if (EventUsed == sizeof(DEBUG_EVENT32))
  1762. {
  1763. DEBUG_EVENT32 Event32 = *(DEBUG_EVENT32*)&Event;
  1764. DebugEvent32To64(&Event32, &Event);
  1765. }
  1766. else if (EventUsed != sizeof(DEBUG_EVENT64))
  1767. {
  1768. ErrOut("Event data corrupt\n");
  1769. Status = E_FAIL;
  1770. goto Exit;
  1771. }
  1772. if (Event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
  1773. {
  1774. Process = FindProcessBySystemId(Event.dwProcessId);
  1775. if (Process != NULL)
  1776. {
  1777. MarkProcessExited(Process);
  1778. }
  1779. }
  1780. Services->ContinueEvent(DBG_CONTINUE);
  1781. }
  1782. AnyLeft = FALSE;
  1783. AnyExited = FALSE;
  1784. for (Process = g_ProcessHead;
  1785. Process != NULL;
  1786. Process = Process->Next)
  1787. {
  1788. if (!Process->Exited)
  1789. {
  1790. ULONG Code;
  1791. if ((Status = Services->
  1792. GetProcessExitCode(Process->FullHandle, &Code)) == S_OK)
  1793. {
  1794. MarkProcessExited(Process);
  1795. AnyExited = TRUE;
  1796. }
  1797. else if (FAILED(Status))
  1798. {
  1799. ErrOut("Unable to wait for process to terminate, %s\n",
  1800. FormatStatusCode(Status));
  1801. goto Exit;
  1802. }
  1803. else
  1804. {
  1805. AnyLeft = TRUE;
  1806. }
  1807. }
  1808. }
  1809. if (!AnyLeft)
  1810. {
  1811. break;
  1812. }
  1813. if (!AnyExited)
  1814. {
  1815. // Give things time to run and exit.
  1816. Sleep(50);
  1817. }
  1818. }
  1819. // We've terminated everything so it's safe to assume
  1820. // we're no longer debugging any system processes.
  1821. // We do this now rather than wait for DeleteProcess
  1822. // so that shutdown can query the value immediately.
  1823. g_AllProcessFlags &= ~ENG_PROC_SYSTEM;
  1824. //
  1825. // Drain off any remaining events.
  1826. //
  1827. while (Services->WaitForEvent(10, &Event, sizeof(Event), NULL) == S_OK)
  1828. {
  1829. Services->ContinueEvent(DBG_CONTINUE);
  1830. }
  1831. Status = S_OK;
  1832. Exit:
  1833. return Status;
  1834. }
  1835. HRESULT
  1836. DetachProcess(PPROCESS_INFO Process)
  1837. {
  1838. DBG_ASSERT(IS_LIVE_USER_TARGET());
  1839. PUSER_DEBUG_SERVICES Services = ((UserTargetInfo*)g_Target)->m_Services;
  1840. HRESULT Status = S_OK;
  1841. if (!Process->Exited)
  1842. {
  1843. if ((Process->Flags & ENG_PROC_EXAMINED) == 0 &&
  1844. (Status = Services->DetachProcess(Process->SystemId)) != S_OK)
  1845. {
  1846. // Older systems don't support detach so
  1847. // don't show an error message in that case.
  1848. if (Status != E_NOTIMPL)
  1849. {
  1850. ErrOut("DebugActiveProcessStop(%d) failed, %s\n",
  1851. Process->SystemId, FormatStatusCode(Status));
  1852. }
  1853. }
  1854. else
  1855. {
  1856. MarkProcessExited(Process);
  1857. }
  1858. }
  1859. return Status;
  1860. }
  1861. HRESULT
  1862. DetachProcesses(void)
  1863. {
  1864. DBG_ASSERT(IS_LIVE_USER_TARGET());
  1865. HRESULT Status;
  1866. PUSER_DEBUG_SERVICES Services = ((UserTargetInfo*)g_Target)->m_Services;
  1867. Status = PrepareForSeparation();
  1868. if (Status != S_OK)
  1869. {
  1870. ErrOut("Unable to prepare process for detach, %s\n",
  1871. FormatStatusCode(Status));
  1872. return Status;
  1873. }
  1874. if (g_EngDefer & ENG_DEFER_CONTINUE_EVENT)
  1875. {
  1876. if ((Status = Services->ContinueEvent(DBG_CONTINUE)) != S_OK)
  1877. {
  1878. ErrOut("Unable to continue terminated process, %s\n",
  1879. FormatStatusCode(Status));
  1880. return Status;
  1881. }
  1882. }
  1883. DiscardLastEvent();
  1884. PPROCESS_INFO Process;
  1885. for (Process = g_ProcessHead;
  1886. Process != NULL;
  1887. Process = Process->Next)
  1888. {
  1889. DetachProcess(Process);
  1890. }
  1891. // We've terminated everything so it's safe to assume
  1892. // we're no longer debugging any system processes.
  1893. // We do this now rather than wait for DeleteProcess
  1894. // so that shutdown can query the value immediately.
  1895. g_AllProcessFlags &= ~ENG_PROC_SYSTEM;
  1896. //
  1897. // Drain off any remaining events.
  1898. //
  1899. DEBUG_EVENT64 Event;
  1900. while (Services->WaitForEvent(10, &Event, sizeof(Event), NULL) == S_OK)
  1901. {
  1902. Services->ContinueEvent(DBG_CONTINUE);
  1903. }
  1904. return S_OK;
  1905. }
  1906. HRESULT
  1907. AbandonProcess(PPROCESS_INFO Process)
  1908. {
  1909. DBG_ASSERT(IS_LIVE_USER_TARGET());
  1910. HRESULT Status;
  1911. PUSER_DEBUG_SERVICES Services = ((UserTargetInfo*)g_Target)->m_Services;
  1912. if ((Status = Services->AbandonProcess(Process->FullHandle)) != S_OK)
  1913. {
  1914. // Older systems don't support abandon so
  1915. // don't show an error message in that case.
  1916. if (Status != E_NOTIMPL)
  1917. {
  1918. ErrOut("Unable to abandon process\n");
  1919. }
  1920. return Status;
  1921. }
  1922. // We need to continue any existing event as it won't
  1923. // be returned from WaitForDebugEvent again. We
  1924. // do not want to resume execution, though.
  1925. if (g_EngDefer & ENG_DEFER_CONTINUE_EVENT)
  1926. {
  1927. if ((Status = Services->ContinueEvent(DBG_CONTINUE)) != S_OK)
  1928. {
  1929. ErrOut("Unable to continue abandoned event, %s\n",
  1930. FormatStatusCode(Status));
  1931. return Status;
  1932. }
  1933. }
  1934. DiscardLastEvent();
  1935. return Status;
  1936. }
  1937. HRESULT
  1938. SeparateCurrentProcess(ULONG Mode, PSTR Description)
  1939. {
  1940. if (!IS_LIVE_USER_TARGET() ||
  1941. g_CurrentProcess == NULL)
  1942. {
  1943. return E_UNEXPECTED;
  1944. }
  1945. PUSER_DEBUG_SERVICES Services = ((UserTargetInfo*)g_Target)->m_Services;
  1946. if (Mode == SEP_DETACH && IS_CONTEXT_ACCESSIBLE())
  1947. {
  1948. ADDR Pc;
  1949. // Move the PC past any current breakpoint instruction so that
  1950. // the process has a chance of running.
  1951. g_Machine->GetPC(&Pc);
  1952. if (g_Machine->IsBreakpointInstruction(&Pc))
  1953. {
  1954. g_Machine->AdjustPCPastBreakpointInstruction
  1955. (&Pc, DEBUG_BREAKPOINT_CODE);
  1956. }
  1957. }
  1958. // Flush any buffered changes.
  1959. if (IS_CONTEXT_ACCESSIBLE())
  1960. {
  1961. FlushRegContext();
  1962. }
  1963. if (g_EventProcess == g_CurrentProcess)
  1964. {
  1965. if (g_EngDefer & ENG_DEFER_CONTINUE_EVENT)
  1966. {
  1967. Services->ContinueEvent(DBG_CONTINUE);
  1968. }
  1969. DiscardLastEvent();
  1970. g_EventProcess = NULL;
  1971. g_EventThread = NULL;
  1972. }
  1973. SuspendResumeThreads(g_CurrentProcess, FALSE, NULL);
  1974. HRESULT Status;
  1975. PSTR Operation;
  1976. switch(Mode)
  1977. {
  1978. case SEP_DETACH:
  1979. Status = DetachProcess(g_CurrentProcess);
  1980. Operation = "Detached";
  1981. break;
  1982. case SEP_TERMINATE:
  1983. Status = TerminateProcess(g_CurrentProcess);
  1984. if ((g_CurrentProcess->Flags & ENG_PROC_EXAMINED) == 0)
  1985. {
  1986. Operation = "Terminated. "
  1987. "Exit thread and process events will occur.";
  1988. }
  1989. else
  1990. {
  1991. Operation = "Terminated";
  1992. }
  1993. break;
  1994. case SEP_ABANDON:
  1995. Status = AbandonProcess(g_CurrentProcess);
  1996. Operation = "Abandoned";
  1997. break;
  1998. }
  1999. if (Status == S_OK)
  2000. {
  2001. if (Description != NULL)
  2002. {
  2003. strcpy(Description, Operation);
  2004. }
  2005. // If we're detaching or abandoning it's safe to go
  2006. // ahead and remove the process now so that it
  2007. // can't be access further.
  2008. // If we're terminating we have to wait for
  2009. // the exit events to come through so
  2010. // keep the process until that happens.
  2011. if (Mode != SEP_TERMINATE)
  2012. {
  2013. PPROCESS_INFO Prev, Cur;
  2014. Prev = NULL;
  2015. for (Cur = g_ProcessHead;
  2016. Cur != g_CurrentProcess;
  2017. Cur = Cur->Next)
  2018. {
  2019. Prev = Cur;
  2020. }
  2021. RemoveAndDeleteProcess(Cur, Prev);
  2022. g_CurrentProcess = g_ProcessHead;
  2023. if (g_CurrentProcess != NULL)
  2024. {
  2025. if (g_CurrentProcess->CurrentThread == NULL)
  2026. {
  2027. g_CurrentProcess->CurrentThread =
  2028. g_CurrentProcess->ThreadHead;
  2029. }
  2030. if (g_CurrentProcess->CurrentThread != NULL)
  2031. {
  2032. SetPromptThread(g_CurrentProcess->CurrentThread,
  2033. SPT_DEFAULT_OCI_FLAGS);
  2034. }
  2035. }
  2036. }
  2037. else
  2038. {
  2039. g_CurrentProcess->Exited = FALSE;
  2040. }
  2041. }
  2042. else
  2043. {
  2044. SuspendResumeThreads(g_CurrentProcess, TRUE, NULL);
  2045. }
  2046. return Status;
  2047. }