1
0

dbgtest.c 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352
  1. /*++
  2. Copyright (c) 2013 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. dbgtest.c
  9. Abstract:
  10. This module implements the tests used to verify that the debug API is
  11. working properly.
  12. Author:
  13. Evan Green 15-May-2013
  14. Environment:
  15. User Mode
  16. --*/
  17. //
  18. // ------------------------------------------------------------------- Includes
  19. //
  20. #include <minoca/lib/minocaos.h>
  21. #include <minoca/debug/dbgproto.h>
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <unistd.h>
  25. #include <errno.h>
  26. #include <sys/wait.h>
  27. #include <string.h>
  28. //
  29. // --------------------------------------------------------------------- Macros
  30. //
  31. #define DBGTEST_PRINT(...) \
  32. if (DbgTestVerbose != FALSE) { \
  33. printf(__VA_ARGS__); \
  34. }
  35. #define DBGTEST_ERROR(...) printf(__VA_ARGS__)
  36. //
  37. // ---------------------------------------------------------------- Definitions
  38. //
  39. #define DEBUG_BREAK_COUNT 5
  40. #define MODULE_LIST_BUFFER_SIZE 256
  41. //
  42. // ------------------------------------------------------ Data Type Definitions
  43. //
  44. //
  45. // ----------------------------------------------- Internal Function Prototypes
  46. //
  47. ULONG
  48. RunAllDebugTests (
  49. VOID
  50. );
  51. ULONG
  52. TestBasicDebugConnection (
  53. VOID
  54. );
  55. void
  56. UserSignalHandler (
  57. int SignalNumber,
  58. siginfo_t *SignalInformation,
  59. void *Context
  60. );
  61. void
  62. User2SignalHandler (
  63. int SignalNumber,
  64. siginfo_t *SignalInformation,
  65. void *Context
  66. );
  67. VOID
  68. TestThreadSpinForever (
  69. PVOID Parameter
  70. );
  71. VOID
  72. PrintRegisterContents (
  73. PBREAK_NOTIFICATION Break
  74. );
  75. VOID
  76. PrintSignalParameters (
  77. PSIGNAL_PARAMETERS Parameters
  78. );
  79. ULONG
  80. SingleStep (
  81. pid_t Child
  82. );
  83. ULONG
  84. RangeStep (
  85. pid_t Child
  86. );
  87. VOID
  88. ChildSignalLoop (
  89. pid_t Child,
  90. volatile UCHAR *Stop
  91. );
  92. ULONG
  93. PrintLoadedModules (
  94. pid_t Child
  95. );
  96. //
  97. // -------------------------------------------------------------------- Globals
  98. //
  99. //
  100. // Set this to TRUE to enable more verbose debug output.
  101. //
  102. BOOL DbgTestVerbose = FALSE;
  103. BOOL DbgTestPrintRegisters = FALSE;
  104. //
  105. // Keep track of whether or not the child has initialized.
  106. //
  107. volatile BOOL ChildInitialized;
  108. //
  109. // Remember the number of signals received.
  110. //
  111. volatile ULONG User2SignalsReceived;
  112. //
  113. // ------------------------------------------------------------------ Functions
  114. //
  115. int
  116. main (
  117. int ArgumentCount,
  118. char **Arguments
  119. )
  120. /*++
  121. Routine Description:
  122. This routine implements the debug test program.
  123. Arguments:
  124. ArgumentCount - Supplies the number of elements in the arguments array.
  125. Arguments - Supplies an array of strings. The array count is bounded by the
  126. previous parameter, and the strings are null-terminated.
  127. Return Value:
  128. 0 on success.
  129. Non-zero on failure.
  130. --*/
  131. {
  132. ULONG TestsCompleted;
  133. TestsCompleted = 0;
  134. while (RunAllDebugTests() == 0) {
  135. printf("%d: ", TestsCompleted);
  136. TestsCompleted += 1;
  137. }
  138. return 1;
  139. }
  140. //
  141. // --------------------------------------------------------- Internal Functions
  142. //
  143. ULONG
  144. RunAllDebugTests (
  145. VOID
  146. )
  147. /*++
  148. Routine Description:
  149. This routine executes all debug tests.
  150. Arguments:
  151. None.
  152. Return Value:
  153. Returns the number of failures in the test suite.
  154. --*/
  155. {
  156. ULONG Failures;
  157. Failures = 0;
  158. Failures += TestBasicDebugConnection();
  159. if (Failures != 0) {
  160. DBGTEST_ERROR("*** %d failures in debug tests. ***\n", Failures);
  161. } else {
  162. printf("All debug tests pass.\n");
  163. }
  164. return Failures;
  165. }
  166. ULONG
  167. TestBasicDebugConnection (
  168. VOID
  169. )
  170. /*++
  171. Routine Description:
  172. This routine tests that a process can perform basic trace operations on
  173. another process.
  174. Arguments:
  175. None.
  176. Return Value:
  177. Returns the number of failures in the test.
  178. --*/
  179. {
  180. BREAK_NOTIFICATION Break;
  181. pid_t Child;
  182. volatile ULONG ChildInitializing;
  183. ULONG ChildThreadCount;
  184. ULONG ChildThreadIndex;
  185. int ExitStatus;
  186. ULONG Failures;
  187. struct sigaction OriginalUser1Action;
  188. struct sigaction OriginalUser2Action;
  189. pid_t Parent;
  190. BOOL RestoreUser1;
  191. int Result;
  192. SIGNAL_PARAMETERS SignalParameters;
  193. KSTATUS Status;
  194. volatile UCHAR Stop;
  195. ULONG TraceRound;
  196. struct sigaction User1Action;
  197. struct sigaction User2Action;
  198. pid_t WaitPid;
  199. ChildThreadCount = 5;
  200. Failures = 0;
  201. RestoreUser1 = FALSE;
  202. Stop = FALSE;
  203. ChildInitialized = FALSE;
  204. //
  205. // Wire up the SIGUSR1 handler.
  206. //
  207. memset(&User1Action, 0, sizeof(struct sigaction));
  208. User1Action.sa_sigaction = UserSignalHandler;
  209. User1Action.sa_flags = SA_SIGINFO;
  210. Result = sigaction(SIGUSR1, &User1Action, &OriginalUser1Action);
  211. if (Result < 0) {
  212. DBGTEST_ERROR("DbgTest: Failed to set sigaction for SIGUSR1. "
  213. "Errno %d\n",
  214. errno);
  215. Failures += 1;
  216. goto TestBasicDebugConnectionEnd;
  217. }
  218. RestoreUser1 = TRUE;
  219. //
  220. // Fork off a child to be debugged.
  221. //
  222. Child = fork();
  223. if (Child < 0) {
  224. DBGTEST_ERROR("DbgTest: Failed to fork. Errno %d\n", errno);
  225. Failures += 1;
  226. goto TestBasicDebugConnectionEnd;
  227. }
  228. //
  229. // If this is the child, signal the parent that everything's ready.
  230. //
  231. if (Child == 0) {
  232. Child = getpid();
  233. Parent = getppid();
  234. DBGTEST_PRINT("Created child %d of parent %d\n", Child, Parent);
  235. //
  236. // Allow tracing of this bad boy.
  237. //
  238. Status = OsDebug(DebugCommandEnableDebugging, 0, NULL, NULL, 0, 0);
  239. if (!KSUCCESS(Status)) {
  240. DBGTEST_ERROR("DbgTest: Failed to enable debugging. Status %d\n",
  241. Status);
  242. exit(1);
  243. }
  244. //
  245. // Signal to the parent process that everything is ready.
  246. //
  247. kill(Parent, SIGUSR1);
  248. DBGTEST_PRINT("Child marked as initialized.\n");
  249. //
  250. // Configure the child to ignore SIGUSR2.
  251. //
  252. memset(&User2Action, 0, sizeof(struct sigaction));
  253. User2Action.sa_sigaction = User2SignalHandler;
  254. User2Action.sa_flags = SA_SIGINFO;
  255. Result = sigaction(SIGUSR2, &User2Action, &OriginalUser2Action);
  256. if (Result < 0) {
  257. DBGTEST_ERROR("DbgTest: Child failed to set sigaction for SIGUSR2. "
  258. "errno %d.\n",
  259. errno);
  260. exit(1);
  261. }
  262. //
  263. // Create some extra threads to just hang out.
  264. //
  265. for (ChildThreadIndex = 0;
  266. ChildThreadIndex < ChildThreadCount;
  267. ChildThreadIndex += 1) {
  268. ChildInitializing = 0;
  269. Status = OsCreateThread(NULL,
  270. 0,
  271. TestThreadSpinForever,
  272. (PVOID)&ChildInitializing,
  273. NULL,
  274. 0,
  275. NULL,
  276. NULL);
  277. if (!KSUCCESS(Status)) {
  278. DBGTEST_ERROR("Child %d failed to create thread: %d.\n",
  279. getpid(),
  280. Status);
  281. }
  282. while (ChildInitializing == 0) {
  283. NOTHING;
  284. }
  285. DBGTEST_PRINT("Child dummy thread %d created.\n",
  286. ChildThreadIndex + 1);
  287. }
  288. //
  289. // Send signals until someone sets that stop variable to TRUE.
  290. //
  291. DBGTEST_PRINT("Child looping forever...\n");
  292. ChildSignalLoop(Child, &Stop);
  293. //
  294. // Restore SIGUSR2.
  295. //
  296. Result = sigaction(SIGUSR2, &OriginalUser2Action, NULL);
  297. if (Result < 0) {
  298. DBGTEST_ERROR("DbgTest: Child failed to set sigaction for SIGUSR2. "
  299. "errno %d.\n",
  300. errno);
  301. exit(1);
  302. }
  303. //
  304. // Return peacefully.
  305. //
  306. DBGTEST_PRINT("Child exiting gracefully.\n");
  307. exit(0);
  308. //
  309. // If this is the parent, begin debugging.
  310. //
  311. } else {
  312. //
  313. // Wait for the child to initialize.
  314. //
  315. DBGTEST_PRINT("Waiting for child %d to initialize.\n", Child);
  316. while (ChildInitialized == FALSE) {
  317. NOTHING;
  318. }
  319. for (TraceRound = 0; TraceRound < DEBUG_BREAK_COUNT; TraceRound += 1) {
  320. DBGTEST_PRINT("Debugger waiting %d...\n", TraceRound);
  321. WaitPid = waitpid(-1, &ExitStatus, WUNTRACED);
  322. //
  323. // The wait is expected to succeed.
  324. //
  325. if (WaitPid < 0) {
  326. DBGTEST_ERROR("DbgTest: Failed to wait. Errno %d\n", errno);
  327. Failures += 1;
  328. }
  329. //
  330. // The wait is expected to return the child.
  331. //
  332. if (WaitPid != Child) {
  333. DBGTEST_ERROR("DbgTest: wait() returned %d rather than "
  334. "expected child %d.\n",
  335. WaitPid,
  336. Child);
  337. Failures += 1;
  338. }
  339. //
  340. // If this is the first round, try getting the loaded module list.
  341. //
  342. if (TraceRound == 0) {
  343. Failures += PrintLoadedModules(Child);
  344. }
  345. //
  346. // If this is the last round, the child should have just exited.
  347. //
  348. if (TraceRound == DEBUG_BREAK_COUNT - 1) {
  349. //
  350. // The wait is expected to return a macro status of exited.
  351. //
  352. if ((WIFSIGNALED(ExitStatus)) || (!WIFEXITED(ExitStatus)) ||
  353. (WIFCONTINUED(ExitStatus)) || (WIFSTOPPED(ExitStatus))) {
  354. DBGTEST_ERROR("DbgTest: wait() returned unexpected status "
  355. "%x at end.\n",
  356. ExitStatus);
  357. Failures += 1;
  358. }
  359. if (WEXITSTATUS(ExitStatus) != 0) {
  360. DBGTEST_ERROR("DbgTest: Child returned error code of %d\n",
  361. WEXITSTATUS(ExitStatus));
  362. Failures += WEXITSTATUS(ExitStatus);
  363. }
  364. //
  365. // This is not the last round.
  366. //
  367. } else {
  368. //
  369. // The wait is expected to return a macro status of stopped.
  370. //
  371. if ((WIFSIGNALED(ExitStatus)) || (WIFEXITED(ExitStatus)) ||
  372. (WIFCONTINUED(ExitStatus)) || (!WIFSTOPPED(ExitStatus)) ||
  373. (WSTOPSIG(ExitStatus) != SIGUSR2)) {
  374. DBGTEST_ERROR("DbgTest: wait() returned unexpected status "
  375. "%x. Signaled %x exited %x cont %x stopped "
  376. "%x stopsig %d\n",
  377. ExitStatus,
  378. WIFSIGNALED(ExitStatus),
  379. WIFEXITED(ExitStatus),
  380. WIFCONTINUED(ExitStatus),
  381. WIFSTOPPED(ExitStatus),
  382. WSTOPSIG(ExitStatus));
  383. Failures += 1;
  384. }
  385. //
  386. // If this is the second to last round, write the value of the
  387. // stop variable so that the child quits.
  388. //
  389. if (TraceRound == DEBUG_BREAK_COUNT - 2) {
  390. Stop = TRUE;
  391. Status = OsDebug(DebugCommandWriteMemory,
  392. Child,
  393. (PVOID)&Stop,
  394. (PVOID)&Stop,
  395. sizeof(Stop),
  396. 0);
  397. if (!KSUCCESS(Status)) {
  398. DBGTEST_ERROR("DbgTest: Failed to write to child "
  399. "memory. Status %d\n",
  400. Status);
  401. Failures += 1;
  402. }
  403. }
  404. //
  405. // Also try getting and setting some registers.
  406. //
  407. memset(&Break, 0, sizeof(Break));
  408. Status = OsDebug(DebugCommandGetBreakInformation,
  409. Child,
  410. NULL,
  411. &Break,
  412. sizeof(Break),
  413. 0);
  414. if (!KSUCCESS(Status)) {
  415. DBGTEST_ERROR("DbgTest: Failed to get registers for "
  416. "child %d. Status %d\n",
  417. Child,
  418. Status);
  419. Failures += 1;
  420. }
  421. PrintRegisterContents(&Break);
  422. Status = OsDebug(DebugCommandSetBreakInformation,
  423. Child,
  424. NULL,
  425. &Break,
  426. sizeof(BREAK_NOTIFICATION),
  427. 0);
  428. if (!KSUCCESS(Status)) {
  429. DBGTEST_ERROR("DbgTest: Failed to set registers for child "
  430. "%d. Status %d\n",
  431. Child,
  432. Status);
  433. Failures += 1;
  434. }
  435. //
  436. // Also try getting and setting the signal information.
  437. //
  438. memset(&SignalParameters, 0, sizeof(SIGNAL_PARAMETERS));
  439. Status = OsDebug(DebugCommandGetSignalInformation,
  440. Child,
  441. NULL,
  442. &SignalParameters,
  443. sizeof(SIGNAL_PARAMETERS),
  444. 0);
  445. if (!KSUCCESS(Status)) {
  446. DBGTEST_ERROR("DbgTest: Failed to get signal parameters "
  447. "for child %d. Status %d\n",
  448. Child,
  449. Status);
  450. Failures += 1;
  451. }
  452. PrintSignalParameters(&SignalParameters);
  453. Status = OsDebug(DebugCommandSetSignalInformation,
  454. Child,
  455. NULL,
  456. &SignalParameters,
  457. sizeof(SIGNAL_PARAMETERS),
  458. 0);
  459. if (!KSUCCESS(Status)) {
  460. DBGTEST_ERROR("DbgTest: Failed to set signal parameters "
  461. "for child %d. Status %d\n",
  462. Child,
  463. Status);
  464. Failures += 1;
  465. }
  466. //
  467. // Try a single step, then continue.
  468. //
  469. Failures += SingleStep(Child);
  470. Failures += RangeStep(Child);
  471. Status = OsDebug(DebugCommandContinue,
  472. Child,
  473. NULL,
  474. NULL,
  475. 0,
  476. WSTOPSIG(ExitStatus));
  477. if (!KSUCCESS(Status)) {
  478. DBGTEST_ERROR("DbgTest: Failed to continue. Status %d\n",
  479. Status);
  480. Failures += 1;
  481. }
  482. }
  483. }
  484. DBGTEST_PRINT("Debugger finished. %d errors\n", Failures);
  485. }
  486. TestBasicDebugConnectionEnd:
  487. if (RestoreUser1 != FALSE) {
  488. Result = sigaction(SIGUSR1, &OriginalUser1Action, NULL);
  489. if (Result < 0) {
  490. DBGTEST_ERROR("DbgTest: Child failed to set sigaction for SIGUSR2. "
  491. "errno %d.\n",
  492. errno);
  493. Failures += 1;
  494. }
  495. }
  496. return Failures;
  497. }
  498. void
  499. UserSignalHandler (
  500. int SignalNumber,
  501. siginfo_t *SignalInformation,
  502. void *Context
  503. )
  504. /*++
  505. Routine Description:
  506. This routine implements the SIGUSR1 signal handler, which is sent by the
  507. child to indicate it has fully initialized.
  508. Arguments:
  509. SignalNumber - Supplies the signal number, SIGUSR1.
  510. SignalInformation - Supplies a pointer to the signal information.
  511. Context - Supplies a context pointer supplied when the signal was wired in.
  512. Return Value:
  513. None.
  514. --*/
  515. {
  516. ChildInitialized = TRUE;
  517. return;
  518. }
  519. void
  520. User2SignalHandler (
  521. int SignalNumber,
  522. siginfo_t *SignalInformation,
  523. void *Context
  524. )
  525. /*++
  526. Routine Description:
  527. This routine implements the SIGUSR1 signal handler, which is sent by the
  528. child to indicate it has fully initialized.
  529. Arguments:
  530. SignalNumber - Supplies the signal number, SIGUSR1.
  531. SignalInformation - Supplies a pointer to the signal information.
  532. Context - Supplies a context pointer supplied when the signal was wired in.
  533. Return Value:
  534. None.
  535. --*/
  536. {
  537. User2SignalsReceived += 1;
  538. return;
  539. }
  540. VOID
  541. TestThreadSpinForever (
  542. PVOID Parameter
  543. )
  544. /*++
  545. Routine Description:
  546. This routine implements a thread routine that simply spins forever.
  547. Arguments:
  548. Parameter - Supplies a parameter assumed to be of type PULONG whose
  549. contents will be set to 0.
  550. Return Value:
  551. None. This thread never returns voluntarily.
  552. --*/
  553. {
  554. *((PULONG)Parameter) = 1;
  555. while (TRUE) {
  556. NOTHING;
  557. }
  558. return;
  559. }
  560. VOID
  561. PrintRegisterContents (
  562. PBREAK_NOTIFICATION Break
  563. )
  564. /*++
  565. Routine Description:
  566. This routine prints register contents of a break notification.
  567. Arguments:
  568. Break - Supplies a pointer to the initialized break notification to print.
  569. Return Value:
  570. None.
  571. --*/
  572. {
  573. #if defined(__i386) || defined(__amd64)
  574. ULONG ByteIndex;
  575. #elif defined(__arm__)
  576. ULONG Instruction;
  577. #endif
  578. if (DbgTestPrintRegisters == FALSE) {
  579. return;
  580. }
  581. DBGTEST_PRINT("Break, exception %d, thread ID %x thread Count %x "
  582. "process %x.\n",
  583. Break->Exception,
  584. Break->ProcessorOrThreadNumber,
  585. Break->ProcessorOrThreadCount,
  586. Break->Process);
  587. if (Break->ProcessorBlock != 0) {
  588. DBGTEST_PRINT("Processor block %I64x\n", Break->ProcessorBlock);
  589. }
  590. if (Break->ErrorCode != 0) {
  591. DBGTEST_PRINT("Error code: %x\n", Break->ErrorCode);
  592. }
  593. #if defined(__i386)
  594. DBGTEST_PRINT("Modules count %d signature %I64x, "
  595. "Instruction pointer %I64x.\nInstruction stream: ",
  596. Break->LoadedModuleCount,
  597. Break->LoadedModuleSignature,
  598. Break->InstructionPointer);
  599. for (ByteIndex = 0;
  600. ByteIndex < BREAK_NOTIFICATION_STREAM_SIZE;
  601. ByteIndex += 1) {
  602. DBGTEST_PRINT("%02X ", Break->InstructionStream[ByteIndex]);
  603. }
  604. DBGTEST_PRINT("\n");
  605. DBGTEST_PRINT("eax=%08I64x ebx=%08I64x ecx=%08I64x edx=%08I64x "
  606. "eip=%08I64x\n"
  607. "esi=%08I64x edi=%08I64x ebp=%08I64x esp=%08I64x "
  608. "eflags=%08I64x\n",
  609. Break->Registers.X86.Eax,
  610. Break->Registers.X86.Ebx,
  611. Break->Registers.X86.Ecx,
  612. Break->Registers.X86.Edx,
  613. Break->Registers.X86.Eip,
  614. Break->Registers.X86.Esi,
  615. Break->Registers.X86.Edi,
  616. Break->Registers.X86.Ebp,
  617. Break->Registers.X86.Esp,
  618. Break->Registers.X86.Eflags);
  619. DBGTEST_PRINT("cs=%04x ds=%04x es=%04x fs=%04x gs=%04x ss=%04x\n",
  620. Break->Registers.X86.Cs,
  621. Break->Registers.X86.Ds,
  622. Break->Registers.X86.Es,
  623. Break->Registers.X86.Fs,
  624. Break->Registers.X86.Gs,
  625. Break->Registers.X86.Ss);
  626. #elif defined(__arm__)
  627. RtlCopyMemory(&Instruction, Break->InstructionStream, sizeof(ULONG));
  628. DBGTEST_PRINT("%08X\n", Instruction);
  629. DBGTEST_PRINT("r0=%08x r1=%08x r2=%08x r3=%08x r4=%08x r5=%08x\n"
  630. "r6=%08x r7=%08x r8=%08x r9=%08x r10=%08x fp=%08x\n"
  631. "ip=%08x sp=%08x lr=%08x pc=%08x cpsr=%08x\n",
  632. Break->Registers.Arm.R0,
  633. Break->Registers.Arm.R1,
  634. Break->Registers.Arm.R2,
  635. Break->Registers.Arm.R3,
  636. Break->Registers.Arm.R4,
  637. Break->Registers.Arm.R5,
  638. Break->Registers.Arm.R6,
  639. Break->Registers.Arm.R7,
  640. Break->Registers.Arm.R8,
  641. Break->Registers.Arm.R9,
  642. Break->Registers.Arm.R10,
  643. Break->Registers.Arm.R11Fp,
  644. Break->Registers.Arm.R12Ip,
  645. Break->Registers.Arm.R13Sp,
  646. Break->Registers.Arm.R14Lr,
  647. Break->Registers.Arm.R15Pc,
  648. Break->Registers.Arm.Cpsr);
  649. #elif defined(__amd64)
  650. DBGTEST_PRINT("Modules count %d signature %I64x, "
  651. "Instruction pointer %I64x.\nInstruction stream: ",
  652. Break->LoadedModuleCount,
  653. Break->LoadedModuleSignature,
  654. Break->InstructionPointer);
  655. for (ByteIndex = 0;
  656. ByteIndex < BREAK_NOTIFICATION_STREAM_SIZE;
  657. ByteIndex += 1) {
  658. DBGTEST_PRINT("%02X ", Break->InstructionStream[ByteIndex]);
  659. }
  660. DBGTEST_PRINT("\n");
  661. #else
  662. #error Unsupported processor architecture
  663. #endif
  664. }
  665. VOID
  666. PrintSignalParameters (
  667. PSIGNAL_PARAMETERS Parameters
  668. )
  669. /*++
  670. Routine Description:
  671. This routine prints out signal parameters.
  672. Arguments:
  673. Parameters - Supplies a pointer to the parameters to print.
  674. Return Value:
  675. None.
  676. --*/
  677. {
  678. DBGTEST_PRINT("Signal %d, code %d, error %d, sending process %d user %d, "
  679. "value %d\n",
  680. Parameters->SignalNumber,
  681. Parameters->SignalCode,
  682. Parameters->ErrorNumber,
  683. Parameters->FromU.SendingProcess,
  684. Parameters->SendingUserId,
  685. Parameters->Parameter);
  686. return;
  687. }
  688. ULONG
  689. SingleStep (
  690. pid_t Child
  691. )
  692. /*++
  693. Routine Description:
  694. This routine steps the target by one instruction. This routine assumes the
  695. child is already stopped.
  696. Arguments:
  697. Child - Supplies the child to step.
  698. Return Value:
  699. Returns the number of failures encountered.
  700. --*/
  701. {
  702. BREAK_NOTIFICATION Break;
  703. int ExitStatus;
  704. ULONG Failures;
  705. KSTATUS Status;
  706. pid_t WaitPid;
  707. Failures = 0;
  708. //
  709. // Single step that bad boy, and skip the signal that caused the break.
  710. //
  711. Status = OsDebug(DebugCommandSingleStep, Child, NULL, NULL, 0, 0);
  712. if (!KSUCCESS(Status)) {
  713. DBGTEST_ERROR("DbgTest: Failed to single step child %x: %d\n",
  714. Child,
  715. Status);
  716. }
  717. WaitPid = waitpid(-1, &ExitStatus, WUNTRACED);
  718. //
  719. // The wait is expected to succeed.
  720. //
  721. if (WaitPid < 0) {
  722. DBGTEST_ERROR("DbgTest: Failed to wait (ss). Errno %d\n", errno);
  723. Failures += 1;
  724. }
  725. //
  726. // The wait is expected to return the child.
  727. //
  728. if (WaitPid != Child) {
  729. DBGTEST_ERROR("DbgTest: wait() returned %d rather than "
  730. "expected child %d.\n",
  731. WaitPid,
  732. Child);
  733. Failures += 1;
  734. }
  735. //
  736. // The wait is expected to return a macro status of stopped.
  737. //
  738. if ((WIFSIGNALED(ExitStatus)) || (WIFEXITED(ExitStatus)) ||
  739. (WIFCONTINUED(ExitStatus)) || (!WIFSTOPPED(ExitStatus)) ||
  740. (WSTOPSIG(ExitStatus) != SIGTRAP)) {
  741. DBGTEST_ERROR("DbgTest: wait() (SS) returned unexpected status "
  742. "%x. Signaled %x exited %x cont %x stopped "
  743. "%x stopsig %d\n",
  744. ExitStatus,
  745. WIFSIGNALED(ExitStatus),
  746. WIFEXITED(ExitStatus),
  747. WIFCONTINUED(ExitStatus),
  748. WIFSTOPPED(ExitStatus),
  749. WSTOPSIG(ExitStatus));
  750. Failures += 1;
  751. }
  752. //
  753. // Print the new registers.
  754. //
  755. memset(&Break, 0, sizeof(Break));
  756. Status = OsDebug(DebugCommandGetBreakInformation,
  757. Child,
  758. NULL,
  759. &Break,
  760. sizeof(Break),
  761. 0);
  762. if (!KSUCCESS(Status)) {
  763. DBGTEST_ERROR("DbgTest: Failed to get registers for "
  764. "child %d. Status %d\n",
  765. Child,
  766. Status);
  767. Failures += 1;
  768. }
  769. DBGTEST_PRINT("Post single step registers:\n");
  770. PrintRegisterContents(&Break);
  771. return Failures;
  772. }
  773. ULONG
  774. RangeStep (
  775. pid_t Child
  776. )
  777. /*++
  778. Routine Description:
  779. This routine lets the target go until it hits a specific range.
  780. Arguments:
  781. Child - Supplies the child to step.
  782. Return Value:
  783. Returns the number of failures encountered.
  784. --*/
  785. {
  786. BREAK_NOTIFICATION Break;
  787. PROCESS_DEBUG_BREAK_RANGE BreakRange;
  788. int ExitStatus;
  789. ULONG Failures;
  790. KSTATUS Status;
  791. pid_t WaitPid;
  792. Failures = 0;
  793. BreakRange.BreakRangeStart = (PVOID)0;
  794. BreakRange.BreakRangeEnd = (PVOID)(UINTN)MAX_ULONGLONG;
  795. BreakRange.RangeHoleStart = NULL;
  796. BreakRange.RangeHoleEnd = NULL;
  797. //
  798. // Range step that bad boy, and skip the signal that caused the break.
  799. //
  800. Status = OsDebug(DebugCommandRangeStep,
  801. Child,
  802. NULL,
  803. &BreakRange,
  804. sizeof(PROCESS_DEBUG_BREAK_RANGE),
  805. 0);
  806. if (!KSUCCESS(Status)) {
  807. DBGTEST_ERROR("DbgTest: Failed to range step child %x: %d\n",
  808. Child,
  809. Status);
  810. }
  811. WaitPid = waitpid(-1, &ExitStatus, WUNTRACED);
  812. //
  813. // The wait is expected to succeed.
  814. //
  815. if (WaitPid < 0) {
  816. DBGTEST_ERROR("DbgTest: Failed to wait (rs). Errno %d\n", errno);
  817. Failures += 1;
  818. }
  819. //
  820. // The wait is expected to return the child.
  821. //
  822. if (WaitPid != Child) {
  823. DBGTEST_ERROR("DbgTest: wait() (rs) returned %d rather than "
  824. "expected child %d.\n",
  825. WaitPid,
  826. Child);
  827. Failures += 1;
  828. }
  829. //
  830. // The wait is expected to return a macro status of stopped.
  831. //
  832. if ((WIFSIGNALED(ExitStatus)) || (WIFEXITED(ExitStatus)) ||
  833. (WIFCONTINUED(ExitStatus)) || (!WIFSTOPPED(ExitStatus)) ||
  834. (WSTOPSIG(ExitStatus) != SIGTRAP)) {
  835. DBGTEST_ERROR("DbgTest: wait() (RS) returned unexpected status "
  836. "%x. Signaled %x exited %x cont %x stopped "
  837. "%x stopsig %d\n",
  838. ExitStatus,
  839. WIFSIGNALED(ExitStatus),
  840. WIFEXITED(ExitStatus),
  841. WIFCONTINUED(ExitStatus),
  842. WIFSTOPPED(ExitStatus),
  843. WSTOPSIG(ExitStatus));
  844. Failures += 1;
  845. }
  846. //
  847. // Print the new registers.
  848. //
  849. memset(&Break, 0, sizeof(Break));
  850. Status = OsDebug(DebugCommandGetBreakInformation,
  851. Child,
  852. NULL,
  853. &Break,
  854. sizeof(Break),
  855. 0);
  856. if (!KSUCCESS(Status)) {
  857. DBGTEST_ERROR("DbgTest: Failed to get registers for "
  858. "child %d (RS). Status %d\n",
  859. Child,
  860. Status);
  861. Failures += 1;
  862. }
  863. DBGTEST_PRINT("Post range step registers:\n");
  864. PrintRegisterContents(&Break);
  865. return Failures;
  866. }
  867. VOID
  868. ChildSignalLoop (
  869. pid_t Child,
  870. volatile UCHAR *Stop
  871. )
  872. /*++
  873. Routine Description:
  874. This routine spins signaling itself until someone tells it to stop.
  875. Arguments:
  876. Child - Supplies this process' process identifier.
  877. Stop - Supplies the address of the boolean that is set to a non-zero value
  878. when they want it to stop.
  879. Return Value:
  880. None.
  881. --*/
  882. {
  883. ULONG ExpectedSignalsReceived;
  884. int Result;
  885. User2SignalsReceived = 0;
  886. while (*Stop == FALSE) {
  887. ExpectedSignalsReceived = User2SignalsReceived + 1;
  888. Result = kill(Child, SIGUSR2);
  889. if (Result < 0) {
  890. DBGTEST_ERROR("DbgTest: Child failed to send signal to "
  891. "itself. errno %d.\n",
  892. errno);
  893. exit(1);
  894. }
  895. while (User2SignalsReceived != ExpectedSignalsReceived) {
  896. NOTHING;
  897. }
  898. }
  899. return;
  900. }
  901. ULONG
  902. PrintLoadedModules (
  903. pid_t Child
  904. )
  905. /*++
  906. Routine Description:
  907. This routine retrieves and prints the list of loaded modules in the client.
  908. Arguments:
  909. Child - Supplies the child process to query.
  910. Return Value:
  911. Returns the number of failures encountered.
  912. --*/
  913. {
  914. ULONG ComputedStructureLength;
  915. ULONG Failures;
  916. PMODULE_LIST_HEADER List;
  917. PLOADED_MODULE_ENTRY Module;
  918. ULONG ModuleIndex;
  919. ULONG NameLength;
  920. ULONGLONG Signature;
  921. KSTATUS Status;
  922. Failures = 0;
  923. //
  924. // Create a reasonably sized buffer for the request.
  925. //
  926. List = malloc(MODULE_LIST_BUFFER_SIZE);
  927. if (List == NULL) {
  928. DBGTEST_ERROR("Error: Failed to malloc %d for loaded modules.\n",
  929. MODULE_LIST_BUFFER_SIZE);
  930. Failures += 1;
  931. goto PrintLoadedModulesEnd;
  932. }
  933. Status = OsDebug(DebugCommandGetLoadedModules,
  934. Child,
  935. NULL,
  936. List,
  937. MODULE_LIST_BUFFER_SIZE,
  938. 0);
  939. if (!KSUCCESS(Status)) {
  940. DBGTEST_ERROR("Error: Failed to get loaded module list. Status %d\n",
  941. Status);
  942. Failures += 1;
  943. goto PrintLoadedModulesEnd;
  944. }
  945. //
  946. // Print the list.
  947. //
  948. DBGTEST_PRINT("Module List: %d modules, signature 0x%I64x:\n",
  949. List->ModuleCount,
  950. List->Signature);
  951. Signature = 0;
  952. Module = (PLOADED_MODULE_ENTRY)(List + 1);
  953. for (ModuleIndex = 0; ModuleIndex < List->ModuleCount; ModuleIndex += 1) {
  954. if (Module->StructureSize < sizeof(LOADED_MODULE_ENTRY)) {
  955. DBGTEST_ERROR("DbgTest: Module %d had size %d, shouldn't have "
  956. "been less than %d.\n",
  957. ModuleIndex,
  958. Module->StructureSize,
  959. sizeof(LOADED_MODULE_ENTRY));
  960. Failures += 1;
  961. goto PrintLoadedModulesEnd;
  962. }
  963. DBGTEST_PRINT(" %d: %20s StructSize %2d Timestamp %I64x "
  964. "LowestAddress %8I64x Size %I64x Process %x\n",
  965. ModuleIndex,
  966. Module->BinaryName,
  967. Module->StructureSize,
  968. Module->Timestamp,
  969. Module->LowestAddress,
  970. Module->Size,
  971. Module->Process);
  972. Signature += Module->Timestamp + Module->LowestAddress;
  973. NameLength = RtlStringLength(Module->BinaryName) + 1;
  974. ComputedStructureLength = sizeof(LOADED_MODULE_ENTRY) + NameLength -
  975. (ANYSIZE_ARRAY * sizeof(CHAR));
  976. if (Module->StructureSize != ComputedStructureLength) {
  977. DBGTEST_ERROR("DbgTest: Module structure size was reported as "
  978. "%x but seems to actually be %x.\n",
  979. Module->StructureSize,
  980. ComputedStructureLength);
  981. Failures += 1;
  982. }
  983. Module = (PVOID)Module + Module->StructureSize;
  984. }
  985. if (Signature != List->Signature) {
  986. DBGTEST_ERROR("DbgTest: Module signature was reported as %x but "
  987. "seems to actually be %x.\n",
  988. List->Signature,
  989. Signature);
  990. Failures += 1;
  991. }
  992. PrintLoadedModulesEnd:
  993. if (List != NULL) {
  994. free(List);
  995. }
  996. return Failures;
  997. }