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.

572 lines
11 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. stack.c
  5. Abstract:
  6. Dumps the AML Context Structure in Human-Readable-Form (HRF)
  7. Author:
  8. Stephane Plante (splante) 26-Oct-1997
  9. Environment:
  10. User Mode.
  11. Revision History:
  12. --*/
  13. #include "pch.h"
  14. VOID
  15. stackArgument(
  16. IN ULONG_PTR ObjectAddress
  17. )
  18. {
  19. BOOL result;
  20. OBJDATA object;
  21. PUCHAR buffer = NULL;
  22. ULONG returnLength;
  23. //
  24. // Read the object
  25. //
  26. result = ReadMemory(
  27. ObjectAddress,
  28. &object,
  29. sizeof(OBJDATA),
  30. &returnLength
  31. );
  32. if (!result || returnLength != sizeof(OBJDATA)) {
  33. dprintf("_BAD_");
  34. return;
  35. }
  36. if (object.pbDataBuff != 0) {
  37. buffer = LocalAlloc( LPTR, object.dwDataLen+1 );
  38. if (buffer == NULL) {
  39. dprintf("_MEM_");
  40. return;
  41. }
  42. result = ReadMemory(
  43. (ULONG_PTR) object.pbDataBuff,
  44. buffer,
  45. object.dwDataLen,
  46. &returnLength
  47. );
  48. if (!result || returnLength != object.dwDataLen) {
  49. dprintf("_BUF_");
  50. return;
  51. }
  52. }
  53. switch (object.dwDataType) {
  54. case OBJTYPE_INTDATA:
  55. dprintf("0x%x", object.uipDataValue);
  56. break;
  57. case OBJTYPE_STRDATA:
  58. buffer[object.dwDataLen] = '\0';
  59. dprintf("%s",buffer);
  60. break;
  61. case OBJTYPE_BUFFDATA:
  62. dprintf(
  63. "<buffer> %08lx-%08lx",
  64. object.pbDataBuff,
  65. object.pbDataBuff+object.dwDataLen
  66. );
  67. break;
  68. case OBJTYPE_PKGDATA:
  69. dprintf("<package> %08lx", ObjectAddress );
  70. break;
  71. case OBJTYPE_FIELDUNIT:
  72. dprintf("<fieldunit> %08lx", ObjectAddress );
  73. break;
  74. case OBJTYPE_DEVICE:
  75. dprintf("<device> %08lx", ObjectAddress );
  76. break;
  77. case OBJTYPE_EVENT:
  78. dprintf("<event> %08lx", ObjectAddress );
  79. break;
  80. case OBJTYPE_METHOD:
  81. dprintf("<method> %08lx", ObjectAddress );
  82. break;
  83. case OBJTYPE_MUTEX:
  84. dprintf("<mutex> %08lx", ObjectAddress );
  85. break;
  86. case OBJTYPE_OPREGION:
  87. dprintf("<opregion> %08lx", ObjectAddress );
  88. break;
  89. case OBJTYPE_POWERRES:
  90. dprintf("<powerres> %08lx", ObjectAddress );
  91. break;
  92. case OBJTYPE_PROCESSOR:
  93. dprintf("<processor> %08lx", ObjectAddress );
  94. break;
  95. case OBJTYPE_THERMALZONE:
  96. dprintf("<thermalzone> %08lx", ObjectAddress );
  97. break;
  98. case OBJTYPE_BUFFFIELD:
  99. dprintf("<bufffield> %08lx", ObjectAddress );
  100. break;
  101. case OBJTYPE_DDBHANDLE:
  102. dprintf("<ddbhandle> %08lx", ObjectAddress );
  103. break;
  104. case OBJTYPE_DEBUG:
  105. dprintf("<debug> %08lx", ObjectAddress );
  106. break;
  107. case OBJTYPE_DATAALIAS:
  108. dprintf("<dataalias> %08lx", ObjectAddress );
  109. break;
  110. case OBJTYPE_BANKFIELD:
  111. dprintf("<bankfield> %08lx", ObjectAddress );
  112. break;
  113. case OBJTYPE_FIELD:
  114. dprintf("<field> %08lx", ObjectAddress );
  115. break;
  116. case OBJTYPE_INDEXFIELD:
  117. dprintf("<indexfield> %08lx", ObjectAddress );
  118. break;
  119. default:
  120. dprintf("<unknown> %08lx", ObjectAddress );
  121. break;
  122. }
  123. }
  124. VOID
  125. stackCall(
  126. IN ULONG_PTR CallAddress
  127. )
  128. /*++
  129. Format Displayed:
  130. ResultAddress MethodName( Arg0, ..., ArgN )
  131. --*/
  132. {
  133. ULONG_PTR address;
  134. BOOL result;
  135. CALL call;
  136. INT i;
  137. NSOBJ object;
  138. PUCHAR objectPath;
  139. ULONG returnLength;
  140. result = ReadMemory(
  141. CallAddress,
  142. &call,
  143. sizeof(CALL),
  144. &returnLength
  145. );
  146. if (result != TRUE ||
  147. returnLength != sizeof(CALL) ||
  148. call.FrameHdr.dwSig != SIG_CALL) {
  149. dprintf(
  150. "stackCall: --- Coult not read call frame %08lx\n",
  151. CallAddress
  152. );
  153. return;
  154. }
  155. if (call.pnsMethod == NULL) {
  156. dprintf( "%08lx --- No method\n", CallAddress );
  157. return;
  158. }
  159. //
  160. // Display result address
  161. //
  162. dprintf("CALL %08lx ", CallAddress );
  163. //
  164. // Display the function name
  165. //
  166. objectPath = stackGetObjectPath( (ULONG_PTR) call.pnsMethod );
  167. dprintf("%s(", objectPath);
  168. //
  169. // Display all parsed arguments;
  170. //
  171. for (i = 0; i < call.iArg; i++) {
  172. //
  173. // What is the address of the argument
  174. //
  175. address = (ULONG_PTR) &call.pdataArgs[i];
  176. //
  177. // Display that argument
  178. //
  179. stackArgument(
  180. address
  181. );
  182. if (i < (call.icArgs - 1)) {
  183. dprintf(",");
  184. }
  185. }
  186. //
  187. // Let the user know how many unprocessed arguments there are
  188. //
  189. for (; i < call.icArgs; i++) {
  190. dprintf("_???_");
  191. if (i < (call.icArgs-1)) {
  192. dprintf(",");
  193. }
  194. }
  195. dprintf(")\n");
  196. }
  197. PUCHAR
  198. stackGetAmlTermPath(
  199. IN ULONG_PTR AmlTermAddress
  200. )
  201. {
  202. AMLTERM amlTerm;
  203. BOOL result;
  204. static UCHAR termPath[2049];
  205. ULONG i;
  206. ULONG resultLength;
  207. result = ReadMemory(
  208. AmlTermAddress,
  209. &amlTerm,
  210. sizeof(AMLTERM),
  211. &resultLength
  212. );
  213. if (!result || resultLength != sizeof(AMLTERM)) {
  214. return NULL;
  215. }
  216. if (amlTerm.pszTermName == NULL) {
  217. return NULL;
  218. }
  219. result = ReadMemory(
  220. (ULONG_PTR) amlTerm.pszTermName,
  221. &termPath,
  222. 2048,
  223. &resultLength
  224. );
  225. if (!result || resultLength == 0) {
  226. return NULL;
  227. }
  228. termPath[resultLength] = '\0';
  229. return termPath;
  230. }
  231. PUCHAR
  232. stackGetObjectPath(
  233. IN ULONG_PTR ObjectAddress
  234. )
  235. {
  236. BOOL result;
  237. NSOBJ object;
  238. static UCHAR namePath[2049];
  239. ULONG i;
  240. ULONG resultLength;
  241. //
  242. // Read the object
  243. //
  244. result = ReadMemory(
  245. ObjectAddress,
  246. &object,
  247. sizeof(NSOBJ),
  248. &resultLength
  249. );
  250. if (!result || resultLength != sizeof(NSOBJ)) {
  251. return NULL;
  252. }
  253. if (object.pnsParent == NULL) {
  254. strcpy( namePath, "\\");
  255. } else {
  256. NSOBJ parent;
  257. stackGetObjectPath( (ULONG_PTR) object.pnsParent );
  258. result = ReadMemory(
  259. (ULONG_PTR) object.pnsParent,
  260. &parent,
  261. sizeof(NSOBJ),
  262. &resultLength
  263. );
  264. if (!result || resultLength != sizeof(NSOBJ)) {
  265. return NULL;
  266. }
  267. if (parent.pnsParent != NULL) {
  268. strcat(namePath, ".");
  269. }
  270. strncat( namePath, (PUCHAR) &(object.dwNameSeg), sizeof(NAMESEG) );
  271. for (i = strlen(namePath); i > 0; --i) {
  272. if (namePath[i-1] == '_') {
  273. namePath[i-1] = '\0';
  274. } else {
  275. break;
  276. }
  277. }
  278. }
  279. return namePath;
  280. }
  281. VOID
  282. stackTerm(
  283. IN ULONG_PTR TermAddress
  284. )
  285. /*++
  286. Format Displayed:
  287. term TermAddress TermName( Arg0, ..., ArgN )
  288. --*/
  289. {
  290. ULONG_PTR address;
  291. BOOL result;
  292. INT i;
  293. NSOBJ object;
  294. PUCHAR objectPath;
  295. TERM term;
  296. ULONG returnLength;
  297. result = ReadMemory(
  298. TermAddress,
  299. &term,
  300. sizeof(TERM),
  301. &returnLength
  302. );
  303. if (result != TRUE ||
  304. returnLength != sizeof(TERM) ||
  305. term.FrameHdr.dwSig != SIG_TERM) {
  306. dprintf(
  307. "stackTerm: --- Coult not read call frame %08lx\n",
  308. TermAddress
  309. );
  310. return;
  311. }
  312. if (term.pamlterm == NULL) {
  313. dprintf( "%08lx --- No term\n", TermAddress );
  314. return;
  315. }
  316. //
  317. // Display result address
  318. //
  319. dprintf("TERM %08lx ", TermAddress );
  320. //
  321. // Display the function name
  322. //
  323. objectPath = stackGetAmlTermPath( (ULONG_PTR) term.pamlterm );
  324. dprintf("%s(", objectPath);
  325. //
  326. // Display all parsed arguments;
  327. //
  328. for (i = 0; i < term.iArg; i++) {
  329. //
  330. // What is the address of the argument
  331. //
  332. address = (ULONG_PTR) &term.pdataArgs[i];
  333. //
  334. // Display that argument
  335. //
  336. stackArgument(
  337. address
  338. );
  339. if (i < (term.icArgs - 1)) {
  340. dprintf(",");
  341. }
  342. }
  343. //
  344. // Let the user know how many unprocessed arguments there are
  345. //
  346. for (; i < term.icArgs; i++) {
  347. dprintf("_???_");
  348. if (i < (term.icArgs-1)) {
  349. dprintf(",");
  350. }
  351. }
  352. dprintf(")\n");
  353. }
  354. VOID
  355. stackTrace(
  356. IN ULONG_PTR ContextAddress,
  357. IN ULONG Verbose
  358. )
  359. /*++
  360. Routine Description:
  361. This routine dumps a context as a stack
  362. Arguments:
  363. ContextAddress - Where the stack is located
  364. Verbose - How much information to display
  365. Return Value:
  366. None
  367. --*/
  368. {
  369. BOOL callSeen = FALSE;
  370. BOOL result;
  371. CTXT context;
  372. FRAMEHDR frame;
  373. PUCHAR frameAddress;
  374. ULONG returnLength;
  375. //
  376. // Read the context from the target
  377. //
  378. result = ReadMemory(
  379. ContextAddress,
  380. &context,
  381. sizeof(CTXT),
  382. &returnLength
  383. );
  384. if (result != TRUE || returnLength != sizeof(CTXT)) {
  385. dprintf(
  386. "stackTrace: --- Could not read Context %08lx\n",
  387. ContextAddress
  388. );
  389. return;
  390. }
  391. if (context.dwSig != SIG_CTXT) {
  392. dprintf(
  393. "stackTrace: --- Not a Context (%08lx)\n",
  394. context.dwSig
  395. );
  396. return;
  397. }
  398. //
  399. // Begin to walk the frames
  400. //
  401. frameAddress = context.LocalHeap.pbHeapEnd;
  402. while (frameAddress < context.pbCtxtEnd) {
  403. result = ReadMemory(
  404. (ULONG_PTR) frameAddress,
  405. &frame,
  406. sizeof(FRAMEHDR),
  407. &returnLength
  408. );
  409. if (result != TRUE || returnLength != sizeof(FRAMEHDR)) {
  410. dprintf(
  411. "stackTrace: --- could not read frame %08lx\n",
  412. frameAddress
  413. );
  414. return;
  415. }
  416. //
  417. // Do we care about the frame?
  418. //
  419. switch(frame.dwSig) {
  420. case SIG_CALL:
  421. callSeen = TRUE;
  422. stackCall(
  423. (ULONG_PTR) frameAddress
  424. );
  425. break;
  426. case SIG_TERM:
  427. if (!callSeen || (callSeen && Verbose)) {
  428. stackTerm(
  429. (ULONG_PTR) frameAddress
  430. );
  431. }
  432. } // switch
  433. //
  434. // Next
  435. //
  436. frameAddress += frame.dwLen;
  437. }
  438. }