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.

472 lines
12 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. udbg.c
  5. Abstract:
  6. Usermode test for debugger
  7. Author:
  8. Mark Lucovsky (markl) 19-Jan-1990
  9. Revision History:
  10. --*/
  11. #include <nt.h>
  12. #include <ntrtl.h>
  13. #include <nturtl.h>
  14. #include <ntdbg.h>
  15. HANDLE DebugPort;
  16. NTSTATUS
  17. ThreadThatExits (
  18. IN PVOID ThreadParameter
  19. )
  20. {
  21. NtTerminateThread(NtCurrentThread(),(NTSTATUS) ThreadParameter );
  22. }
  23. ULONG
  24. foo(PULONG l)
  25. {
  26. //ULONG x;
  27. //x = *l;
  28. //return x + 1;
  29. return *l;
  30. }
  31. NTSTATUS
  32. ThreadThatExcepts (
  33. IN PVOID ThreadParameter
  34. )
  35. {
  36. foo((PULONG)0x00000001);
  37. NtTerminateThread(NtCurrentThread(),(NTSTATUS) ThreadParameter );
  38. }
  39. NTSTATUS
  40. ThreadThatSpins (
  41. IN PVOID ThreadParameter
  42. )
  43. {
  44. for(;;);
  45. NtTerminateThread(NtCurrentThread(),STATUS_SUCCESS);
  46. }
  47. UdbgTest1()
  48. {
  49. NTSTATUS st;
  50. HANDLE ExitThread, SpinThread, DebugProcess;
  51. CLIENT_ID ExitClientId, SpinClientId;
  52. DBGKM_APIMSG m;
  53. PDBGKM_CREATE_THREAD CreateThreadArgs;
  54. PDBGKM_CREATE_PROCESS CreateProcessArgs;
  55. PDBGKM_EXIT_THREAD ExitThreadArgs;
  56. PDBGKM_EXIT_PROCESS ExitProcessArgs;
  57. ULONG Psp;
  58. DbgPrint("UdbgTest1: (1)...\n");
  59. //
  60. // Verify that a process can be created with a debug
  61. // port.
  62. //
  63. st = NtCreateProcess(
  64. &DebugProcess,
  65. PROCESS_ALL_ACCESS,
  66. NULL,
  67. NtCurrentProcess(),
  68. FALSE,
  69. NULL,
  70. DebugPort,
  71. NULL
  72. );
  73. ASSERT(NT_SUCCESS(st));
  74. st = RtlCreateUserThread(
  75. DebugProcess,
  76. NULL,
  77. TRUE,
  78. 0L,
  79. 0L,
  80. 0L,
  81. ThreadThatExits,
  82. (PVOID) STATUS_ABANDONED,
  83. &ExitThread,
  84. &ExitClientId
  85. );
  86. ASSERT(NT_SUCCESS(st));
  87. st = RtlCreateUserThread(
  88. DebugProcess,
  89. NULL,
  90. TRUE,
  91. 0L,
  92. 0L,
  93. 0L,
  94. ThreadThatSpins,
  95. NULL,
  96. &SpinThread,
  97. &SpinClientId
  98. );
  99. ASSERT(NT_SUCCESS(st));
  100. DbgPrint("UdbgTest1: (2)...\n");
  101. //
  102. // Verify that CreateProcess Messages Arrive, and that
  103. // they are correct
  104. //
  105. st = NtResumeThread(SpinThread,NULL);
  106. ASSERT(NT_SUCCESS(st));
  107. st = NtReplyWaitReceivePort(
  108. DebugPort,
  109. NULL,
  110. NULL,
  111. (PPORT_MESSAGE)&m
  112. );
  113. ASSERT(NT_SUCCESS(st));
  114. ASSERT(m.ApiNumber == DbgKmCreateProcessApi);
  115. CreateThreadArgs = &m.u.CreateProcess.InitialThread;
  116. CreateProcessArgs = &m.u.CreateProcess;
  117. ASSERT( CreateThreadArgs->SubSystemKey == 0 && CreateThreadArgs->StartAddress == (PVOID)ThreadThatSpins );
  118. ASSERT( CreateProcessArgs->SubSystemKey == 0);
  119. DbgPrint("UdbgTest1: (3)...\n");
  120. //
  121. // Verify that other threads in the process are properly suspended
  122. //
  123. st = NtSuspendThread(ExitThread,&Psp);
  124. ASSERT(NT_SUCCESS(st) && Psp == 2);
  125. st = NtResumeThread(ExitThread,&Psp);
  126. ASSERT(NT_SUCCESS(st) && Psp == 3);
  127. st = NtReplyPort(DebugPort,(PPORT_MESSAGE)&m);
  128. ASSERT(NT_SUCCESS(st));
  129. DbgPrint("UdbgTest1: (4)...\n");
  130. //
  131. // Verify that CreateThread Messages Arrive, and that
  132. // they are correct
  133. //
  134. st = NtResumeThread(ExitThread,&Psp);
  135. ASSERT(NT_SUCCESS(st));
  136. st = NtReplyWaitReceivePort(
  137. DebugPort,
  138. NULL,
  139. NULL,
  140. (PPORT_MESSAGE)&m
  141. );
  142. ASSERT(NT_SUCCESS(st));
  143. ASSERT(m.ApiNumber == DbgKmCreateThreadApi);
  144. CreateThreadArgs = &m.u.CreateThread;
  145. ASSERT( CreateThreadArgs->SubSystemKey == 0 && CreateThreadArgs->StartAddress == (PVOID)ThreadThatExits );
  146. st = NtReplyPort(DebugPort,(PPORT_MESSAGE)&m);
  147. ASSERT(NT_SUCCESS(st));
  148. DbgPrint("UdbgTest1: (5)...\n");
  149. //
  150. // Verify that ExitThread Messages Arrive, and that
  151. // they are correct
  152. //
  153. st = NtReplyWaitReceivePort(
  154. DebugPort,
  155. NULL,
  156. NULL,
  157. (PPORT_MESSAGE)&m
  158. );
  159. ASSERT(NT_SUCCESS(st));
  160. ASSERT(m.ApiNumber == DbgKmExitThreadApi);
  161. ExitThreadArgs = &m.u.ExitThread;
  162. ASSERT( ExitThreadArgs->ExitStatus == STATUS_ABANDONED );
  163. st = NtReplyPort(DebugPort,(PPORT_MESSAGE)&m);
  164. ASSERT(NT_SUCCESS(st));
  165. st = NtWaitForSingleObject(ExitThread,FALSE,NULL);
  166. ASSERT(NT_SUCCESS(st));
  167. DbgPrint("UdbgTest1: (6)...\n");
  168. //
  169. // Verify that ExitThread Messages Arrive, and that
  170. // they are correct
  171. //
  172. st = NtTerminateProcess(DebugProcess,STATUS_REPARSE);
  173. ASSERT(NT_SUCCESS(st));
  174. st = NtReplyWaitReceivePort(
  175. DebugPort,
  176. NULL,
  177. NULL,
  178. (PPORT_MESSAGE)&m
  179. );
  180. ASSERT(NT_SUCCESS(st));
  181. ASSERT(m.ApiNumber == DbgKmExitThreadApi);
  182. ExitThreadArgs = &m.u.ExitThread;
  183. ASSERT( ExitThreadArgs->ExitStatus == STATUS_REPARSE );
  184. st = NtReplyPort(DebugPort,(PPORT_MESSAGE)&m);
  185. ASSERT(NT_SUCCESS(st));
  186. DbgPrint("UdbgTest1: (7)...\n");
  187. //
  188. // Verify that ExitProcess Messages Arrive, and that
  189. // they are correct
  190. //
  191. st = NtReplyWaitReceivePort(
  192. DebugPort,
  193. NULL,
  194. NULL,
  195. (PPORT_MESSAGE)&m
  196. );
  197. ASSERT(NT_SUCCESS(st));
  198. ASSERT(m.ApiNumber == DbgKmExitProcessApi);
  199. ExitProcessArgs = &m.u.ExitProcess;
  200. ASSERT( ExitProcessArgs->ExitStatus == STATUS_REPARSE );
  201. st = NtReplyPort(DebugPort,(PPORT_MESSAGE)&m);
  202. ASSERT(NT_SUCCESS(st));
  203. st = NtWaitForSingleObject(ExitThread,FALSE,NULL);
  204. ASSERT(NT_SUCCESS(st));
  205. st = NtWaitForSingleObject(DebugProcess,FALSE,NULL);
  206. ASSERT(NT_SUCCESS(st));
  207. NtClose(ExitThread);
  208. NtClose(SpinThread);
  209. NtClose(DebugProcess);
  210. DbgPrint("UdbgTest1: END OF TEST ***\n");
  211. }
  212. UdbgTest2()
  213. {
  214. NTSTATUS st;
  215. HANDLE ExceptionThread, DebugProcess;
  216. DBGKM_APIMSG m;
  217. PDBGKM_CREATE_THREAD CreateThreadArgs;
  218. PDBGKM_CREATE_PROCESS CreateProcessArgs;
  219. PDBGKM_EXIT_THREAD ExitThreadArgs;
  220. PDBGKM_EXIT_PROCESS ExitProcessArgs;
  221. PDBGKM_EXCEPTION ExceptionArgs;
  222. ULONG Psp;
  223. DbgPrint("UdbgTest2: (1)...\n");
  224. //
  225. // Verify that a process can be created with a debug
  226. // port.
  227. //
  228. st = NtCreateProcess(
  229. &DebugProcess,
  230. PROCESS_ALL_ACCESS,
  231. NULL,
  232. NtCurrentProcess(),
  233. FALSE,
  234. NULL,
  235. DebugPort,
  236. NULL
  237. );
  238. ASSERT(NT_SUCCESS(st));
  239. st = RtlCreateUserThread(
  240. DebugProcess,
  241. NULL,
  242. TRUE,
  243. 0L,
  244. 0L,
  245. 0L,
  246. ThreadThatExcepts,
  247. (PVOID) STATUS_ABANDONED,
  248. &ExceptionThread,
  249. NULL
  250. );
  251. ASSERT(NT_SUCCESS(st));
  252. DbgPrint("UdbgTest2: (2)...\n");
  253. //
  254. // Verify that CreateThread Messages Arrive, and that
  255. // they are correct
  256. //
  257. st = NtResumeThread(ExceptionThread,NULL);
  258. ASSERT(NT_SUCCESS(st));
  259. st = NtReplyWaitReceivePort(
  260. DebugPort,
  261. NULL,
  262. NULL,
  263. (PPORT_MESSAGE)&m
  264. );
  265. ASSERT(NT_SUCCESS(st));
  266. ASSERT(m.ApiNumber == DbgKmCreateProcessApi);
  267. CreateThreadArgs = &m.u.CreateProcess.InitialThread;
  268. CreateProcessArgs = &m.u.CreateProcess;
  269. ASSERT( CreateThreadArgs->SubSystemKey == 0 && CreateThreadArgs->StartAddress == (PVOID)ThreadThatExcepts );
  270. ASSERT( CreateProcessArgs->SubSystemKey == 0);
  271. st = NtReplyPort(DebugPort,(PPORT_MESSAGE)&m);
  272. ASSERT(NT_SUCCESS(st));
  273. DbgPrint("UdbgTest2: (3)...\n");
  274. //
  275. // Verify that First Chance Exception Messages Arrive, and that
  276. // they are correct
  277. //
  278. st = NtReplyWaitReceivePort(
  279. DebugPort,
  280. NULL,
  281. NULL,
  282. (PPORT_MESSAGE)&m
  283. );
  284. ASSERT(NT_SUCCESS(st));
  285. ASSERT(m.ApiNumber == DbgKmExceptionApi);
  286. ExceptionArgs = &m.u.Exception;
  287. ASSERT( ExceptionArgs->FirstChance == TRUE );
  288. m.ReturnedStatus = DBG_EXCEPTION_NOT_HANDLED;
  289. st = NtReplyPort(DebugPort,(PPORT_MESSAGE)&m);
  290. ASSERT(NT_SUCCESS(st));
  291. DbgPrint("UdbgTest2: (4)...\n");
  292. //
  293. // Verify that First Chance Exception Messages Arrive, and that
  294. // they are correct
  295. //
  296. st = NtReplyWaitReceivePort(
  297. DebugPort,
  298. NULL,
  299. NULL,
  300. (PPORT_MESSAGE)&m
  301. );
  302. ASSERT(NT_SUCCESS(st));
  303. ASSERT(m.ApiNumber == DbgKmExceptionApi);
  304. ExceptionArgs = &m.u.Exception;
  305. ASSERT( ExceptionArgs->FirstChance == FALSE );
  306. m.ReturnedStatus = DBG_EXCEPTION_HANDLED;
  307. skip4:
  308. st = NtTerminateProcess(DebugProcess,STATUS_REPARSE);
  309. ASSERT(NT_SUCCESS(st));
  310. st = NtReplyPort(DebugPort,(PPORT_MESSAGE)&m);
  311. ASSERT(NT_SUCCESS(st));
  312. st = NtReplyWaitReceivePort(
  313. DebugPort,
  314. NULL,
  315. NULL,
  316. (PPORT_MESSAGE)&m
  317. );
  318. ASSERT(NT_SUCCESS(st));
  319. ASSERT(m.ApiNumber == DbgKmExitThreadApi);
  320. ExitThreadArgs = &m.u.ExitThread;
  321. ASSERT( ExitThreadArgs->ExitStatus == STATUS_REPARSE );
  322. st = NtReplyPort(DebugPort,(PPORT_MESSAGE)&m);
  323. ASSERT(NT_SUCCESS(st));
  324. DbgPrint("UdbgTest2: (5)...\n");
  325. //
  326. // Verify that ExitProcess Messages Arrive, and that
  327. // they are correct
  328. //
  329. st = NtReplyWaitReceivePort(
  330. DebugPort,
  331. NULL,
  332. NULL,
  333. (PPORT_MESSAGE)&m
  334. );
  335. ASSERT(NT_SUCCESS(st));
  336. ASSERT(m.ApiNumber == DbgKmExitProcessApi);
  337. ExitProcessArgs = &m.u.ExitProcess;
  338. ASSERT( ExitProcessArgs->ExitStatus == STATUS_REPARSE );
  339. st = NtReplyPort(DebugPort,(PPORT_MESSAGE)&m);
  340. ASSERT(NT_SUCCESS(st));
  341. st = NtWaitForSingleObject(ExceptionThread,FALSE,NULL);
  342. ASSERT(NT_SUCCESS(st));
  343. st = NtWaitForSingleObject(DebugProcess,FALSE,NULL);
  344. ASSERT(NT_SUCCESS(st));
  345. NtClose(ExceptionThread);
  346. NtClose(DebugProcess);
  347. DbgPrint("UdbgTest2: END OF TEST ***\n");
  348. }
  349. main()
  350. {
  351. NTSTATUS st;
  352. OBJECT_ATTRIBUTES Obja;
  353. InitializeObjectAttributes(&Obja, NULL, 0, NULL, NULL);
  354. st = NtCreatePort(
  355. &DebugPort,
  356. &Obja,
  357. 0L,
  358. 256,
  359. 256 * 16
  360. );
  361. ASSERT(NT_SUCCESS(st));
  362. UdbgTest2();
  363. UdbgTest1();
  364. }