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.

650 lines
17 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1995 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: newdpf.c
  6. * Content: new debug printf
  7. *@@BEGIN_MSINTERNAL
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 10-oct-95 jeffno initial implementation
  12. *@@END_MSINTERNAL
  13. *
  14. ***************************************************************************/
  15. #if defined(DEBUG) || defined(DBG)
  16. #ifdef IS_16
  17. #define OUTPUTDEBUGSTRING OutputDebugString
  18. #define GETPROFILESTRING GetProfileString
  19. #define GETPROFILEINT GetProfileInt
  20. #define WSPRINTF wsprintf
  21. #define WVSPRINTF wvsprintf
  22. #define LSTRLEN lstrlen
  23. #else
  24. #define OUTPUTDEBUGSTRING OutputDebugStringA
  25. #define GETPROFILESTRING GetProfileStringA
  26. #define GETPROFILEINT GetProfileIntA
  27. #define WSPRINTF wsprintfA
  28. #define WVSPRINTF wvsprintfA
  29. #define LSTRLEN lstrlenA
  30. #endif
  31. #include "dpf.h"
  32. #undef DEBUG_TOPIC
  33. #define DEBUG_TOPIC(flag,name) {#flag,name,TRUE},
  34. static
  35. struct {
  36. char cFlag[4];
  37. char cName[64];
  38. BOOL bOn;
  39. } DebugTopics[] = {
  40. {"","Filler",FALSE},
  41. {"A","API Usage",TRUE},
  42. #include "DBGTOPIC.H"
  43. {"","End",FALSE}
  44. };
  45. #ifndef PROF_SECT
  46. #define PROF_SECT "Direct3D"
  47. #endif
  48. #ifndef PROF_SECT_D3D
  49. #define PROF_SECT_D3D "Direct3D"
  50. #endif
  51. #ifndef START_STR_D3D
  52. #define START_STR_D3D "Direct3D8: "
  53. #endif
  54. #define END_STR "\r\n"
  55. #undef DPF_MODULE_NAME
  56. #define DPF_MODULE_NAME "Direct3D8: "
  57. static DWORD bDetailOn = 1;
  58. static BOOL bInited=FALSE;
  59. static BOOL bAllowMisc=TRUE;
  60. static bBreakOnAsserts=FALSE;
  61. static bPrintLineNumbers=FALSE;
  62. static bPrintFileNames=FALSE;
  63. static bPrintExecutableName=FALSE;
  64. static bPrintTID=FALSE;
  65. static bPrintPID=FALSE;
  66. static bIndentOnMessageLevel=FALSE;
  67. static bPrintTopicsAndLevels=FALSE;
  68. static bPrintModuleName=TRUE;
  69. static bPrintFunctionName=FALSE;
  70. static bRespectColumns=FALSE;
  71. static bPrintAPIStats=FALSE;
  72. static bPrintAllTopics=TRUE;
  73. static bAdvancedDPFs=FALSE;
  74. static DWORD dwFileLineTID=0;
  75. static char cFile[100];
  76. static char cFnName[100];
  77. static DWORD dwLineNo;
  78. static bMute=FALSE;
  79. // Debug level for D3D
  80. LONG lD3dDebugLevel = 0;
  81. DPF_PROC_STATS ProcStats[MAX_PROC_ORDINAL];
  82. #ifdef cplusplus
  83. extern "C" {
  84. #endif
  85. void mystrncpy(char * to,char * from,int n)
  86. {
  87. for(;n;n--)
  88. *(to++)=*(from++);
  89. }
  90. char * mystrrchr(char * in,char c)
  91. {
  92. char * last=0;
  93. while (*in)
  94. {
  95. if (*in == c)
  96. last = in;
  97. in++;
  98. }
  99. return last;
  100. }
  101. char Junk[]="DPF_MODNAME undef'd";
  102. char * DPF_MODNAME = Junk;
  103. int DebugSetFileLineEtc(LPSTR szFile, DWORD dwLineNumber, LPSTR szFnName)
  104. {
  105. if (!(bPrintFileNames||bPrintLineNumbers||bPrintFunctionName))
  106. {
  107. return 1;
  108. }
  109. #ifdef WIN32
  110. dwFileLineTID = GetCurrentThreadId();
  111. #endif
  112. mystrncpy (cFile,szFile,sizeof(cFile));
  113. mystrncpy (cFnName,szFnName,sizeof(cFnName));
  114. dwLineNo = dwLineNumber;
  115. return 1;
  116. }
  117. static void dumpStr( LPSTR str )
  118. {
  119. /*
  120. * Have to warm the string, since OutputDebugString is buried
  121. * deep enough that it won't page the string in before reading it.
  122. */
  123. int i=0;
  124. if (str)
  125. while(str[i])
  126. i++;
  127. OUTPUTDEBUGSTRING( str );
  128. OUTPUTDEBUGSTRING("\n");
  129. }
  130. void DebugPrintfInit(void)
  131. {
  132. signed int lDebugLevel;
  133. int i;
  134. char cTopics[100];
  135. lD3dDebugLevel = GetProfileInt( PROF_SECT_D3D, "debug", 0 );
  136. bDetailOn=1;
  137. for (i=0;i<LAST_TOPIC;i++)
  138. DebugTopics[i].bOn=FALSE;
  139. //ZeroMemory(ProcStats,sizeof(ProcStats));
  140. GETPROFILESTRING( "DirectX", DPF_CONTROL_LINE, "DefaultTopics", cTopics, sizeof(cTopics) );
  141. if (!strcmp(cTopics,"DefaultTopics"))
  142. {
  143. DebugSetTopicsAndLevels("");
  144. bAllowMisc=TRUE;
  145. bPrintAllTopics=TRUE;
  146. lDebugLevel = (signed int) GETPROFILEINT( PROF_SECT, "debug", 0 );
  147. if (lDebugLevel <0)
  148. {
  149. if (lDebugLevel < -9)
  150. lDebugLevel=-9;
  151. bDetailOn |= (1<<(-lDebugLevel));
  152. }
  153. else
  154. {
  155. for (i=0;i<= (lDebugLevel<10?lDebugLevel:10);i++)
  156. bDetailOn |= 1<<i;
  157. }
  158. }
  159. else
  160. {
  161. bAdvancedDPFs=TRUE;
  162. DebugSetTopicsAndLevels(cTopics);
  163. if (!strcmp(cTopics,"?") && !bInited)
  164. {
  165. dumpStr("--------------" DPF_MODULE_NAME " Debug Output Control -------------");
  166. dumpStr("Each character on the control line controls a topic, a detail");
  167. dumpStr("level or an extra info. E.g. 0-36A@ means print detail levels 0");
  168. dumpStr("through 3 and 6 for topic A with source file name and line numbers.");
  169. dumpStr("The extra info control characters are:");
  170. dumpStr(" !: Break on asserts");
  171. dumpStr(" ^: Print TID of calling thread");
  172. dumpStr(" #: Print PID of calling process");
  173. dumpStr(" >: Indent on message detail levels");
  174. dumpStr(" &: Print the topic and detail level of each message");
  175. dumpStr(" =: Print function name");
  176. dumpStr(" +: Print all topics, including topic-less");
  177. dumpStr(" / or -: do not allow topic-less messages");
  178. dumpStr(" @ or $: Print source filename and line number of DPF");
  179. dumpStr("Topics for this module are:");
  180. for(i=0;strcmp(DebugTopics[i].cName,"End");i++)
  181. {
  182. OUTPUTDEBUGSTRING(" ");
  183. OUTPUTDEBUGSTRING(DebugTopics[i].cFlag);
  184. OUTPUTDEBUGSTRING(": ");
  185. dumpStr(DebugTopics[i].cName);
  186. }
  187. dumpStr("Tip: Use 0-3A to get debug info about API calls");
  188. }
  189. }
  190. bInited=TRUE;
  191. }
  192. /*
  193. *
  194. * The full output can be:
  195. * Module:(Executable,TxNNNN,PxNN):FunctionName:"file.c",#nnn(AAnn) Messagemessagemessage
  196. * or, if indentation turned on:
  197. * Module:(Executable,TxNNNN,PxNN):FunctionName:"file.c",#nnn(AAnn) Messagemessagemessage
  198. */
  199. int DebugPrintf(DWORD dwDetail, ...)
  200. {
  201. #define MSGBUFFERSIZE 1000
  202. BOOL bAllowed=FALSE;
  203. BOOL bMiscMessage=TRUE;
  204. char cMsg[MSGBUFFERSIZE];
  205. char cTopics[20];
  206. DWORD_PTR arg;
  207. LPSTR szFormat;
  208. int i;
  209. #ifdef WIN95
  210. char szTemp[MSGBUFFERSIZE];
  211. char *psz = NULL;
  212. #endif
  213. va_list ap;
  214. if (!bInited)
  215. DebugPrintfInit();
  216. //error checking:
  217. if (dwDetail >= 10)
  218. return 1;
  219. if ( (bDetailOn & (1<<dwDetail)) == 0 )
  220. return 1;
  221. if (bMute)
  222. return 1;
  223. va_start(ap,dwDetail);
  224. WSPRINTF(cTopics,"%d",dwDetail);
  225. //Pull out which topics this DPF refers to
  226. while ( (arg = va_arg(ap,DWORD_PTR)) <256 )
  227. {
  228. if (arg>0 && arg < LAST_TOPIC)
  229. {
  230. bMiscMessage=FALSE;
  231. if (DebugTopics[arg].bOn)
  232. bAllowed = TRUE;
  233. }
  234. }
  235. //if this message has no topics, then it's a misc message.
  236. //we turn them on only if allowed (i.e. "-" is not in the enable string).
  237. //And level zero messages are always allowed
  238. if (bMiscMessage)
  239. {
  240. if (bAllowMisc || dwDetail == 0)
  241. bAllowed=TRUE;
  242. }
  243. else
  244. {
  245. //topic-ed message is only allowed if the advanced DPF line is set in [DirectX]
  246. if (!bAdvancedDPFs)
  247. bAllowed=FALSE;
  248. }
  249. //Advanced DPFs have the option ("+") to print every topic
  250. if (bAdvancedDPFs)
  251. {
  252. if ( bPrintAllTopics )
  253. bAllowed=TRUE;
  254. }
  255. if (!bAllowed)
  256. return FALSE;
  257. szFormat = (LPSTR) arg;
  258. cMsg[0]=0;
  259. /*
  260. * Add the module name first
  261. */
  262. if (bPrintModuleName)
  263. {
  264. WSPRINTF( cMsg+strlen(cMsg),DPF_MODULE_NAME);
  265. }
  266. if (dwDetail==0)
  267. {
  268. WSPRINTF( cMsg+strlen(cMsg),"(ERROR) :" );
  269. }
  270. if (dwDetail==1)
  271. {
  272. WSPRINTF( cMsg+strlen(cMsg),"(WARN) :" );
  273. }
  274. if (dwDetail==2)
  275. {
  276. WSPRINTF( cMsg+strlen(cMsg),"(INFO) :" );
  277. }
  278. if (bPrintExecutableName || bPrintTID || bPrintPID)
  279. WSPRINTF( cMsg+strlen(cMsg),"(");
  280. #ifdef WIN32
  281. #if 0
  282. /*
  283. * deleted due to RIP in GetModuleFilename on debug windows when win16 lock held
  284. */
  285. if (bPrintExecutableName)
  286. {
  287. GetModuleFileName(NULL,str,256);
  288. if (mystrrchr(str,'\\'))
  289. WSPRINTF(cMsg+strlen(cMsg),"%12s",mystrrchr(str,'\\')+1);
  290. }
  291. #endif
  292. if (bPrintPID)
  293. {
  294. if (bPrintExecutableName)
  295. strcat(cMsg,",");
  296. WSPRINTF( cMsg+strlen(cMsg),"Px%02x",GetCurrentProcessId());
  297. }
  298. if (bPrintTID)
  299. {
  300. if (bPrintExecutableName || bPrintPID)
  301. strcat(cMsg,",");
  302. WSPRINTF( cMsg+strlen(cMsg),"Tx%04x",GetCurrentThreadId());
  303. }
  304. if (bPrintExecutableName || bPrintTID || bPrintPID)
  305. WSPRINTF( cMsg+strlen(cMsg),"):");
  306. #endif
  307. if (bPrintFunctionName)
  308. {
  309. WSPRINTF( cMsg+strlen(cMsg),cFnName);
  310. }
  311. if (bPrintFileNames || bPrintLineNumbers)
  312. {
  313. if (mystrrchr(cFile,'\\'))
  314. WSPRINTF( cMsg+strlen(cMsg),":%12s",mystrrchr(cFile,'\\')+1 );
  315. else
  316. WSPRINTF( cMsg+strlen(cMsg),":%12s",cFile);
  317. WSPRINTF( cMsg+strlen(cMsg),"@%d",dwLineNo);
  318. }
  319. if (bPrintTopicsAndLevels)
  320. {
  321. WSPRINTF( cMsg+strlen(cMsg),"(%3s)",cTopics);
  322. }
  323. if (cMsg[strlen(cMsg)-1] != ':')
  324. WSPRINTF( cMsg+strlen(cMsg),":");
  325. if (bIndentOnMessageLevel)
  326. {
  327. for(i=0;(DWORD)i<dwDetail;i++)
  328. strcat(cMsg," ");
  329. }
  330. // 7/07/2000(RichGr) - IA64: The %p format specifier that can handle either a 32-bit
  331. // or a 64-bit pointer doesn't work on Win95 or Win98 - it's not recognized. So it
  332. // needs to be replaced in Win9x builds.
  333. #ifdef WIN95
  334. strcpy(szTemp, szFormat); // Copy to a local string that we can modify.
  335. //////////////////////////////////////////////////////////////////////////////////////////////
  336. //WARNING: This code does not handle escape sequences using %p. Extra code must be added to
  337. // deal with that case if necessary
  338. //////////////////////////////////////////////////////////////////////////////////////////////
  339. while (psz = strstr(szTemp, "%p")) // Look for each "%p".
  340. *(psz+1) = 'x'; // Substitute 'x' for 'p'. Don't try to expand the string.
  341. WVSPRINTF( cMsg+LSTRLEN( cMsg ), szTemp, ap); // Use the local, modified string.
  342. #else
  343. WVSPRINTF( cMsg+LSTRLEN( cMsg ), szFormat, ap); // Standard code for Win2K/Whistler/IA64.
  344. #endif
  345. if (bAllowed)
  346. dumpStr( cMsg );
  347. va_end(ap);
  348. return 1;
  349. }
  350. void DebugSetMute(BOOL bMuteFlag)
  351. {
  352. bMute=bMuteFlag;
  353. }
  354. void DebugEnterAPI(char *pFunctionName , LPDWORD pIface)
  355. {
  356. DebugPrintf(2,A,"%08x->%s",pIface,pFunctionName);
  357. }
  358. void DebugSetTopicsAndLevels(char * cTopics)
  359. {
  360. int i;
  361. int j;
  362. bAllowMisc=TRUE;
  363. bBreakOnAsserts=FALSE;
  364. bPrintLineNumbers=FALSE;
  365. bPrintFileNames=FALSE;
  366. bPrintExecutableName=FALSE;
  367. bPrintTID=FALSE;
  368. bPrintPID=FALSE;
  369. bIndentOnMessageLevel=FALSE;
  370. bPrintTopicsAndLevels=FALSE;
  371. bPrintFunctionName=FALSE;
  372. bPrintAPIStats=FALSE;
  373. bPrintAllTopics=FALSE;
  374. bDetailOn=1; /* always print detail level 0*/
  375. for (i=0;(DWORD)i<strlen(cTopics);i++)
  376. {
  377. switch (cTopics[i])
  378. {
  379. case '/':
  380. case '-':
  381. bAllowMisc=FALSE;
  382. break;
  383. case '!':
  384. bBreakOnAsserts=TRUE;
  385. break;
  386. case '@':
  387. bPrintLineNumbers=TRUE;
  388. break;
  389. case '$':
  390. bPrintFileNames=TRUE;
  391. break;
  392. #if 0
  393. /*
  394. * Currently deleted because GetModuleFilename causes a RIP on debug windows when the win16
  395. * lock is held.
  396. */
  397. case '?':
  398. bPrintExecutableName=TRUE;
  399. break;
  400. #endif
  401. case '^':
  402. bPrintTID=TRUE;
  403. break;
  404. case '#':
  405. bPrintPID=TRUE;
  406. break;
  407. case '>':
  408. bIndentOnMessageLevel=TRUE;
  409. break;
  410. case '&':
  411. bPrintTopicsAndLevels=TRUE;
  412. break;
  413. case '=':
  414. bPrintFunctionName=TRUE;
  415. break;
  416. case '%':
  417. bPrintAPIStats=TRUE;
  418. break;
  419. case '+':
  420. bPrintAllTopics=TRUE;
  421. break;
  422. default:
  423. if (cTopics[i]>='0' && cTopics[i]<='9')
  424. {
  425. if (cTopics[i+1]=='-')
  426. {
  427. if (cTopics[i+2]>='0' && cTopics[i+2]<='9')
  428. {
  429. for(j=cTopics[i]-'0';j<=cTopics[i+2]-'0';j++)
  430. bDetailOn |= 1<<j;
  431. i+=2;
  432. }
  433. }
  434. else
  435. bDetailOn |= 1<<(cTopics[i]-'0');
  436. }
  437. else
  438. {
  439. for(j=0;j<LAST_TOPIC;j++)
  440. if (cTopics[i]==DebugTopics[j].cFlag[0])
  441. DebugTopics[j].bOn=TRUE;
  442. }
  443. } //end switch
  444. }
  445. }
  446. /*
  447. * NOTE: I don't want to get into error checking for buffer overflows when
  448. * trying to issue an assertion failure message. So instead I just allocate
  449. * a buffer that is "bug enough" (I know, I know...)
  450. */
  451. #define ASSERT_BUFFER_SIZE 512
  452. #define ASSERT_BANNER_STRING "************************************************************"
  453. #define ASSERT_BREAK_SECTION "BreakOnAssert"
  454. #define ASSERT_BREAK_DEFAULT FALSE
  455. #define ASSERT_MESSAGE_LEVEL 0
  456. void _DDAssert( LPCSTR szFile, int nLine, LPCSTR szCondition )
  457. {
  458. char buffer[ASSERT_BUFFER_SIZE];
  459. /*
  460. * Build the debug stream message.
  461. */
  462. WSPRINTF( buffer, "ASSERTION FAILED! File %s Line %d: %s", szFile, nLine, szCondition );
  463. /*
  464. * Actually issue the message. These messages are considered error level
  465. * so they all go out at error level priority.
  466. */
  467. dprintf( ASSERT_MESSAGE_LEVEL, ASSERT_BANNER_STRING );
  468. dprintf( ASSERT_MESSAGE_LEVEL, buffer );
  469. dprintf( ASSERT_MESSAGE_LEVEL, ASSERT_BANNER_STRING );
  470. /*
  471. * Should we drop into the debugger?
  472. */
  473. if( bBreakOnAsserts || GETPROFILEINT( PROF_SECT, ASSERT_BREAK_SECTION, ASSERT_BREAK_DEFAULT ) )
  474. {
  475. /*
  476. * Into the debugger we go...
  477. */
  478. DEBUG_BREAK();
  479. }
  480. }
  481. static void cdecl
  482. D3Dprintf( UINT lvl, LPSTR msgType, LPSTR szFormat, va_list ap)
  483. {
  484. char str[256];
  485. //char str2[256];
  486. BOOL allow = FALSE;
  487. if (bMute)
  488. return;
  489. if( lD3dDebugLevel < 0 )
  490. {
  491. if( (UINT) -lD3dDebugLevel == lvl )
  492. {
  493. allow = TRUE;
  494. }
  495. }
  496. else if( (UINT) lD3dDebugLevel >= lvl )
  497. {
  498. allow = TRUE;
  499. }
  500. if( allow )
  501. {
  502. wsprintf( (LPSTR) str, START_STR_D3D );
  503. wsprintf( (LPSTR) str+lstrlen( str ), msgType );
  504. #ifdef WIN95
  505. {
  506. char szTmp[512];
  507. char *psz = szTmp;
  508. strncpy(szTmp, szFormat, 512);
  509. // %p does not work on Windows95.
  510. // We look for each "%p" and substitute 'x' for 'p'
  511. // WARNING: This code does not handle escape sequences using %p.
  512. // Extra code must be added to deal with that case
  513. // if necessary
  514. while (psz = strstr(psz, "%p"))
  515. *(psz+1) = 'x';
  516. wvsprintf( str+lstrlen( str ), szTmp, ap);
  517. }
  518. #else
  519. wvsprintf( str+lstrlen( str ), szFormat, ap); //(LPVOID)(&szFormat+1) );
  520. #endif // WIN95
  521. lstrcat( (LPSTR) str, END_STR );
  522. dumpStr( str );
  523. }
  524. } /* D3Dprintf */
  525. void cdecl
  526. D3DInfoPrintf( UINT lvl, LPSTR szFormat, ...)
  527. {
  528. va_list ap;
  529. va_start(ap, szFormat);
  530. D3Dprintf(lvl, "(INFO) :", szFormat, ap);
  531. va_end(ap);
  532. }
  533. void cdecl
  534. D3DWarnPrintf( UINT lvl, LPSTR szFormat, ...)
  535. {
  536. va_list ap;
  537. va_start(ap,szFormat);
  538. D3Dprintf(lvl, "(WARN) :", szFormat, ap);
  539. va_end(ap);
  540. }
  541. void cdecl
  542. D3DErrorPrintf( LPSTR szFormat, ...)
  543. {
  544. va_list ap;
  545. va_start(ap,szFormat);
  546. D3Dprintf(0, "(ERROR) :", szFormat, ap);
  547. va_end(ap);
  548. }
  549. #ifdef cplusplus
  550. }
  551. #endif
  552. #else // !debug
  553. void DebugSetMute(BOOL bMuteFlag)
  554. {
  555. }
  556. #endif //defined debug