Leaked source code of windows server 2003
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.

2493 lines
63 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Process abstraction.
  4. //
  5. // Copyright (C) Microsoft Corporation, 2001-2002.
  6. //
  7. //----------------------------------------------------------------------------
  8. #include "ntsdp.hpp"
  9. #include <common.ver>
  10. #define NTLDR_IMAGE_NAME "ntldr"
  11. #define OSLOADER_IMAGE_NAME "osloader"
  12. #define SETUPLDR_IMAGE_NAME "setupldr"
  13. #define LDR_IMAGE_SIZE 0x80000
  14. #define CSRSS_IMAGE_NAME "csrss.exe"
  15. #define LSASS_IMAGE_NAME "lsass.exe"
  16. #define SERVICES_IMAGE_NAME "services.exe"
  17. void
  18. RestrictModNameChars(PCSTR ModName, PSTR RewriteBuffer)
  19. {
  20. PCSTR Scan = ModName;
  21. PSTR Write = RewriteBuffer;
  22. while (*Scan)
  23. {
  24. if ((*Scan < 'a' || *Scan > 'z') &&
  25. (*Scan < 'A' || *Scan > 'Z') &&
  26. (*Scan < '0' || *Scan > '9') &&
  27. *Scan != '_')
  28. {
  29. *Write++ = '_';
  30. }
  31. else
  32. {
  33. *Write++ = *Scan;
  34. }
  35. Scan++;
  36. }
  37. *Write = 0;
  38. }
  39. //----------------------------------------------------------------------------
  40. //
  41. // ProcCorDataAccessServices.
  42. //
  43. //----------------------------------------------------------------------------
  44. ProcCorDataAccessServices::ProcCorDataAccessServices(void)
  45. {
  46. m_Process = NULL;
  47. }
  48. STDMETHODIMP
  49. ProcCorDataAccessServices::QueryInterface(
  50. THIS_
  51. IN REFIID InterfaceId,
  52. OUT PVOID* Interface
  53. )
  54. {
  55. if (DbgIsEqualIID(InterfaceId, IID_IUnknown) ||
  56. DbgIsEqualIID(InterfaceId, __uuidof(ICorDataAccessServices)))
  57. {
  58. *Interface = (ICorDataAccessServices*)this;
  59. // No need to refcount as this class is contained.
  60. return S_OK;
  61. }
  62. else
  63. {
  64. *Interface = NULL;
  65. return E_NOINTERFACE;
  66. }
  67. }
  68. STDMETHODIMP_(ULONG)
  69. ProcCorDataAccessServices::AddRef(
  70. THIS
  71. )
  72. {
  73. // No need to refcount as this class is contained.
  74. return 1;
  75. }
  76. STDMETHODIMP_(ULONG)
  77. ProcCorDataAccessServices::Release(
  78. THIS
  79. )
  80. {
  81. // No need to refcount as this class is contained.
  82. return 0;
  83. }
  84. HRESULT STDMETHODCALLTYPE
  85. ProcCorDataAccessServices::GetMachineType(
  86. /* [out] */ ULONG32 *machine)
  87. {
  88. *machine = m_Process->m_Target->m_MachineType;
  89. return S_OK;
  90. }
  91. HRESULT STDMETHODCALLTYPE
  92. ProcCorDataAccessServices::GetPointerSize(
  93. /* [out] */ ULONG32 *size)
  94. {
  95. *size = m_Process->m_Target->m_Machine->m_Ptr64 ? 8 : 4;
  96. return S_OK;
  97. }
  98. HRESULT STDMETHODCALLTYPE
  99. ProcCorDataAccessServices::GetImageBase(
  100. /* [string][in] */ LPCWSTR name,
  101. /* [out] */ CORDATA_ADDRESS *base)
  102. {
  103. HRESULT Status;
  104. PSTR Ansi;
  105. INAME WhichName;
  106. ImageInfo* Image;
  107. if ((Status = WideToAnsi(name, &Ansi)) != S_OK)
  108. {
  109. return Status;
  110. }
  111. if (PathTail(Ansi) != Ansi)
  112. {
  113. WhichName = INAME_IMAGE_PATH;
  114. }
  115. else
  116. {
  117. WhichName = INAME_IMAGE_PATH_TAIL;
  118. }
  119. if (Image = m_Process->FindImageByName(Ansi, 0, WhichName, FALSE))
  120. {
  121. *base = Image->m_BaseOfImage;
  122. Status = S_OK;
  123. }
  124. else
  125. {
  126. Status = E_NOINTERFACE;
  127. }
  128. FreeAnsi(Ansi);
  129. return Status;
  130. }
  131. HRESULT STDMETHODCALLTYPE
  132. ProcCorDataAccessServices::ReadVirtual(
  133. /* [in] */ CORDATA_ADDRESS address,
  134. /* [length_is][size_is][out] */ PBYTE buffer,
  135. /* [in] */ ULONG32 request,
  136. /* [optional][out] */ ULONG32 *done)
  137. {
  138. return m_Process->m_Target->
  139. ReadVirtual(m_Process, address, buffer, request, (PULONG)done);
  140. }
  141. HRESULT STDMETHODCALLTYPE
  142. ProcCorDataAccessServices::WriteVirtual(
  143. /* [in] */ CORDATA_ADDRESS address,
  144. /* [size_is][in] */ PBYTE buffer,
  145. /* [in] */ ULONG32 request,
  146. /* [optional][out] */ ULONG32 *done)
  147. {
  148. return m_Process->m_Target->
  149. WriteVirtual(m_Process, address, buffer, request, (PULONG)done);
  150. }
  151. HRESULT STDMETHODCALLTYPE
  152. ProcCorDataAccessServices::GetTlsValue(
  153. /* [in] */ ULONG32 index,
  154. /* [out] */ CORDATA_ADDRESS* value)
  155. {
  156. HRESULT Status;
  157. ULONG64 SlotAddr;
  158. if ((Status = m_Process->m_CurrentThread->
  159. GetTlsSlotAddress((ULONG)index, &SlotAddr)) != S_OK)
  160. {
  161. return Status;
  162. }
  163. return m_Process->m_Target->
  164. ReadPointer(m_Process, m_Process->m_Target->m_Machine,
  165. SlotAddr, value);
  166. }
  167. HRESULT STDMETHODCALLTYPE
  168. ProcCorDataAccessServices::SetTlsValue(
  169. /* [in] */ ULONG32 index,
  170. /* [in] */ CORDATA_ADDRESS value)
  171. {
  172. HRESULT Status;
  173. ULONG64 SlotAddr;
  174. if ((Status = m_Process->m_CurrentThread->
  175. GetTlsSlotAddress((ULONG)index, &SlotAddr)) != S_OK)
  176. {
  177. return Status;
  178. }
  179. return m_Process->m_Target->
  180. WritePointer(m_Process, m_Process->m_Target->m_Machine,
  181. SlotAddr, value);
  182. }
  183. HRESULT STDMETHODCALLTYPE
  184. ProcCorDataAccessServices::GetCurrentThreadId(
  185. /* [out] */ ULONG32* threadId)
  186. {
  187. *threadId = g_Thread->m_SystemId;
  188. return S_OK;
  189. }
  190. HRESULT STDMETHODCALLTYPE
  191. ProcCorDataAccessServices::GetThreadContext(
  192. /* [in] */ ULONG32 threadId,
  193. /* [in] */ ULONG32 contextFlags,
  194. /* [in] */ ULONG32 contextSize,
  195. /* [out, size_is(contextSize)] */ PBYTE context)
  196. {
  197. HRESULT Status;
  198. if (contextSize < m_Process->m_Target->m_TypeInfo.SizeTargetContext)
  199. {
  200. return E_INVALIDARG;
  201. }
  202. ThreadInfo* Thread = m_Process->FindThreadBySystemId(threadId);
  203. if (!Thread)
  204. {
  205. return E_NOINTERFACE;
  206. }
  207. m_Process->m_Target->ChangeRegContext(Thread);
  208. if ((Status = m_Process->m_Target->m_Machine->
  209. GetContextState(MCTX_CONTEXT)) == S_OK)
  210. {
  211. Status = m_Process->m_Target->m_Machine->
  212. ConvertContextTo(&m_Process->m_Target->m_Machine->m_Context,
  213. m_Process->m_Target->m_SystemVersion,
  214. m_Process->m_Target->m_TypeInfo.SizeTargetContext,
  215. context);
  216. }
  217. m_Process->m_Target->ChangeRegContext(m_Process->m_CurrentThread);
  218. return Status;
  219. }
  220. HRESULT STDMETHODCALLTYPE
  221. ProcCorDataAccessServices::SetThreadContext(
  222. /* [in] */ ULONG32 threadId,
  223. /* [in] */ ULONG32 contextSize,
  224. /* [out, size_is(contextSize)] */ PBYTE context)
  225. {
  226. HRESULT Status;
  227. if (contextSize < m_Process->m_Target->m_TypeInfo.SizeTargetContext)
  228. {
  229. return E_INVALIDARG;
  230. }
  231. ThreadInfo* Thread = m_Process->FindThreadBySystemId(threadId);
  232. if (!Thread)
  233. {
  234. return E_NOINTERFACE;
  235. }
  236. m_Process->m_Target->ChangeRegContext(Thread);
  237. if ((Status = m_Process->m_Target->m_Machine->
  238. GetContextState(MCTX_DIRTY)) == S_OK)
  239. {
  240. Status = m_Process->m_Target->m_Machine->
  241. ConvertContextFrom(&m_Process->m_Target->m_Machine->m_Context,
  242. m_Process->m_Target->m_SystemVersion,
  243. m_Process->m_Target->
  244. m_TypeInfo.SizeTargetContext,
  245. context);
  246. if (Status == S_OK)
  247. {
  248. NotifyChangeDebuggeeState(DEBUG_CDS_REGISTERS, DEBUG_ANY_ID);
  249. }
  250. }
  251. m_Process->m_Target->ChangeRegContext(m_Process->m_CurrentThread);
  252. return Status;
  253. }
  254. //----------------------------------------------------------------------------
  255. //
  256. // ProcessInfo.
  257. //
  258. //----------------------------------------------------------------------------
  259. ProcessInfo::ProcessInfo(TargetInfo* Target,
  260. ULONG SystemId,
  261. HANDLE SymHandle,
  262. ULONG64 SysHandle,
  263. ULONG Flags,
  264. ULONG Options)
  265. {
  266. m_Target = Target;
  267. m_UserId = FindNextUserId(LAYER_PROCESS);
  268. m_Next = NULL;
  269. m_NumImages = 0;
  270. m_NumUnloadedModules = 0;
  271. m_ImageHead = NULL;
  272. m_ExecutableImage = NULL;
  273. m_SynthesizedImage = NULL;
  274. m_NumThreads = 0;
  275. m_ThreadHead = NULL;
  276. m_CurrentThread = NULL;
  277. m_SystemId = SystemId;
  278. m_Exited = FALSE;
  279. m_ModulesLoaded = FALSE;
  280. m_InitialBreakDone = (Flags & ENG_PROC_NO_INITIAL_BREAK) != 0;
  281. // Always ask for an "initial" break when the process
  282. // won't generate its own initial break as the first
  283. // break encountered will just be a normal break and
  284. // so should cause a break-in.
  285. m_InitialBreak =
  286. (Flags & ENG_PROC_NO_INITIAL_BREAK) ||
  287. IS_KERNEL_TARGET(m_Target) ||
  288. (g_EngOptions & DEBUG_ENGOPT_INITIAL_BREAK) != 0;
  289. m_InitialBreakWx86 =
  290. (g_EngOptions & DEBUG_ENGOPT_INITIAL_BREAK) != 0;
  291. m_DataOffset = 0;
  292. m_SymHandle = SymHandle;
  293. m_SysHandle = SysHandle;
  294. m_Flags = Flags;
  295. m_Options = Options;
  296. m_NumBreakpoints = 0;
  297. m_Breakpoints = NULL;
  298. m_BreakpointsTail = NULL;
  299. m_DynFuncTableList = 0;
  300. m_OopFuncTableDlls = NULL;
  301. m_RtlUnloadList = 0;
  302. ResetImplicitData();
  303. m_CorImage = NULL;
  304. m_CorImageType = COR_DLL_INVALID;
  305. m_CorDebugDll = NULL;
  306. m_CorAccess = NULL;
  307. m_CorServices.m_Process = this;
  308. m_VirtualCache.SetProcess(this);
  309. PCHAR CacheEnv = getenv("_NT_DEBUG_CACHE_SIZE");
  310. if (CacheEnv != NULL)
  311. {
  312. m_VirtualCache.m_MaxSize = atol(CacheEnv);
  313. }
  314. m_VirtualCache.m_DecodePTEs =
  315. IS_KERNEL_TARGET(m_Target) &&
  316. !(m_Target->m_KdVersion.Flags & DBGKD_VERS_FLAG_NOMM);
  317. m_Target->InsertProcess(this);
  318. SymInitialize(m_SymHandle, NULL, FALSE);
  319. SymRegisterCallback64(m_SymHandle, SymbolCallbackFunction,
  320. (ULONG_PTR)this);
  321. if (IS_USER_TARGET(m_Target) &&
  322. m_Target->m_MachineType != IMAGE_FILE_MACHINE_I386)
  323. {
  324. SymRegisterFunctionEntryCallback64
  325. (m_SymHandle, TargetInfo::DynamicFunctionTableCallback,
  326. (ULONG_PTR)this);
  327. }
  328. SetSymbolSearchPath(this);
  329. SynthesizeSymbols();
  330. }
  331. ProcessInfo::~ProcessInfo(void)
  332. {
  333. ClearOopFuncTableDlls();
  334. RELEASE(m_CorAccess);
  335. if (m_CorDebugDll)
  336. {
  337. FreeLibrary(m_CorDebugDll);
  338. }
  339. while (m_ThreadHead)
  340. {
  341. delete m_ThreadHead;
  342. }
  343. // Suppress notifications until all images are deleted.
  344. g_EngNotify++;
  345. while (m_ImageHead)
  346. {
  347. delete m_ImageHead;
  348. }
  349. delete m_SynthesizedImage;
  350. // Notification can use process information so put things
  351. // in a clean state before notify.
  352. m_SynthesizedImage = NULL;
  353. g_EngNotify--;
  354. NotifyChangeSymbolState(DEBUG_CSS_UNLOADS, 0, this);
  355. SymCleanup(m_SymHandle);
  356. RemoveProcessBreakpoints(this);
  357. if (m_Flags & ENG_PROC_THREAD_CLOSE_HANDLE)
  358. {
  359. DBG_ASSERT(IS_LIVE_USER_TARGET(m_Target) &&
  360. ((LiveUserTargetInfo*)m_Target)->m_Services);
  361. ((LiveUserTargetInfo*)m_Target)->m_Services->
  362. CloseHandle(m_SysHandle);
  363. }
  364. m_Target->RemoveProcess(this);
  365. g_UserIdFragmented[LAYER_PROCESS]++;
  366. if (this == g_Process)
  367. {
  368. g_Process = NULL;
  369. }
  370. if (this == g_EventProcess)
  371. {
  372. g_EventProcess = NULL;
  373. DiscardLastEvent();
  374. }
  375. if (g_StepTraceBp && g_StepTraceBp->m_Process == this)
  376. {
  377. g_StepTraceBp->m_Process = NULL;
  378. if (g_WatchFunctions.IsStarted())
  379. {
  380. g_WatchFunctions.End(NULL);
  381. }
  382. ResetStepTrace();
  383. g_StepTraceBp->m_Flags &= ~(DEBUG_BREAKPOINT_ENABLED |
  384. BREAKPOINT_INSERTED);
  385. }
  386. if (g_ScopeBuffer.State == ScopeFromContext &&
  387. g_ScopeBuffer.Process == this)
  388. {
  389. ResetCurrentScopeLazy();
  390. }
  391. }
  392. ThreadInfo*
  393. ProcessInfo::FindThreadByUserId(ULONG Id)
  394. {
  395. ThreadInfo* Thread;
  396. ForProcessThreads(this)
  397. {
  398. if (Thread->m_UserId == Id)
  399. {
  400. return Thread;
  401. }
  402. }
  403. return NULL;
  404. }
  405. ThreadInfo*
  406. ProcessInfo::FindThreadBySystemId(ULONG Id)
  407. {
  408. ThreadInfo* Thread;
  409. ForProcessThreads(this)
  410. {
  411. if (Thread->m_SystemId == Id)
  412. {
  413. return Thread;
  414. }
  415. }
  416. return NULL;
  417. }
  418. ThreadInfo*
  419. ProcessInfo::FindThreadByHandle(ULONG64 Handle)
  420. {
  421. ThreadInfo* Thread;
  422. ForProcessThreads(this)
  423. {
  424. if (Thread->m_Handle == Handle)
  425. {
  426. return Thread;
  427. }
  428. }
  429. return NULL;
  430. }
  431. void
  432. ProcessInfo::InsertThread(ThreadInfo* Thread)
  433. {
  434. ThreadInfo* Cur;
  435. ThreadInfo* Prev;
  436. Prev = NULL;
  437. for (Cur = m_ThreadHead; Cur; Cur = Cur->m_Next)
  438. {
  439. if (Cur->m_UserId > Thread->m_UserId)
  440. {
  441. break;
  442. }
  443. Prev = Cur;
  444. }
  445. Thread->m_Next = Cur;
  446. if (!Prev)
  447. {
  448. m_ThreadHead = Thread;
  449. }
  450. else
  451. {
  452. Prev->m_Next = Thread;
  453. }
  454. m_NumThreads++;
  455. Thread->m_Process = this;
  456. if (!m_CurrentThread)
  457. {
  458. m_CurrentThread = Thread;
  459. }
  460. m_Target->AddThreadToAllProcessInfo(this, Thread);
  461. }
  462. void
  463. ProcessInfo::RemoveThread(ThreadInfo* Thread)
  464. {
  465. ThreadInfo* Cur;
  466. ThreadInfo* Prev;
  467. Prev = NULL;
  468. for (Cur = m_ThreadHead; Cur; Cur = Cur->m_Next)
  469. {
  470. if (Cur == Thread)
  471. {
  472. break;
  473. }
  474. Prev = Cur;
  475. }
  476. if (!Cur)
  477. {
  478. return;
  479. }
  480. if (!Prev)
  481. {
  482. m_ThreadHead = Thread->m_Next;
  483. }
  484. else
  485. {
  486. Prev->m_Next = Thread->m_Next;
  487. }
  488. m_NumThreads--;
  489. Thread->m_Process = NULL;
  490. if (m_CurrentThread == Thread)
  491. {
  492. m_CurrentThread = m_ThreadHead;
  493. }
  494. m_Target->RemoveThreadFromAllProcessInfo(this, Thread);
  495. }
  496. HRESULT
  497. ProcessInfo::CreateVirtualThreads(ULONG StartId, ULONG Threads)
  498. {
  499. ThreadInfo* Thread;
  500. while (Threads-- > 0)
  501. {
  502. Thread = new ThreadInfo(this, VIRTUAL_THREAD_ID(StartId), 0,
  503. VIRTUAL_THREAD_HANDLE(StartId), 0, 0);
  504. if (!Thread)
  505. {
  506. return E_OUTOFMEMORY;
  507. }
  508. StartId++;
  509. }
  510. return S_OK;
  511. }
  512. ImageInfo*
  513. ProcessInfo::FindImageByIndex(ULONG Index)
  514. {
  515. ImageInfo* Image = m_ImageHead;
  516. while (Index > 0 && Image != NULL)
  517. {
  518. Index--;
  519. Image = Image->m_Next;
  520. }
  521. return Image;
  522. }
  523. ImageInfo*
  524. ProcessInfo::FindImageByOffset(ULONG64 Offset, BOOL AllowSynth)
  525. {
  526. ImageInfo* Image = m_ImageHead;
  527. while (Image != NULL &&
  528. (Offset < Image->m_BaseOfImage ||
  529. Offset >= Image->m_BaseOfImage + Image->m_SizeOfImage))
  530. {
  531. Image = Image->m_Next;
  532. }
  533. //
  534. // If synthesized symbols are allowed, check those images
  535. // also.
  536. //
  537. if (!Image &&
  538. AllowSynth &&
  539. m_SynthesizedImage &&
  540. Offset >= m_SynthesizedImage->m_BaseOfImage &&
  541. Offset < m_SynthesizedImage->m_BaseOfImage +
  542. m_SynthesizedImage->m_SizeOfImage)
  543. {
  544. Image = m_SynthesizedImage;
  545. }
  546. return Image;
  547. }
  548. ImageInfo*
  549. ProcessInfo::FindImageByName(PCSTR Name, ULONG NameChars,
  550. INAME Which, BOOL AllowSynth)
  551. {
  552. if (NameChars == 0)
  553. {
  554. NameChars = strlen(Name);
  555. }
  556. ImageInfo* Image = m_ImageHead;
  557. while (Image != NULL)
  558. {
  559. PCSTR WhichStr;
  560. switch(Which)
  561. {
  562. case INAME_IMAGE_PATH:
  563. WhichStr = Image->m_ImagePath;
  564. break;
  565. case INAME_IMAGE_PATH_TAIL:
  566. WhichStr = PathTail(Image->m_ImagePath);
  567. break;
  568. case INAME_MODULE:
  569. if (Image->m_OriginalModuleName[0] &&
  570. strlen(Image->m_OriginalModuleName) == NameChars &&
  571. !_memicmp(Image->m_OriginalModuleName, Name, NameChars))
  572. {
  573. return Image;
  574. }
  575. WhichStr = Image->m_ModuleName;
  576. break;
  577. }
  578. if (strlen(WhichStr) == NameChars &&
  579. _memicmp(WhichStr, Name, NameChars) == 0)
  580. {
  581. break;
  582. }
  583. Image = Image->m_Next;
  584. }
  585. //
  586. // If synthesized symbols are allowed, check those images
  587. // also.
  588. //
  589. if (!Image &&
  590. AllowSynth &&
  591. m_SynthesizedImage &&
  592. Which == INAME_MODULE &&
  593. strlen(m_SynthesizedImage->m_ModuleName) == NameChars &&
  594. !_memicmp(m_SynthesizedImage->m_ModuleName, Name, NameChars))
  595. {
  596. Image = m_SynthesizedImage;
  597. }
  598. return Image;
  599. }
  600. BOOL
  601. ProcessInfo::GetOffsetFromMod(PCSTR String, PULONG64 Offset)
  602. {
  603. if (!strchr(String, '!'))
  604. {
  605. ULONG Len;
  606. BOOL End;
  607. //
  608. // Could be a module name or module$ for the end
  609. // of a module.
  610. //
  611. Len = strlen(String);
  612. if (Len == 0)
  613. {
  614. return FALSE;
  615. }
  616. if (String[Len - 1] == '$')
  617. {
  618. // Retrieving end-of-module.
  619. Len--;
  620. End = TRUE;
  621. }
  622. else
  623. {
  624. End = FALSE;
  625. }
  626. ImageInfo* Image = FindImageByName(String, Len, INAME_MODULE, TRUE);
  627. if (Image)
  628. {
  629. if (End)
  630. {
  631. *Offset = Image->m_BaseOfImage + Image->m_SizeOfImage;
  632. }
  633. else
  634. {
  635. *Offset = Image->m_BaseOfImage;
  636. }
  637. return TRUE;
  638. }
  639. }
  640. return FALSE;
  641. }
  642. COR_DLL
  643. IsCorDll(PCSTR ImagePath)
  644. {
  645. PCSTR ImagePathTail = PathTail(ImagePath);
  646. if (!_stricmp(ImagePathTail, "mscoree.dll"))
  647. {
  648. return COR_DLL_EE;
  649. }
  650. if (!_stricmp(ImagePathTail, "mscorwks.dll"))
  651. {
  652. return COR_DLL_WKS;
  653. }
  654. if (!_stricmp(ImagePathTail, "mscorsvr.dll"))
  655. {
  656. return COR_DLL_SVR;
  657. }
  658. return COR_DLL_INVALID;
  659. }
  660. void
  661. ProcessInfo::InsertImage(ImageInfo* Image)
  662. {
  663. ImageInfo* Cur;
  664. ImageInfo* Prev;
  665. Prev = NULL;
  666. for (Cur = m_ImageHead; Cur; Cur = Cur->m_Next)
  667. {
  668. if (Cur->m_BaseOfImage > Image->m_BaseOfImage)
  669. {
  670. break;
  671. }
  672. Prev = Cur;
  673. }
  674. Image->m_Next = Cur;
  675. if (!Prev)
  676. {
  677. m_ImageHead = Image;
  678. }
  679. else
  680. {
  681. Prev->m_Next = Image;
  682. }
  683. m_NumImages++;
  684. Image->m_Process = this;
  685. Image->m_Linked = TRUE;
  686. if (m_ExecutableImage == NULL)
  687. {
  688. // Try and locate the executable image entry for
  689. // the process to use as the process's name.
  690. ULONG NameLen = strlen(Image->m_ImagePath);
  691. if (NameLen > 4 &&
  692. !_stricmp(Image->m_ImagePath + NameLen - 4, ".exe"))
  693. {
  694. m_ExecutableImage = Image;
  695. }
  696. }
  697. COR_DLL CorDll = IsCorDll(Image->m_ImagePath);
  698. if (CorDll > m_CorImageType)
  699. {
  700. m_CorImage = Image;
  701. m_CorImageType = CorDll;
  702. }
  703. }
  704. void
  705. ProcessInfo::RemoveImage(ImageInfo* Image)
  706. {
  707. ImageInfo* Cur;
  708. ImageInfo* Prev;
  709. Prev = NULL;
  710. for (Cur = m_ImageHead; Cur; Cur = Cur->m_Next)
  711. {
  712. if (Cur == Image)
  713. {
  714. break;
  715. }
  716. Prev = Cur;
  717. }
  718. if (!Cur)
  719. {
  720. return;
  721. }
  722. if (!Prev)
  723. {
  724. m_ImageHead = Image->m_Next;
  725. }
  726. else
  727. {
  728. Prev->m_Next = Image->m_Next;
  729. }
  730. m_NumImages--;
  731. Image->m_Process = NULL;
  732. Image->m_Linked = FALSE;
  733. if (m_ExecutableImage == Image)
  734. {
  735. m_ExecutableImage = NULL;
  736. }
  737. if (m_CorImageType != COR_DLL_INVALID &&
  738. IsCorDll(Image->m_ImagePath) != COR_DLL_INVALID)
  739. {
  740. m_CorImage = NULL;
  741. m_CorImageType = COR_DLL_INVALID;
  742. }
  743. }
  744. BOOL
  745. ProcessInfo::DeleteImageByName(PCSTR Name, INAME Which)
  746. {
  747. ImageInfo* Image;
  748. for (Image = m_ImageHead; Image; Image = Image->m_Next)
  749. {
  750. PCSTR WhichStr;
  751. switch(Which)
  752. {
  753. case INAME_IMAGE_PATH:
  754. WhichStr = Image->m_ImagePath;
  755. break;
  756. case INAME_IMAGE_PATH_TAIL:
  757. WhichStr = PathTail(Image->m_ImagePath);
  758. break;
  759. case INAME_MODULE:
  760. WhichStr = Image->m_ModuleName;
  761. break;
  762. }
  763. if (!_stricmp(WhichStr, Name))
  764. {
  765. delete Image;
  766. return TRUE;
  767. }
  768. }
  769. return FALSE;
  770. }
  771. BOOL
  772. ProcessInfo::DeleteImageByBase(ULONG64 BaseOfImage)
  773. {
  774. ImageInfo* Image;
  775. for (Image = m_ImageHead; Image; Image = Image->m_Next)
  776. {
  777. if (Image->m_BaseOfImage == BaseOfImage)
  778. {
  779. delete Image;
  780. return TRUE;
  781. }
  782. }
  783. return FALSE;
  784. }
  785. void
  786. ProcessInfo::DeleteImagesBelowOffset(ULONG64 Offset)
  787. {
  788. ImageInfo* Image, *Next;
  789. ULONG Count = 0;
  790. // Suppress notifications until all images are deleted.
  791. g_EngNotify++;
  792. for (Image = m_ImageHead; Image; Image = Next)
  793. {
  794. Next = Image->m_Next;
  795. if (Image->m_BaseOfImage < Offset)
  796. {
  797. delete Image;
  798. Count++;
  799. }
  800. }
  801. g_EngNotify--;
  802. if (Count)
  803. {
  804. NotifyChangeSymbolState(DEBUG_CSS_UNLOADS, 0, this);
  805. }
  806. }
  807. void
  808. ProcessInfo::DeleteImages(void)
  809. {
  810. // Suppress notifications until all images are deleted.
  811. g_EngNotify++;
  812. while (m_ImageHead)
  813. {
  814. delete m_ImageHead;
  815. }
  816. g_EngNotify--;
  817. NotifyChangeSymbolState(DEBUG_CSS_UNLOADS, 0, this);
  818. }
  819. HRESULT
  820. ProcessInfo::AddImage(PMODULE_INFO_ENTRY ModEntry,
  821. BOOL ForceSymbolLoad,
  822. ImageInfo** ImageAdded)
  823. {
  824. ImageInfo* ImageNew;
  825. IMAGEHLP_MODULE64 SymModInfo;
  826. ULONG64 LoadAddress;
  827. BOOL LoadSymbols = TRUE;
  828. PCSTR ImagePathTail;
  829. MODLOAD_DATA ModLoadData;
  830. HRESULT Status;
  831. BOOL ReusedExisting = FALSE;
  832. #if DBG_MOD_LIST
  833. dprintf("AddImage:\n"
  834. " ImagePath %s\n"
  835. " File %I64x\n"
  836. " BaseOfImage %I64x\n"
  837. " SizeOfImage %x\n"
  838. " CheckSum %x\n"
  839. " ModuleName %s\n"
  840. " ForceSymbolLoad %d\n",
  841. ModEntry->NamePtr,
  842. (ULONG64)(ULONG_PTR)File,
  843. ModEntry->Base,
  844. ModEntry->Size,
  845. ModEntry->CheckSum,
  846. ModEntry->ModuleName,
  847. ForceSymbolLoad);
  848. #endif
  849. if (ModEntry->NamePtr == NULL)
  850. {
  851. WarnOut("AddImage(NULL) fails\n");
  852. return E_INVALIDARG;
  853. }
  854. if (ModEntry->NamePtr &&
  855. IS_USER_TARGET(m_Target) &&
  856. m_Target->m_PlatformId == VER_PLATFORM_WIN32_NT)
  857. {
  858. TranslateNtPathName(ModEntry->NamePtr);
  859. }
  860. //
  861. // Search for existing image at same base address.
  862. // If found, remove symbols, but leave image structure intact.
  863. //
  864. for (ImageNew = m_ImageHead; ImageNew; ImageNew = ImageNew->m_Next)
  865. {
  866. if (ImageNew->m_BaseOfImage == ModEntry->Base)
  867. {
  868. VerbOut("Force unload of %s\n", ImageNew->m_ImagePath);
  869. ImageNew->DeleteResources(FALSE);
  870. break;
  871. }
  872. }
  873. //
  874. // If we didn't reuse an existing image, allocate
  875. // a new one.
  876. //
  877. if (!ImageNew)
  878. {
  879. ImageNew = new ImageInfo(this,
  880. ModEntry->NamePtr, ModEntry->Base, TRUE);
  881. if (ImageNew == NULL)
  882. {
  883. ErrOut("Unable to allocate memory for %s symbols.\n",
  884. ModEntry->NamePtr);
  885. return E_OUTOFMEMORY;
  886. }
  887. // Module name is set later after possible renaming.
  888. ImageNew->m_File = ModEntry->File;
  889. ImageNew->m_CheckSum = ModEntry->CheckSum;
  890. ImageNew->m_TimeDateStamp = ModEntry->TimeDateStamp;
  891. ImageNew->m_SymState = ISS_MATCHED;
  892. ImageNew->m_UserMode = ModEntry->UserMode;
  893. }
  894. else
  895. {
  896. ReusedExisting = TRUE;
  897. // Update the reused entry with the latest information.
  898. if (ModEntry->NamePtr)
  899. {
  900. CopyString(ImageNew->m_ImagePath, ModEntry->NamePtr,
  901. DIMA(ImageNew->m_ImagePath));
  902. }
  903. else
  904. {
  905. ImageNew->m_ImagePath[0] = 0;
  906. }
  907. }
  908. // Always update the entry size as this allows users
  909. // to update explicit entries (.reload image.ext=base,size)
  910. // without having to unload them first.
  911. ImageNew->m_SizeOfImage = ModEntry->Size;
  912. ImagePathTail = PathTail(ImageNew->m_ImagePath);
  913. if (ForceSymbolLoad)
  914. {
  915. // Try to load the image memory right away in this
  916. // case to catch incomplete-information errors.
  917. if (!ImageNew->DemandLoadImageMemory(!ReusedExisting, TRUE))
  918. {
  919. if (!ReusedExisting)
  920. {
  921. g_EngNotify++;
  922. delete ImageNew;
  923. g_EngNotify--;
  924. }
  925. return E_OUTOFMEMORY;
  926. }
  927. }
  928. if (IS_KERNEL_TARGET(m_Target))
  929. {
  930. CHAR Buf[MAX_IMAGE_PATH];
  931. MODULE_ALIAS_LIST* ModAlias;
  932. //
  933. // Determine the actual image name for kernel images which
  934. // are known to have multiple identities.
  935. //
  936. if ((ModEntry->ModuleName &&
  937. _stricmp(ModEntry->ModuleName, KERNEL_MODULE_NAME) == 0) ||
  938. ModEntry->Base == m_Target->m_KdDebuggerData.KernBase)
  939. {
  940. ModAlias = &g_AliasLists[MODALIAS_KERNEL];
  941. }
  942. else
  943. {
  944. ModAlias = FindModuleAliasList(ImagePathTail, NULL);
  945. }
  946. if (ModAlias)
  947. {
  948. if (GetModnameFromImage(this, ModEntry->Base, NULL,
  949. Buf, sizeof(Buf), FALSE))
  950. {
  951. CopyString(ImageNew->m_ImagePath, Buf,
  952. DIMA(ImageNew->m_ImagePath));
  953. }
  954. ModEntry->ModuleName = (PSTR)ModAlias->BaseModule;
  955. }
  956. else if (ImageNew->m_SizeOfImage == 0 &&
  957. ((_stricmp(ImagePathTail, NTLDR_IMAGE_NAME) == 0) ||
  958. (_stricmp(ImagePathTail, NTLDR_IMAGE_NAME ".exe") == 0) ||
  959. (_stricmp(ImagePathTail, OSLOADER_IMAGE_NAME) == 0) ||
  960. (_stricmp(ImagePathTail, OSLOADER_IMAGE_NAME ".exe") == 0) ||
  961. (_stricmp(ImagePathTail, SETUPLDR_IMAGE_NAME) == 0) ||
  962. (_stricmp(ImagePathTail, SETUPLDR_IMAGE_NAME ".exe") == 0)))
  963. {
  964. ImageNew->m_SizeOfImage = LDR_IMAGE_SIZE;
  965. }
  966. }
  967. else if (!IS_DUMP_TARGET(m_Target))
  968. {
  969. //
  970. // When debugging CSR, LSA or Services.exe, force the use of local-only
  971. // symbols. Otherwise we can deadlock the entire machine when trying
  972. // to load the symbol file from the network.
  973. //
  974. if (((LiveUserTargetInfo*)m_Target)->m_Local &&
  975. (_stricmp(ImagePathTail, CSRSS_IMAGE_NAME) == 0 ||
  976. _stricmp(ImagePathTail, LSASS_IMAGE_NAME) == 0 ||
  977. _stricmp(ImagePathTail, SERVICES_IMAGE_NAME) == 0))
  978. {
  979. if (g_EngOptions & DEBUG_ENGOPT_ALLOW_NETWORK_PATHS)
  980. {
  981. //
  982. // Since the user has chambered a round and pointed the barrel
  983. // of the gun at his head, we may as well tell him that it's
  984. // going to hurt if he pulls the trigger.
  985. //
  986. WarnOut("WARNING: Using network symbols with %s\n",
  987. ImagePathTail);
  988. WarnOut("WARNING: You may deadlock your machine.\n");
  989. }
  990. else
  991. {
  992. g_EngOptions |= DEBUG_ENGOPT_DISALLOW_NETWORK_PATHS;
  993. }
  994. }
  995. if (g_EngOptions & DEBUG_ENGOPT_DISALLOW_NETWORK_PATHS)
  996. {
  997. DWORD NetPath;
  998. NetPath = NetworkPathCheck(g_SymbolSearchPath);
  999. if (NetPath == ERROR_FILE_OFFLINE)
  1000. {
  1001. ErrOut("ERROR: sympath contained network references but "
  1002. "they were not allowed.\n");
  1003. ErrOut("Symbols not loaded for %s\n",
  1004. ImagePathTail);
  1005. LoadSymbols = FALSE;
  1006. }
  1007. else if (NetPath == ERROR_BAD_PATHNAME)
  1008. {
  1009. VerbOut("WARNING: sympath contains invalid references.\n");
  1010. }
  1011. }
  1012. }
  1013. if (ModEntry->ModuleName == NULL)
  1014. {
  1015. CreateModuleNameFromPath(ImageNew->m_ImagePath,
  1016. ImageNew->m_ModuleName);
  1017. RestrictModNameChars(ImageNew->m_ModuleName, ImageNew->m_ModuleName);
  1018. strcpy(ImageNew->m_OriginalModuleName, ImageNew->m_ModuleName);
  1019. }
  1020. else
  1021. {
  1022. RestrictModNameChars(ModEntry->ModuleName, ImageNew->m_ModuleName);
  1023. //
  1024. // We have an alias, so keep original module name from path
  1025. //
  1026. CreateModuleNameFromPath(ImageNew->m_ImagePath,
  1027. ImageNew->m_OriginalModuleName);
  1028. RestrictModNameChars(ImageNew->m_OriginalModuleName,
  1029. ImageNew->m_OriginalModuleName);
  1030. }
  1031. //
  1032. // Check for duplicate module names and
  1033. // image overlaps.
  1034. //
  1035. ImageInfo* Check;
  1036. for (Check = m_ImageHead; Check != NULL; Check = Check->m_Next)
  1037. {
  1038. if (Check != ImageNew &&
  1039. !_strcmpi(ImageNew->m_ModuleName, Check->m_ModuleName))
  1040. {
  1041. int Len = strlen(ImageNew->m_ModuleName);
  1042. // Module names match, so qualify with the base address.
  1043. // Resulting name must be unique since base addresses are.
  1044. if (m_Target->m_Machine->m_Ptr64)
  1045. {
  1046. if (Len >= MAX_MODULE - 17)
  1047. {
  1048. Len = MAX_MODULE - 18;
  1049. }
  1050. sprintf(ImageNew->m_ModuleName + Len, "_%I64x",
  1051. ModEntry->Base);
  1052. }
  1053. else
  1054. {
  1055. if (Len >= MAX_MODULE - 9)
  1056. {
  1057. Len = MAX_MODULE - 10;
  1058. }
  1059. sprintf(ImageNew->m_ModuleName + Len, "_%x",
  1060. (ULONG)ModEntry->Base);
  1061. }
  1062. // Force all references to this module to be
  1063. // through the exact module name and not through
  1064. // an original name that may have been ambiguous.
  1065. ImageNew->m_OriginalModuleName[0] = 0;
  1066. }
  1067. if (Check != ImageNew &&
  1068. ImageNew->m_BaseOfImage <
  1069. Check->m_BaseOfImage + Check->m_SizeOfImage &&
  1070. Check->m_BaseOfImage <
  1071. ImageNew->m_BaseOfImage + ImageNew->m_SizeOfImage)
  1072. {
  1073. WarnOut("WARNING: %s overlaps %s\n",
  1074. ImageNew->m_ModuleName,
  1075. Check->m_ModuleName);
  1076. }
  1077. }
  1078. //
  1079. // If we do not want to load symbolic information, just return here.
  1080. //
  1081. if (!LoadSymbols)
  1082. {
  1083. *ImageAdded = ImageNew;
  1084. return S_OK;
  1085. }
  1086. if (ModEntry->DebugHeader)
  1087. {
  1088. ModLoadData.ssize = sizeof(ModLoadData);
  1089. ModLoadData.ssig = DBHHEADER_DEBUGDIRS;
  1090. ModLoadData.data = ModEntry->DebugHeader;
  1091. ModLoadData.size = ModEntry->SizeOfDebugHeader;
  1092. ModLoadData.flags = 0;
  1093. }
  1094. LoadAddress = SymLoadModuleEx(m_SymHandle,
  1095. ImageNew->m_File,
  1096. PrepareImagePath(ImageNew->m_ImagePath),
  1097. ImageNew->m_ModuleName,
  1098. ImageNew->m_BaseOfImage,
  1099. ImageNew->m_SizeOfImage,
  1100. ModEntry->DebugHeader ? &ModLoadData : NULL,
  1101. 0);
  1102. if (!LoadAddress)
  1103. {
  1104. Status = WIN32_LAST_STATUS();
  1105. VerbOut("SymLoadModule(%N, %N, \"%s\", \"%s\", %s, %x) fails\n",
  1106. m_SymHandle,
  1107. ImageNew->m_File,
  1108. ImageNew->m_ImagePath,
  1109. ImageNew->m_ModuleName,
  1110. FormatAddr64(ImageNew->m_BaseOfImage),
  1111. ImageNew->m_SizeOfImage);
  1112. // We don't want deletion to notify of a symbol change
  1113. // if this is a partially newly created image.
  1114. if (!ReusedExisting)
  1115. {
  1116. g_EngNotify++;
  1117. }
  1118. delete ImageNew;
  1119. if (!ReusedExisting)
  1120. {
  1121. g_EngNotify--;
  1122. }
  1123. return Status;
  1124. }
  1125. if (!ImageNew->m_BaseOfImage)
  1126. {
  1127. ImageNew->m_BaseOfImage = LoadAddress;
  1128. }
  1129. if (ForceSymbolLoad)
  1130. {
  1131. SymLoadModule64(m_SymHandle,
  1132. NULL,
  1133. NULL,
  1134. NULL,
  1135. ImageNew->m_BaseOfImage,
  1136. 0);
  1137. }
  1138. SymModInfo.SizeOfStruct = sizeof(SymModInfo);
  1139. if (SymGetModuleInfo64(m_SymHandle,
  1140. ImageNew->m_BaseOfImage, &SymModInfo))
  1141. {
  1142. ImageNew->m_SizeOfImage = SymModInfo.ImageSize;
  1143. }
  1144. else
  1145. {
  1146. Status = WIN32_LAST_STATUS();
  1147. VerbOut("SymGetModuleInfo(%N, %s) fails\n",
  1148. m_SymHandle, FormatAddr64(ImageNew->m_BaseOfImage));
  1149. // We don't want DelImage to notify of a symbol change
  1150. // if this is a partially newly created image.
  1151. if (!ReusedExisting)
  1152. {
  1153. g_EngNotify++;
  1154. }
  1155. delete ImageNew;
  1156. if (!ReusedExisting)
  1157. {
  1158. g_EngNotify--;
  1159. }
  1160. return Status;
  1161. }
  1162. if (ModEntry->ImageMachineTypeValid)
  1163. {
  1164. ImageNew->m_MachineType = ModEntry->MachineType;
  1165. }
  1166. StartOutLine(DEBUG_OUTPUT_VERBOSE, OUT_LINE_NO_PREFIX);
  1167. VerbOut("ModLoad: %s %s %-8s\n",
  1168. FormatAddr64(ImageNew->m_BaseOfImage),
  1169. FormatAddr64(ImageNew->m_BaseOfImage + ImageNew->m_SizeOfImage),
  1170. ImageNew->m_ImagePath);
  1171. NotifyChangeSymbolState(DEBUG_CSS_LOADS, ImageNew->m_BaseOfImage, this);
  1172. *ImageAdded = ImageNew;
  1173. return S_OK;
  1174. }
  1175. void
  1176. ProcessInfo::SynthesizeSymbols(void)
  1177. {
  1178. // SynthesizeSymbols can result in symbol
  1179. // callbacks but the symbols involved aren't real symbols
  1180. // so suppress notifications.
  1181. g_EngNotify++;
  1182. if (m_Target->m_TypeInfo.UmSharedUserDataOffset)
  1183. {
  1184. //
  1185. // Create a fake module for the shared user
  1186. // data area. Add a symbol for the system
  1187. // call stub there if a stub exists.
  1188. //
  1189. ImageInfo* Image;
  1190. Image = new ImageInfo(this, "SharedUserData",
  1191. m_Target->m_TypeInfo.UmSharedUserDataOffset,
  1192. FALSE);
  1193. if (!Image)
  1194. {
  1195. WarnOut("Unable to create shared user data image\n");
  1196. }
  1197. else
  1198. {
  1199. Image->m_SizeOfImage = m_Target->m_Machine->m_PageSize;
  1200. strcpy(Image->m_ModuleName, Image->m_ImagePath);
  1201. strcpy(Image->m_OriginalModuleName, Image->m_ImagePath);
  1202. if (!SymLoadModuleEx(m_SymHandle, NULL,
  1203. Image->m_ImagePath,
  1204. Image->m_ModuleName, Image->m_BaseOfImage,
  1205. Image->m_SizeOfImage, NULL, SLMFLAG_VIRTUAL))
  1206. {
  1207. WarnOut("Unable to add shared user data module\n");
  1208. delete Image;
  1209. }
  1210. else if (m_Target->m_TypeInfo.UmSharedSysCallOffset &&
  1211. !SymAddSymbol(m_SymHandle,
  1212. Image->m_BaseOfImage,
  1213. "SystemCallStub",
  1214. m_Target->m_TypeInfo.UmSharedSysCallOffset,
  1215. m_Target->m_TypeInfo.UmSharedSysCallSize,
  1216. 0))
  1217. {
  1218. WarnOut("Unable to add system call symbol\n");
  1219. delete Image;
  1220. }
  1221. else
  1222. {
  1223. m_SynthesizedImage = Image;
  1224. }
  1225. }
  1226. }
  1227. g_EngNotify--;
  1228. }
  1229. void
  1230. ProcessInfo::VerifyKernel32Version(void)
  1231. {
  1232. ImageInfo* Image = FindImageByName("kernel32", 8, INAME_MODULE, FALSE);
  1233. if (!Image)
  1234. {
  1235. return;
  1236. }
  1237. //
  1238. // Verify the OS version matches kernel32's image version.
  1239. //
  1240. IMAGE_NT_HEADERS64 NtHeaders;
  1241. if (m_Target->ReadImageNtHeaders(this, Image->m_BaseOfImage,
  1242. &NtHeaders) == S_OK)
  1243. {
  1244. if (NtHeaders.OptionalHeader.MajorImageVersion !=
  1245. m_Target->m_KdVersion.MajorVersion ||
  1246. NtHeaders.OptionalHeader.MinorImageVersion !=
  1247. m_Target->m_KdVersion.MinorVersion)
  1248. {
  1249. WarnOut("WARNING: System version is %d.%d but "
  1250. "kernel32.dll is version %d.%d.\n",
  1251. m_Target->m_KdVersion.MajorVersion,
  1252. m_Target->m_KdVersion.MinorVersion,
  1253. NtHeaders.OptionalHeader.MajorImageVersion,
  1254. NtHeaders.OptionalHeader.MinorImageVersion);
  1255. if (IS_USER_DUMP(m_Target))
  1256. {
  1257. WarnOut("If this dump was generated by userdump.exe on "
  1258. "Windows NT 4.0 the dump\n"
  1259. "version is probably incorrect. "
  1260. "Set DBGENG_FULL_DUMP_VERSION=4.0 in your\n"
  1261. "environment to override the dump version.\n");
  1262. }
  1263. }
  1264. }
  1265. }
  1266. BOOL
  1267. ProcessInfo::DeleteExitedInfos(void)
  1268. {
  1269. ThreadInfo* Thread;
  1270. ThreadInfo* ThreadNext;
  1271. BOOL DeletedSomething = FALSE;
  1272. for (Thread = m_ThreadHead; Thread; Thread = ThreadNext)
  1273. {
  1274. ThreadNext = Thread->m_Next;
  1275. if (Thread->m_Exited)
  1276. {
  1277. delete Thread;
  1278. DeletedSomething = TRUE;
  1279. }
  1280. }
  1281. ImageInfo* Image;
  1282. ImageInfo* ImagePrev;
  1283. ImageInfo* ImageNext;
  1284. ImagePrev = NULL;
  1285. for (Image = m_ImageHead; Image; Image = ImageNext)
  1286. {
  1287. ImageNext = Image->m_Next;
  1288. if (Image->m_Unloaded)
  1289. {
  1290. delete Image;
  1291. DeletedSomething = TRUE;
  1292. }
  1293. else
  1294. {
  1295. ImagePrev = Image;
  1296. }
  1297. }
  1298. return DeletedSomething;
  1299. }
  1300. void
  1301. ProcessInfo::PrepareForExecution(void)
  1302. {
  1303. ThreadInfo* Thread;
  1304. ForProcessThreads(this)
  1305. {
  1306. Thread->PrepareForExecution();
  1307. }
  1308. ResetImplicitData();
  1309. m_VirtualCache.Empty();
  1310. m_VirtualCache.SetForceDecodePtes(FALSE, m_Target);
  1311. FlushCorState();
  1312. }
  1313. void
  1314. ProcessInfo::OutputThreadInfo(ThreadInfo* Match, BOOL Verbose)
  1315. {
  1316. ThreadInfo* Thread;
  1317. Thread = m_ThreadHead;
  1318. while (Thread)
  1319. {
  1320. if (Match == NULL || Match == Thread)
  1321. {
  1322. ULONG64 DataOffset;
  1323. HRESULT Status;
  1324. char CurMark;
  1325. Status =
  1326. m_Target->
  1327. GetThreadInfoDataOffset(Thread, 0, &DataOffset);
  1328. if (Status != S_OK)
  1329. {
  1330. WarnOut("Unable to get thread data for thread %u\n",
  1331. Thread->m_UserId);
  1332. DataOffset = 0;
  1333. }
  1334. if (Thread == g_Thread)
  1335. {
  1336. CurMark = '.';
  1337. }
  1338. else if (Thread == g_EventThread)
  1339. {
  1340. CurMark = '#';
  1341. }
  1342. else
  1343. {
  1344. CurMark = ' ';
  1345. }
  1346. dprintf("%c%3ld Id: %lx.%lx Suspend: %d Teb: %s ",
  1347. CurMark,
  1348. Thread->m_UserId,
  1349. m_SystemId,
  1350. Thread->m_SystemId,
  1351. Thread->m_SuspendCount,
  1352. FormatAddr64(DataOffset));
  1353. if (Thread->m_Frozen)
  1354. {
  1355. dprintf("Frozen ");
  1356. }
  1357. else
  1358. {
  1359. dprintf("Unfrozen");
  1360. }
  1361. if (Thread->m_Name[0])
  1362. {
  1363. dprintf(" \"%s\"", Thread->m_Name);
  1364. }
  1365. dprintf("\n");
  1366. if (Verbose)
  1367. {
  1368. dprintf(" ");
  1369. if (!Thread->m_StartOffset)
  1370. {
  1371. if (m_Target->
  1372. GetThreadStartOffset(Thread,
  1373. &Thread->m_StartOffset) != S_OK)
  1374. {
  1375. Thread->m_StartOffset = 0;
  1376. }
  1377. }
  1378. if (Thread->m_StartOffset)
  1379. {
  1380. dprintf("Start: ");
  1381. OutputSymAddr(Thread->m_StartOffset,
  1382. SYMADDR_FORCE | SYMADDR_OFFSET, NULL);
  1383. }
  1384. dprintf("\n");
  1385. }
  1386. }
  1387. if (CheckUserInterrupt())
  1388. {
  1389. break;
  1390. }
  1391. Thread = Thread->m_Next;
  1392. }
  1393. }
  1394. HRESULT
  1395. ProcessInfo::AddOopFuncTableDll(PWSTR Dll, ULONG64 Handle)
  1396. {
  1397. OUT_OF_PROC_FUNC_TABLE_DLL* OopDll;
  1398. OopDll = (OUT_OF_PROC_FUNC_TABLE_DLL*)
  1399. malloc(sizeof(*OopDll) + (wcslen(Dll) + 1) * sizeof(Dll));
  1400. if (!OopDll)
  1401. {
  1402. return E_OUTOFMEMORY;
  1403. }
  1404. OopDll->Next = m_OopFuncTableDlls;
  1405. m_OopFuncTableDlls = OopDll;
  1406. OopDll->Handle = Handle;
  1407. wcscpy((PWSTR)(OopDll + 1), Dll);
  1408. return S_OK;
  1409. }
  1410. void
  1411. ProcessInfo::ClearOopFuncTableDlls(void)
  1412. {
  1413. while (m_OopFuncTableDlls)
  1414. {
  1415. OUT_OF_PROC_FUNC_TABLE_DLL* OopDll = m_OopFuncTableDlls;
  1416. m_OopFuncTableDlls = OopDll->Next;
  1417. if (IS_LIVE_USER_TARGET(m_Target))
  1418. {
  1419. ((LiveUserTargetInfo*)m_Target)->m_Services->
  1420. FreeLibrary(OopDll->Handle);
  1421. }
  1422. free(OopDll);
  1423. }
  1424. }
  1425. OUT_OF_PROC_FUNC_TABLE_DLL*
  1426. ProcessInfo::FindOopFuncTableDll(PWSTR Dll)
  1427. {
  1428. OUT_OF_PROC_FUNC_TABLE_DLL* OopDll;
  1429. for (OopDll = m_OopFuncTableDlls; OopDll; OopDll = OopDll->Next)
  1430. {
  1431. if (!_wcsicmp(Dll, (PWSTR)(OopDll + 1)))
  1432. {
  1433. return OopDll;
  1434. }
  1435. }
  1436. return NULL;
  1437. }
  1438. HRESULT
  1439. ProcessInfo::LoadCorDebugDll(void)
  1440. {
  1441. HRESULT Status;
  1442. MachineInfo* CorMachine;
  1443. if (m_CorDebugDll)
  1444. {
  1445. return S_OK;
  1446. }
  1447. if (!m_CorImage ||
  1448. !(CorMachine = MachineTypeInfo(m_Target,
  1449. m_CorImage->GetMachineType())))
  1450. {
  1451. return E_UNEXPECTED;
  1452. }
  1453. VS_FIXEDFILEINFO CorVer;
  1454. if ((Status = m_Target->
  1455. GetImageVersionInformation(this,
  1456. m_CorImage->m_ImagePath,
  1457. m_CorImage->m_BaseOfImage,
  1458. "\\", &CorVer, sizeof(CorVer),
  1459. NULL)) != S_OK)
  1460. {
  1461. ErrOut("Unable to get version information for %s\n",
  1462. m_CorImage->m_ModuleName);
  1463. return Status;
  1464. }
  1465. PSTR CorDacType;
  1466. switch(m_CorImageType)
  1467. {
  1468. case COR_DLL_EE:
  1469. CorDacType = "ee";
  1470. break;
  1471. case COR_DLL_WKS:
  1472. CorDacType = "wks";
  1473. break;
  1474. case COR_DLL_SVR:
  1475. CorDacType = "svr";
  1476. break;
  1477. default:
  1478. ErrOut("Unknown runtime DLL type %s\n",
  1479. m_CorImage->m_ModuleName);
  1480. return E_INVALIDARG;
  1481. }
  1482. char DacDll[MAX_PATH];
  1483. PSTR CorImagePath = NULL;
  1484. PSTR Tail;
  1485. // If this is a live session we want to look for the
  1486. // debug DLL in the same place that the runtime is.
  1487. // If this is a dump, we want to look in the same place
  1488. // that the runtime image file was mapped from.
  1489. if (IS_DUMP_TARGET(m_Target) &&
  1490. m_CorImage->m_MappedImagePath[0])
  1491. {
  1492. CorImagePath = m_CorImage->m_MappedImagePath;
  1493. }
  1494. if (!CorImagePath)
  1495. {
  1496. CorImagePath = m_CorImage->m_ImagePath;
  1497. }
  1498. if (!CopyString(DacDll, CorImagePath, DIMA(DacDll)))
  1499. {
  1500. ErrOut("Runtime debugging DLL path overflow\n");
  1501. return E_OUTOFMEMORY;
  1502. }
  1503. // We need to request the debugging DLL that runs
  1504. // using the currently running processor type and
  1505. // that can debug the current target's processor type.
  1506. #if defined(_X86_)
  1507. PSTR HostCpu = "x86";
  1508. #elif defined(_IA64_)
  1509. PSTR HostCpu = "IA64";
  1510. #elif defined(_AMD64_)
  1511. PSTR HostCpu = "AMD64";
  1512. #elif defined(_ARM_)
  1513. PSTR HostCpu = "ARM";
  1514. #else
  1515. #error Unknown processor.
  1516. #endif
  1517. Tail = (PSTR)PathTail(DacDll);
  1518. if (!PrintString(Tail, (ULONG)(DIMA(DacDll) - (Tail - DacDll)),
  1519. "mscordac%s_%s_%s_%u.%u.%u.%u%s.dll",
  1520. CorDacType,
  1521. HostCpu,
  1522. CorMachine->m_AbbrevName,
  1523. CorVer.dwFileVersionMS >> 16,
  1524. CorVer.dwFileVersionMS & 0xffff,
  1525. CorVer.dwFileVersionLS >> 16,
  1526. CorVer.dwFileVersionLS & 0xffff,
  1527. (CorVer.dwFileFlags & VS_FF_DEBUG) ?
  1528. ((CorVer.dwFileFlags & VS_FF_PRIVATEBUILD) ?
  1529. ".fastchecked" : ".checked") : ""))
  1530. {
  1531. ErrOut("Runtime debugging DLL path overflow\n");
  1532. return E_OUTOFMEMORY;
  1533. }
  1534. //
  1535. // First try and load the debugging DLL using the same
  1536. // path as the runtime DLL. This makes it easy to pick
  1537. // up debugging DLLs that come with runtime installations.
  1538. //
  1539. PSTR DllPath = DacDll;
  1540. m_CorDebugDll = LoadLibrary(DllPath);
  1541. if (!m_CorDebugDll &&
  1542. (GetLastError() == ERROR_PATH_NOT_FOUND ||
  1543. GetLastError() == ERROR_FILE_NOT_FOUND ||
  1544. GetLastError() == ERROR_MOD_NOT_FOUND))
  1545. {
  1546. // Couldn't find it, so allow a path search.
  1547. DllPath = Tail;
  1548. m_CorDebugDll = LoadLibrary(DllPath);
  1549. }
  1550. if (!m_CorDebugDll)
  1551. {
  1552. Status = WIN32_LAST_STATUS();
  1553. VerbOut("Unable to load runtime debug DLL %s, %s\n",
  1554. DllPath, FormatStatusCode(Status));
  1555. return Status;
  1556. }
  1557. PFN_CreateCorDataAccess Entry = (PFN_CreateCorDataAccess)
  1558. GetProcAddress(m_CorDebugDll, "CreateCorDataAccess");
  1559. if (!Entry)
  1560. {
  1561. Status = WIN32_LAST_STATUS();
  1562. FreeLibrary(m_CorDebugDll);
  1563. m_CorDebugDll = NULL;
  1564. ErrOut("Runtime debug DLL %s missing entry point\n", DllPath);
  1565. return Status;
  1566. }
  1567. if ((Status = Entry(__uuidof(ICorDataAccess), &m_CorServices,
  1568. (void**)&m_CorAccess)) != S_OK)
  1569. {
  1570. FreeLibrary(m_CorDebugDll);
  1571. m_CorDebugDll = NULL;
  1572. ErrOut("Runtime debug DLL %s init failure, %s\n",
  1573. DllPath, FormatStatusCode(Status));
  1574. return Status;
  1575. }
  1576. VerbOut("Loaded runtime debug DLL %s\n", DllPath);
  1577. return S_OK;
  1578. }
  1579. HRESULT
  1580. ProcessInfo::IsCorCode(ULONG64 Native)
  1581. {
  1582. HRESULT Status;
  1583. if ((Status = LoadCorDebugDll()) != S_OK)
  1584. {
  1585. return Status;
  1586. }
  1587. return m_CorAccess->IsCorCode(Native);
  1588. }
  1589. HRESULT
  1590. ProcessInfo::ConvertNativeToIlOffset(ULONG64 Native,
  1591. PULONG64 ImageBase,
  1592. PULONG32 MethodToken,
  1593. PULONG32 MethodOffs)
  1594. {
  1595. HRESULT Status;
  1596. if ((Status = LoadCorDebugDll()) != S_OK)
  1597. {
  1598. return Status;
  1599. }
  1600. if ((Status = m_CorAccess->
  1601. GetILOffsetFromTargetAddress(Native, ImageBase,
  1602. MethodToken, MethodOffs)) != S_OK)
  1603. {
  1604. return Status;
  1605. }
  1606. if (!FindImageByOffset(*ImageBase, FALSE))
  1607. {
  1608. IMAGE_NT_HEADERS64 NtHdr;
  1609. char Name[MAX_IMAGE_PATH];
  1610. // XXX drewb - Need to work out when the
  1611. // module list should be updated for managed
  1612. // code that's not system-loaded.
  1613. // We don't know about this module, so load it
  1614. // right now.
  1615. if (m_Target->ReadImageNtHeaders(this, *ImageBase, &NtHdr) == S_OK &&
  1616. GetModnameFromImage(this, *ImageBase, NULL,
  1617. Name, DIMA(Name), TRUE))
  1618. {
  1619. char ReloadCmd[MAX_IMAGE_PATH];
  1620. PCSTR ArgsRet;
  1621. PrintString(ReloadCmd, DIMA(ReloadCmd), "%s=0x%s,0x%x",
  1622. Name, FormatAddr64(*ImageBase),
  1623. NtHdr.OptionalHeader.SizeOfImage);
  1624. m_Target->Reload(m_CurrentThread, ReloadCmd, &ArgsRet);
  1625. ImageInfo* Image = FindImageByOffset(*ImageBase, FALSE);
  1626. if (Image)
  1627. {
  1628. Image->m_CorImage = TRUE;
  1629. }
  1630. }
  1631. }
  1632. return S_OK;
  1633. }
  1634. HRESULT
  1635. ProcessInfo::GetCorSymbol(ULONG64 Native, PSTR Buffer, ULONG BufferChars,
  1636. PULONG64 Displacement)
  1637. {
  1638. HRESULT Status;
  1639. if ((Status = LoadCorDebugDll()) != S_OK)
  1640. {
  1641. return Status;
  1642. }
  1643. WCHAR SymWide[MAX_SYMBOL_LEN];
  1644. if ((Status = m_CorAccess->
  1645. GetCodeSymbolForTargetAddress(Native, SymWide, DIMA(SymWide),
  1646. Displacement)) != S_OK)
  1647. {
  1648. return Status;
  1649. }
  1650. if (!WideCharToMultiByte(CP_ACP, 0, SymWide, -1,
  1651. Buffer, BufferChars,
  1652. NULL, NULL))
  1653. {
  1654. return WIN32_LAST_STATUS();
  1655. }
  1656. return S_OK;
  1657. }
  1658. ICorDataStackWalk*
  1659. ProcessInfo::StartCorStack(ULONG32 CorThreadId)
  1660. {
  1661. HRESULT Status;
  1662. ICorDataStackWalk* Walk;
  1663. if ((Status = LoadCorDebugDll()) != S_OK)
  1664. {
  1665. return NULL;
  1666. }
  1667. if ((Status = m_CorAccess->StartStackWalk(CorThreadId,
  1668. DAC_STACK_ALL_FRAMES,
  1669. &Walk)) != S_OK)
  1670. {
  1671. return NULL;
  1672. }
  1673. return Walk;
  1674. }
  1675. HRESULT
  1676. ProcessInfo::Terminate(void)
  1677. {
  1678. if (!IS_LIVE_USER_TARGET(m_Target))
  1679. {
  1680. return E_UNEXPECTED;
  1681. }
  1682. PUSER_DEBUG_SERVICES Services =
  1683. ((LiveUserTargetInfo*)m_Target)->m_Services;
  1684. HRESULT Status = S_OK;
  1685. if (!m_Exited)
  1686. {
  1687. if ((m_Flags & ENG_PROC_EXAMINED) == 0 &&
  1688. (Status = Services->TerminateProcess(m_SysHandle,
  1689. E_FAIL)) != S_OK)
  1690. {
  1691. ErrOut("TerminateProcess failed, %s\n",
  1692. FormatStatusCode(Status));
  1693. }
  1694. else
  1695. {
  1696. MarkExited();
  1697. }
  1698. }
  1699. return Status;
  1700. }
  1701. HRESULT
  1702. ProcessInfo::Detach(void)
  1703. {
  1704. if (!IS_LIVE_USER_TARGET(m_Target))
  1705. {
  1706. return E_UNEXPECTED;
  1707. }
  1708. PUSER_DEBUG_SERVICES Services =
  1709. ((LiveUserTargetInfo*)m_Target)->m_Services;
  1710. HRESULT Status = S_OK;
  1711. if (!m_Exited)
  1712. {
  1713. if ((m_Flags & ENG_PROC_EXAMINED) == 0 &&
  1714. (Status = Services->DetachProcess(m_SystemId)) != S_OK)
  1715. {
  1716. // Older systems don't support detach so
  1717. // don't show an error message in that case.
  1718. if (Status != E_NOTIMPL)
  1719. {
  1720. ErrOut("DebugActiveProcessStop(%d) failed, %s\n",
  1721. m_SystemId, FormatStatusCode(Status));
  1722. }
  1723. }
  1724. else
  1725. {
  1726. MarkExited();
  1727. }
  1728. }
  1729. return Status;
  1730. }
  1731. HRESULT
  1732. ProcessInfo::Abandon(void)
  1733. {
  1734. if (!IS_LIVE_USER_TARGET(m_Target))
  1735. {
  1736. return E_UNEXPECTED;
  1737. }
  1738. PUSER_DEBUG_SERVICES Services =
  1739. ((LiveUserTargetInfo*)m_Target)->m_Services;
  1740. HRESULT Status;
  1741. if ((Status = Services->AbandonProcess(m_SysHandle)) != S_OK)
  1742. {
  1743. // Older systems don't support abandon so
  1744. // don't show an error message in that case.
  1745. if (Status != E_NOTIMPL)
  1746. {
  1747. ErrOut("Unable to abandon process\n");
  1748. }
  1749. return Status;
  1750. }
  1751. // We need to continue any existing event as it won't
  1752. // be returned from WaitForDebugEvent again. We
  1753. // do not want to resume execution, though.
  1754. if (m_Target->m_DeferContinueEvent)
  1755. {
  1756. if ((Status = Services->ContinueEvent(DBG_CONTINUE)) != S_OK)
  1757. {
  1758. ErrOut("Unable to continue abandoned event, %s\n",
  1759. FormatStatusCode(Status));
  1760. return Status;
  1761. }
  1762. m_Target->m_DeferContinueEvent = FALSE;
  1763. }
  1764. return Status;
  1765. }
  1766. HRESULT
  1767. ProcessInfo::GetImplicitThreadData(ThreadInfo* Thread, PULONG64 Offset)
  1768. {
  1769. HRESULT Status;
  1770. if (m_ImplicitThreadData == 0 ||
  1771. (m_ImplicitThreadDataIsDefault &&
  1772. Thread != m_ImplicitThreadDataThread))
  1773. {
  1774. Status = SetImplicitThreadData(Thread, 0, FALSE);
  1775. }
  1776. else
  1777. {
  1778. Status = S_OK;
  1779. }
  1780. *Offset = m_ImplicitThreadData;
  1781. return Status;
  1782. }
  1783. HRESULT
  1784. ProcessInfo::GetImplicitThreadDataTeb(ThreadInfo* Thread, PULONG64 Offset)
  1785. {
  1786. if (IS_USER_TARGET(m_Target))
  1787. {
  1788. // In user mode the thread data is the TEB.
  1789. return GetImplicitThreadData(Thread, Offset);
  1790. }
  1791. else if (IS_KERNEL_TARGET(m_Target))
  1792. {
  1793. return ReadImplicitThreadInfoPointer
  1794. (Thread, m_Target->m_KdDebuggerData.OffsetKThreadTeb, Offset);
  1795. }
  1796. else
  1797. {
  1798. return E_UNEXPECTED;
  1799. }
  1800. }
  1801. HRESULT
  1802. ProcessInfo::SetImplicitThreadData(ThreadInfo* Thread,
  1803. ULONG64 Offset, BOOL Verbose)
  1804. {
  1805. HRESULT Status;
  1806. BOOL Default = FALSE;
  1807. if (Offset == 0)
  1808. {
  1809. if (!Thread || Thread->m_Process != this)
  1810. {
  1811. if (Verbose)
  1812. {
  1813. ErrOut("Unable to get the current thread data\n");
  1814. }
  1815. return E_UNEXPECTED;
  1816. }
  1817. if ((Status = m_Target->
  1818. GetThreadInfoDataOffset(Thread, 0, &Offset)) != S_OK)
  1819. {
  1820. if (Verbose)
  1821. {
  1822. ErrOut("Unable to get the current thread data\n");
  1823. }
  1824. return Status;
  1825. }
  1826. if (Offset == 0)
  1827. {
  1828. if (Verbose)
  1829. {
  1830. ErrOut("Current thread data is NULL\n");
  1831. }
  1832. return E_FAIL;
  1833. }
  1834. Default = TRUE;
  1835. }
  1836. m_ImplicitThreadData = Offset;
  1837. m_ImplicitThreadDataIsDefault = Default;
  1838. m_ImplicitThreadDataThread = Thread;
  1839. return S_OK;
  1840. }
  1841. HRESULT
  1842. ProcessInfo::ReadImplicitThreadInfoPointer(ThreadInfo* Thread,
  1843. ULONG Offset, PULONG64 Ptr)
  1844. {
  1845. HRESULT Status;
  1846. ULONG64 CurThread;
  1847. // Retrieve the current ETHREAD.
  1848. if ((Status = GetImplicitThreadData(Thread, &CurThread)) != S_OK)
  1849. {
  1850. return Status;
  1851. }
  1852. return m_Target->
  1853. ReadPointer(this, m_Target->m_Machine, CurThread + Offset, Ptr);
  1854. }
  1855. //----------------------------------------------------------------------------
  1856. //
  1857. // Functions.
  1858. //
  1859. //----------------------------------------------------------------------------
  1860. ProcessInfo*
  1861. FindAnyProcessByUserId(ULONG Id)
  1862. {
  1863. TargetInfo* Target;
  1864. ProcessInfo* Process;
  1865. ForAllLayersToProcess()
  1866. {
  1867. if (Process->m_UserId == Id)
  1868. {
  1869. return Process;
  1870. }
  1871. }
  1872. return NULL;
  1873. }
  1874. ProcessInfo*
  1875. FindAnyProcessBySystemId(ULONG Id)
  1876. {
  1877. TargetInfo* Target;
  1878. ProcessInfo* Process;
  1879. ForAllLayersToProcess()
  1880. {
  1881. if (Process->m_SystemId == Id)
  1882. {
  1883. return Process;
  1884. }
  1885. }
  1886. return NULL;
  1887. }
  1888. void
  1889. ParseProcessCmds(void)
  1890. {
  1891. char Ch;
  1892. ProcessInfo* Process;
  1893. ULONG Id;
  1894. if (!g_Target)
  1895. {
  1896. error(BADTHREAD);
  1897. }
  1898. Ch = PeekChar();
  1899. if (Ch == '\0' || Ch == ';')
  1900. {
  1901. g_Target->OutputProcessInfo(NULL);
  1902. }
  1903. else
  1904. {
  1905. Process = g_Process;
  1906. g_CurCmd++;
  1907. if (Ch == '.')
  1908. {
  1909. ;
  1910. }
  1911. else if (Ch == '#')
  1912. {
  1913. Process = g_EventProcess;
  1914. }
  1915. else if (Ch == '*')
  1916. {
  1917. Process = NULL;
  1918. }
  1919. else if (Ch == '[')
  1920. {
  1921. g_CurCmd--;
  1922. Id = (ULONG)GetTermExpression("Process ID missing from");
  1923. Process = FindAnyProcessByUserId(Id);
  1924. if (Process == NULL)
  1925. {
  1926. error(BADPROCESS);
  1927. }
  1928. }
  1929. else if (Ch == '~')
  1930. {
  1931. if (*g_CurCmd != '[')
  1932. {
  1933. error(SYNTAX);
  1934. }
  1935. Id = (ULONG)GetTermExpression("Process ID missing from");
  1936. Process = FindAnyProcessBySystemId(Id);
  1937. if (Process == NULL)
  1938. {
  1939. error(BADPROCESS);
  1940. }
  1941. }
  1942. else if (Ch >= '0' && Ch <= '9')
  1943. {
  1944. Id = 0;
  1945. do
  1946. {
  1947. Id = Id * 10 + Ch - '0';
  1948. Ch = *g_CurCmd++;
  1949. } while (Ch >= '0' && Ch <= '9');
  1950. g_CurCmd--;
  1951. Process = FindAnyProcessByUserId(Id);
  1952. if (Process == NULL)
  1953. {
  1954. error(BADPROCESS);
  1955. }
  1956. }
  1957. else
  1958. {
  1959. g_CurCmd--;
  1960. }
  1961. Ch = PeekChar();
  1962. if (Ch == '\0' || Ch == ';')
  1963. {
  1964. g_Target->OutputProcessInfo(Process);
  1965. }
  1966. else
  1967. {
  1968. g_CurCmd++;
  1969. if (tolower(Ch) == 's')
  1970. {
  1971. if (Process == NULL)
  1972. {
  1973. error(BADPROCESS);
  1974. }
  1975. if (Process->m_CurrentThread == NULL)
  1976. {
  1977. Process->m_CurrentThread = Process->m_ThreadHead;
  1978. if (Process->m_CurrentThread == NULL)
  1979. {
  1980. error(BADPROCESS);
  1981. }
  1982. }
  1983. SetPromptThread(Process->m_CurrentThread,
  1984. SPT_DEFAULT_OCI_FLAGS);
  1985. }
  1986. else
  1987. {
  1988. g_CurCmd--;
  1989. }
  1990. }
  1991. }
  1992. }
  1993. //----------------------------------------------------------------------------
  1994. //
  1995. // Process creation and attach functions.
  1996. //
  1997. //----------------------------------------------------------------------------
  1998. HRESULT
  1999. TerminateProcesses(void)
  2000. {
  2001. HRESULT Status;
  2002. if (!AnyLiveUserTargets())
  2003. {
  2004. // Nothing to do.
  2005. return S_OK;
  2006. }
  2007. if (g_SymOptions & SYMOPT_SECURE)
  2008. {
  2009. ErrOut("SECURE: Process termination disallowed\n");
  2010. return HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED);
  2011. }
  2012. Status = PrepareForSeparation();
  2013. if (Status != S_OK)
  2014. {
  2015. ErrOut("Unable to prepare for termination, %s\n",
  2016. FormatStatusCode(Status));
  2017. return Status;
  2018. }
  2019. TargetInfo* Target;
  2020. HRESULT SingleStatus;
  2021. ForAllLayersToTarget()
  2022. {
  2023. // If we fail in the middle of killing things there
  2024. // isn't much that can be done so just attempt to
  2025. // kill as many things as possible.
  2026. if (IS_LIVE_USER_TARGET(Target) &&
  2027. (SingleStatus = Target->TerminateProcesses()) != S_OK)
  2028. {
  2029. Status = SingleStatus;
  2030. }
  2031. }
  2032. DiscardLastEvent();
  2033. return Status;
  2034. }
  2035. HRESULT
  2036. DetachProcesses(void)
  2037. {
  2038. HRESULT Status;
  2039. if (!AnyLiveUserTargets())
  2040. {
  2041. // Nothing to do.
  2042. return S_OK;
  2043. }
  2044. if (g_SymOptions & SYMOPT_SECURE)
  2045. {
  2046. ErrOut("SECURE: Process detach disallowed\n");
  2047. return HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED);
  2048. }
  2049. Status = PrepareForSeparation();
  2050. if (Status != S_OK)
  2051. {
  2052. ErrOut("Unable to prepare for detach, %s\n",
  2053. FormatStatusCode(Status));
  2054. return Status;
  2055. }
  2056. TargetInfo* Target;
  2057. HRESULT SingleStatus;
  2058. ForAllLayersToTarget()
  2059. {
  2060. // If we fail in the middle of detaching things there
  2061. // isn't much that can be done so just attempt to
  2062. // detach as many things as possible.
  2063. if (IS_LIVE_USER_TARGET(Target) &&
  2064. (SingleStatus = Target->DetachProcesses()) != S_OK)
  2065. {
  2066. Status = SingleStatus;
  2067. }
  2068. }
  2069. DiscardLastEvent();
  2070. return Status;
  2071. }
  2072. HRESULT
  2073. SeparateCurrentProcess(ULONG Mode, PSTR Description)
  2074. {
  2075. if (!IS_LIVE_USER_TARGET(g_Target) ||
  2076. g_Process == NULL)
  2077. {
  2078. return E_INVALIDARG;
  2079. }
  2080. if (g_SymOptions & SYMOPT_SECURE)
  2081. {
  2082. ErrOut("SECURE: Process separation disallowed\n");
  2083. return HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED);
  2084. }
  2085. PUSER_DEBUG_SERVICES Services =
  2086. ((LiveUserTargetInfo*)g_Target)->m_Services;
  2087. if ((Mode == SEP_DETACH || Mode == SEP_TERMINATE) &&
  2088. IS_CUR_CONTEXT_ACCESSIBLE())
  2089. {
  2090. ADDR Pc;
  2091. // Move the PC past any current breakpoint instruction so that
  2092. // the process has a chance of running.
  2093. g_Machine->GetPC(&Pc);
  2094. if (g_Machine->IsBreakpointInstruction(g_Process, &Pc))
  2095. {
  2096. g_Machine->AdjustPCPastBreakpointInstruction
  2097. (&Pc, DEBUG_BREAKPOINT_CODE);
  2098. }
  2099. }
  2100. // Flush any buffered changes.
  2101. if (IS_CUR_CONTEXT_ACCESSIBLE())
  2102. {
  2103. g_Target->FlushRegContext();
  2104. }
  2105. if (g_EventProcess == g_Process && Mode != SEP_TERMINATE)
  2106. {
  2107. if (g_Target->m_DeferContinueEvent)
  2108. {
  2109. Services->ContinueEvent(DBG_CONTINUE);
  2110. g_Target->m_DeferContinueEvent = FALSE;
  2111. }
  2112. }
  2113. ((LiveUserTargetInfo*)g_Target)->
  2114. SuspendResumeThreads(g_Process, FALSE, NULL);
  2115. HRESULT Status;
  2116. PSTR Operation;
  2117. switch(Mode)
  2118. {
  2119. case SEP_DETACH:
  2120. Status = g_Process->Detach();
  2121. Operation = "Detached";
  2122. break;
  2123. case SEP_TERMINATE:
  2124. Status = g_Process->Terminate();
  2125. if ((g_Process->m_Flags & ENG_PROC_EXAMINED) == 0)
  2126. {
  2127. Operation = "Terminated. "
  2128. "Exit thread and process events will occur.";
  2129. }
  2130. else
  2131. {
  2132. Operation = "Terminated";
  2133. }
  2134. break;
  2135. case SEP_ABANDON:
  2136. Status = g_Process->Abandon();
  2137. Operation = "Abandoned";
  2138. break;
  2139. }
  2140. if (Status == S_OK)
  2141. {
  2142. if (Description != NULL)
  2143. {
  2144. strcpy(Description, Operation);
  2145. }
  2146. // If we're detaching or abandoning it's safe to go
  2147. // ahead and remove the process now so that it
  2148. // can't be access further.
  2149. // If we're terminating we have to wait for
  2150. // the exit events to come through so
  2151. // keep the process until that happens.
  2152. if (Mode != SEP_TERMINATE)
  2153. {
  2154. delete g_Process;
  2155. SetToAnyLayers(TRUE);
  2156. }
  2157. else
  2158. {
  2159. g_Process->m_Exited = FALSE;
  2160. }
  2161. }
  2162. else
  2163. {
  2164. ((LiveUserTargetInfo*)g_Target)->
  2165. SuspendResumeThreads(g_Process, TRUE, NULL);
  2166. }
  2167. return Status;
  2168. }