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

442 lines
8.2 KiB

  1. /*++
  2. Copyright (c) 1998-1999 Microsoft Corporation
  3. All rights reserved.
  4. Module Name:
  5. dbgcap.cxx
  6. Abstract:
  7. Debug capture class
  8. Author:
  9. Steve Kiraly (SteveKi) 18-Jun-1998
  10. Revision History:
  11. --*/
  12. #include "precomp.hxx"
  13. #pragma hdrstop
  14. #include "dbgback.hxx"
  15. #include "dbgcap.hxx"
  16. /*++
  17. Title:
  18. TDebugCapture_Create
  19. Routine Description:
  20. Creates a debug capture object, and returns the newly created
  21. caputure device handle.
  22. Arguments:
  23. pszConfiguration - pointe to backtrace configuration string.
  24. uOutputDevice - what device to send the backtrace to.
  25. pszOutputDeviceConfiguration - pointer to output device configuration
  26. string.
  27. Return Value:
  28. Non null handle if successfull, NULL on failure.
  29. --*/
  30. extern "C"
  31. HANDLE
  32. TDebugCapture_Create(
  33. IN LPCTSTR pszCaptureDeviceConfiguration,
  34. IN UINT uOutputDevice,
  35. IN LPCTSTR pszOutputDeviceConfiguration
  36. )
  37. {
  38. HANDLE hHandle = NULL;
  39. //
  40. // The output device cannot be another back trace device.
  41. //
  42. if (uOutputDevice != kDbgBackTrace)
  43. {
  44. //
  45. // Get access to the debug factory.
  46. //
  47. TDebugFactory DebugFactory;
  48. //
  49. // If we failed to create the debug factory then exit.
  50. //
  51. if (DebugFactory.bValid())
  52. {
  53. TDebugDeviceBacktrace *pBackTrace = NULL;
  54. //
  55. // CAUTION: We are down casting, however, we know this is
  56. // safe since the factory was told produce a product of a
  57. // particular kind.
  58. //
  59. // Create the specified debug device using the factory.
  60. //
  61. pBackTrace = reinterpret_cast<TDebugDeviceBacktrace *>(DebugFactory.Produce(kDbgBackTrace,
  62. pszCaptureDeviceConfiguration,
  63. Globals.CompiledCharType));
  64. //
  65. // If the backtrace device was create successfully.
  66. //
  67. if (pBackTrace)
  68. {
  69. //
  70. // Initialize the output device.
  71. //
  72. pBackTrace->InitializeOutputDevice(uOutputDevice,
  73. pszOutputDeviceConfiguration,
  74. Globals.CompiledCharType);
  75. //
  76. // Return a opaque handle.
  77. //
  78. hHandle = pBackTrace;
  79. }
  80. }
  81. }
  82. return hHandle;
  83. }
  84. /*++
  85. Title:
  86. TDebugCapture_Destroy
  87. Routine Description:
  88. Destroys the capture device.
  89. Arguments:
  90. hHandle - opaque handle to backtrace device.
  91. Return Value:
  92. NULL
  93. --*/
  94. extern "C"
  95. HANDLE
  96. TDebugCapture_Destroy(
  97. IN HANDLE hHandle
  98. )
  99. {
  100. TDebugFactory::Dispose(reinterpret_cast<TDebugDevice *>(hHandle));
  101. return NULL;
  102. }
  103. /*++
  104. Title:
  105. TDebugCapture_Capture
  106. Routine Description:
  107. This routine output a format string to the pre configured
  108. output device then captures a stack back, also sending the
  109. output to the pre configured output device.
  110. Arguments:
  111. hHandle - handle to instance of capture device.
  112. uFlags - must be 0 not defined.
  113. pszFile - pointer to string where call was made.
  114. uLine - line number in file where call was made.
  115. pszCapture - pointer to post formated capture string.
  116. Return Value:
  117. Nothing.
  118. --*/
  119. extern "C"
  120. VOID
  121. TDebugCapture_Capture(
  122. IN HANDLE hHandle,
  123. IN UINT uFlags,
  124. IN LPCTSTR pszFile,
  125. IN UINT uLine,
  126. IN LPTSTR pszCapture
  127. )
  128. {
  129. TDebugString strCapture;
  130. //
  131. // Format the pre-capture string.
  132. //
  133. BOOL bRetval = strCapture.bFormat(_T("Capture: %s %d tc=%x tid=%x %s"),
  134. StripPathFromFileName(pszFile),
  135. uLine,
  136. GetTickCount(),
  137. GetCurrentThreadId(),
  138. pszCapture ? pszCapture : kstrNull);
  139. //
  140. // If the capture string was formated.
  141. //
  142. if (bRetval)
  143. {
  144. //
  145. // Hold the critical section while we capture the backtrace.
  146. //
  147. TDebugCriticalSection::TLock CS( GlobalCriticalSection );
  148. TDebugDeviceBacktrace *pBackTrace = reinterpret_cast<TDebugDeviceBacktrace *>(hHandle);
  149. LPBYTE pData = reinterpret_cast<LPBYTE>(const_cast<LPTSTR>(
  150. static_cast<LPCTSTR>(strCapture)));
  151. bRetval = pBackTrace->bOutput(strCapture.uLen() * sizeof(TCHAR), pData);
  152. }
  153. //
  154. // Release the capture string, if the passed in one was valid.
  155. //
  156. INTERNAL_DELETE [] pszCapture;
  157. }
  158. /*++
  159. Title:
  160. TDebugCapture_pszFmt
  161. Routine Description:
  162. Creates a output string from a printf style format
  163. string and argument list.
  164. Arguments:
  165. pszFmt - pointer to printf style format string.
  166. ... - variable number of arguments.
  167. Return Value:
  168. Pointer to output string, caller must free.
  169. --*/
  170. LPTSTR
  171. TDebugCapture_pszFmt(
  172. IN LPCSTR pszFmt,
  173. IN ...
  174. )
  175. {
  176. va_list pArgs;
  177. va_start(pArgs, pszFmt);
  178. LPTSTR pszString = TDebugCapture_pszFmt_Helper(pszFmt, pArgs, FALSE);
  179. va_end(pArgs);
  180. return pszString;
  181. }
  182. /*++
  183. Title:
  184. TDebugCapture_pszFmt
  185. Routine Description:
  186. Creates a output string from a printf style format
  187. string and argument list.
  188. Arguments:
  189. pszFmt - pointer to printf style format string.
  190. ... - variable number of arguments.
  191. Return Value:
  192. Pointer to output string, caller must free.
  193. --*/
  194. LPTSTR
  195. TDebugCapture_pszFmt(
  196. IN LPCWSTR pszFmt,
  197. IN ...
  198. )
  199. {
  200. va_list pArgs;
  201. va_start(pArgs, pszFmt);
  202. LPTSTR pszString = TDebugCapture_pszFmt_Helper(pszFmt, pArgs, TRUE);
  203. va_end(pArgs);
  204. return pszString;
  205. }
  206. /*++
  207. Title:
  208. TDebugCapture_pszFmt
  209. Routine Description:
  210. Creates a output string from a printf style format
  211. string and argument list.
  212. Arguments:
  213. pszFmt - pointer to printf style format string.
  214. ... - variable number of arguments.
  215. Return Value:
  216. Pointer to output string, caller must free.
  217. --*/
  218. extern "C"
  219. LPTSTR
  220. WINAPIV
  221. TDebugCapture_pszFmtA(
  222. IN LPCSTR pszFmt,
  223. IN ...
  224. )
  225. {
  226. va_list pArgs;
  227. va_start(pArgs, pszFmt);
  228. LPTSTR pszString = TDebugCapture_pszFmt_Helper(pszFmt, pArgs, FALSE);
  229. va_end(pArgs);
  230. return pszString;
  231. }
  232. /*++
  233. Title:
  234. TDebugCapture_pszFmt
  235. Routine Description:
  236. Creates a output string from a printf style format
  237. string and argument list.
  238. Arguments:
  239. pszFmt - pointer to printf style format string.
  240. ... - variable number of arguments.
  241. Return Value:
  242. Pointer to output string, caller must free.
  243. --*/
  244. extern "C"
  245. LPTSTR
  246. WINAPIV
  247. TDebugCapture_pszFmtW(
  248. IN LPCWSTR pszFmt,
  249. IN ...
  250. )
  251. {
  252. va_list pArgs;
  253. va_start(pArgs, pszFmt);
  254. LPTSTR pszString = TDebugCapture_pszFmt_Helper(pszFmt, pArgs, TRUE);
  255. va_end(pArgs);
  256. return pszString;
  257. }
  258. /*++
  259. Title:
  260. TDebugCapture_pszFmt_Helper
  261. Routine Description:
  262. Creates a output string from a printf style format
  263. string and pointer to argument list.
  264. Arguments:
  265. pszFmt - pointer to printf style format string.
  266. pArgs - pointer to variable number of arguments.
  267. bUnicode - Flag indicating the provided string is unicode or ansi.
  268. Return Value:
  269. Pointer to output string, caller must free.
  270. --*/
  271. LPTSTR
  272. TDebugCapture_pszFmt_Helper(
  273. IN const VOID *pszFmt,
  274. IN va_list pArgs,
  275. IN BOOL bUnicode
  276. )
  277. {
  278. LPTSTR pString = NULL;
  279. PVOID pszResult = NULL;
  280. if (pszFmt)
  281. {
  282. if (bUnicode)
  283. {
  284. pszResult = vFormatW(reinterpret_cast<LPCWSTR>(pszFmt), pArgs);
  285. }
  286. else
  287. {
  288. pszResult = vFormatA(reinterpret_cast<LPCSTR>(pszFmt), pArgs);
  289. }
  290. if (pszResult)
  291. {
  292. if (bUnicode)
  293. {
  294. (VOID)StringW2T(&pString, reinterpret_cast<LPWSTR>(pszResult));
  295. }
  296. else
  297. {
  298. (VOID)StringA2T(&pString, reinterpret_cast<LPSTR>(pszResult));
  299. }
  300. INTERNAL_DELETE [] pszResult;
  301. }
  302. }
  303. return pString;
  304. }