VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/util/error.c@ 53038

最後變更 在這個檔案從53038是 52437,由 vboxsync 提交於 10 年 前

crOpenGL: debugging

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Id
檔案大小: 13.8 KB
 
1/* Copyright (c) 2001, Stanford University
2 * All rights reserved
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7#include "cr_environment.h"
8#include "cr_error.h"
9#include "cr_string.h"
10#include "cr_net.h"
11#include "cr_process.h"
12
13#ifdef WINDOWS
14#define WIN32_LEAN_AND_MEAN
15#include <windows.h>
16#include <io.h>
17#include <fcntl.h>
18#endif
19
20#include <stdio.h>
21#include <stdlib.h>
22#include <stdarg.h>
23#include <signal.h>
24
25#ifndef IN_GUEST
26#define LOG_GROUP LOG_GROUP_SHARED_CROPENGL
27#endif
28#if !defined(IN_GUEST) || defined(CR_DEBUG_BACKDOOR_ENABLE)
29#include <VBox/log.h>
30#endif
31
32#if defined(WINDOWS)
33# define CR_DEBUG_CONSOLE_ENABLE
34
35# include "Shlwapi.h"
36#endif
37
38#if defined(WINDOWS) && defined(IN_GUEST)
39# ifndef CR_DEBUG_BACKDOOR_ENABLE
40# error "CR_DEBUG_BACKDOOR_ENABLE is expected!"
41# endif
42#else
43# ifdef CR_DEBUG_BACKDOOR_ENABLE
44# error "CR_DEBUG_BACKDOOR_ENABLE is NOT expected!"
45# endif
46#endif
47
48
49#ifdef CR_DEBUG_BACKDOOR_ENABLE
50# include <VBoxDispMpLogger.h>
51# include <iprt/err.h>
52#endif
53
54
55static char my_hostname[256];
56#ifdef WINDOWS
57static HANDLE my_pid;
58#else
59static int my_pid = 0;
60#endif
61static int canada = 0;
62static int swedish_chef = 0;
63static int australia = 0;
64static int warnings_enabled = 1;
65
66#ifdef DEBUG_misha
67//int g_VBoxFbgFBreakDdi = 0;
68#define DebugBreak() Assert(0)
69#endif
70
71void __getHostInfo( void )
72{
73 char *temp;
74 /* on windows guests we're typically get called in a context of VBoxOGL!DllMain ( which calls VBoxOGLcrutil!crNetInit ),
75 * which may lead to deadlocks..
76 * Avoid it as it is needed for debugging purposes only */
77#if !defined(IN_GUEST) || !defined(RT_OS_WINDOWS)
78 if ( crGetHostname( my_hostname, sizeof( my_hostname ) ) )
79#endif
80 {
81 crStrcpy( my_hostname, "????" );
82 }
83 temp = crStrchr( my_hostname, '.' );
84 if (temp)
85 {
86 *temp = '\0';
87 }
88 my_pid = crGetPID();
89}
90
91static void __crCheckCanada(void)
92{
93 static int first = 1;
94 if (first)
95 {
96 const char *env = crGetenv( "CR_CANADA" );
97 if (env)
98 canada = 1;
99 first = 0;
100 }
101}
102
103static void __crCheckSwedishChef(void)
104{
105 static int first = 1;
106 if (first)
107 {
108 const char *env = crGetenv( "CR_SWEDEN" );
109 if (env)
110 swedish_chef = 1;
111 first = 0;
112 }
113}
114
115static void __crCheckAustralia(void)
116{
117 static int first = 1;
118 if (first)
119 {
120 const char *env = crGetenv( "CR_AUSTRALIA" );
121 const char *env2 = crGetenv( "CR_AUSSIE" );
122 if (env || env2)
123 australia = 1;
124 first = 0;
125 }
126}
127
128static void outputChromiumMessage( FILE *output, char *str )
129{
130 fprintf( output, "%s%s%s%s\n", str,
131 swedish_chef ? " BORK BORK BORK!" : "",
132 canada ? ", eh?" : "",
133 australia ? ", mate!" : ""
134 );
135 fflush( output );
136}
137
138#ifdef WINDOWS
139static void crRedirectIOToConsole()
140{
141 int hConHandle;
142 HANDLE StdHandle;
143 FILE *fp;
144
145 AllocConsole();
146
147 StdHandle = GetStdHandle(STD_OUTPUT_HANDLE);
148 hConHandle = _open_osfhandle((long)StdHandle, _O_TEXT);
149 fp = _fdopen( hConHandle, "w" );
150 *stdout = *fp;
151 *stderr = *fp;
152
153 StdHandle = GetStdHandle(STD_INPUT_HANDLE);
154 hConHandle = _open_osfhandle((long)StdHandle, _O_TEXT);
155 fp = _fdopen( hConHandle, "r" );
156 *stdin = *fp;
157}
158#endif
159
160
161DECLEXPORT(void) crError(const char *format, ... )
162{
163 va_list args;
164 static char txt[8092];
165 int offset;
166#ifdef WINDOWS
167 DWORD err;
168#endif
169
170 __crCheckCanada();
171 __crCheckSwedishChef();
172 __crCheckAustralia();
173 if (!my_hostname[0])
174 __getHostInfo();
175#ifdef WINDOWS
176 if ((err = GetLastError()) != 0 && crGetenv( "CR_WINDOWS_ERRORS" ) != NULL )
177 {
178 static char buf[8092], *temp;
179
180 SetLastError(0);
181 sprintf( buf, "err=%d", err );
182
183 FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
184 FORMAT_MESSAGE_FROM_SYSTEM |
185 FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, err,
186 MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
187 (LPTSTR) &temp, 0, NULL );
188 if ( temp )
189 {
190 crStrncpy( buf, temp, sizeof(buf)-1 );
191 buf[sizeof(buf)-1] = 0;
192 }
193
194 temp = buf + crStrlen(buf) - 1;
195 while ( temp > buf && isspace( *temp ) )
196 {
197 *temp = '\0';
198 temp--;
199 }
200
201 offset = sprintf( txt, "\t-----------------------\n\tWindows ERROR: %s\n\t----------------------\nCR Error(%s:%d): ", buf, my_hostname, my_pid );
202 }
203 else
204 {
205 offset = sprintf( txt, "OpenGL Error: ");
206 }
207#else
208 offset = sprintf( txt, "OpenGL Error: " );
209#endif
210 va_start( args, format );
211 vsprintf( txt + offset, format, args );
212#if defined(IN_GUEST)
213 crDebug("%s", txt);
214 outputChromiumMessage( stderr, txt );
215#else
216 LogRel(("%s\n", txt));
217#endif
218#ifdef WINDOWS
219 if (crGetenv( "CR_GUI_ERROR" ) != NULL)
220 {
221 MessageBox( NULL, txt, "Chromium Error", MB_OK );
222 }
223 else
224 {
225#endif
226 va_end( args );
227#ifdef WINDOWS
228 }
229#if !defined(DEBUG_leo) && !defined(DEBUG_ll158262) && !defined(DEBUG_misha)
230 if (crGetenv( "CR_DEBUG_ON_ERROR" ) != NULL)
231#endif
232 {
233 DebugBreak();
234 }
235#endif
236
237#ifdef IN_GUEST
238 /* Give chance for things to close down */
239 raise( SIGTERM );
240
241 exit(1);
242#endif
243}
244
245void crEnableWarnings(int onOff)
246{
247 warnings_enabled = onOff;
248}
249
250#ifdef DEBUG_misha
251# undef crWarning
252#endif
253DECLEXPORT(void) crWarning(const char *format, ... )
254{
255 if (warnings_enabled) {
256 va_list args;
257 static char txt[8092];
258 int offset;
259
260 __crCheckCanada();
261 __crCheckSwedishChef();
262 __crCheckAustralia();
263 if (!my_hostname[0])
264 __getHostInfo();
265 offset = sprintf( txt, "OpenGL Warning: ");
266 va_start( args, format );
267 vsprintf( txt + offset, format, args );
268#if defined(IN_GUEST)
269 crDebug("%s", txt);
270 outputChromiumMessage( stderr, txt );
271#else
272 LogRel(("%s\n", txt));
273#endif
274 va_end( args );
275
276#if defined(WINDOWS) && defined(DEBUG) && !defined(IN_GUEST) && defined(DEBUG_misha)
277 DebugBreak();
278#endif
279 }
280}
281
282DECLEXPORT(void) crInfo(const char *format, ... )
283{
284 va_list args;
285 static char txt[8092];
286 int offset;
287
288 __crCheckCanada();
289 __crCheckSwedishChef();
290 __crCheckAustralia();
291 if (!my_hostname[0])
292 __getHostInfo();
293 offset = sprintf( txt, "OpenGL Info: ");
294 va_start( args, format );
295 vsprintf( txt + offset, format, args );
296#if defined(IN_GUEST)
297 crDebug("%s", txt);
298 outputChromiumMessage( stderr, txt );
299#else
300 LogRel(("%s\n", txt));
301#endif
302 va_end( args );
303}
304
305#ifdef CR_DEBUG_BACKDOOR_ENABLE
306static DECLCALLBACK(void) crDebugBackdoorRt(char* pcszStr)
307{
308 RTLogBackdoorPrintf("%s", pcszStr);
309}
310
311static DECLCALLBACK(void) crDebugBackdoorDispMp(char* pcszStr)
312{
313 VBoxDispMpLoggerLog(pcszStr);
314}
315#endif
316
317
318#if defined(WINDOWS) /* && (!defined(DEBUG_misha) || !defined(IN_GUEST) ) */
319# define CR_DEBUG_DBGPRINT_ENABLE
320#endif
321
322#ifdef CR_DEBUG_DBGPRINT_ENABLE
323static void crDebugDbgPrint(const char *str)
324{
325 OutputDebugString(str);
326 OutputDebugString("\n");
327}
328
329static void crDebugDbgPrintF(const char * szString, ...)
330{
331 char szBuffer[4096] = {0};
332 va_list pArgList;
333 va_start(pArgList, szString);
334 vsprintf( szBuffer, szString, pArgList );
335 va_end(pArgList);
336
337 OutputDebugStringA(szBuffer);
338}
339
340static void crDebugDmlPrint(const char* pszDesc, const char* pszCmd)
341{
342 crDebugDbgPrintF("<?dml?><exec cmd=\"%s\">%s</exec>, ( %s )\n", pszCmd, pszDesc, pszCmd);
343}
344
345
346DECLEXPORT(void) crDbgCmdPrint(const char *description1, const char *description2, const char *cmd, ...)
347{
348 va_list args;
349 char aTxt[8092];
350 char aCmd[8092];
351
352 sprintf( aTxt, "%s%s", description1, description2 );
353
354 va_start( args, cmd );
355
356 vsprintf( aCmd, cmd, args );
357
358 va_end( args );
359
360 crDebugDmlPrint(aTxt, aCmd);
361
362 crDebug("%s: %s", aTxt, aCmd);
363}
364
365DECLEXPORT(void) crDbgCmdSymLoadPrint(const char *modName, const void*pvAddress)
366{
367 static bool fEnable = false;
368 static bool fInitialized = false;
369 const char * pszName;
370 static const char * pszModulePath = NULL;
371
372 if (!fInitialized)
373 {
374#ifndef DEBUG_misha
375 if (crGetenv( "CR_DEBUG_MODULE_ENABLE" ))
376#endif
377 {
378 fEnable = true;
379 }
380
381 fInitialized = true;
382 }
383
384 if (!fEnable)
385 return;
386
387 pszName = PathFindFileNameA(modName);
388
389 if (!pszModulePath)
390 pszModulePath = crGetenv("CR_DEBUG_MODULE_PATH");
391 if (!pszModulePath)
392 pszModulePath = "c:\\Users\\senmk\\Downloads\\Data\\Data";
393
394 crDbgCmdPrint("load modules for ", pszName, ".reload /i /f %s\\%s=%#p", pszModulePath, pszName, pvAddress);
395}
396
397#endif
398
399DECLEXPORT(void) crDebug(const char *format, ... )
400{
401 va_list args;
402 static char txt[8092];
403 int offset;
404#ifdef WINDOWS
405 DWORD err;
406#endif
407 static FILE *output;
408 static int first_time = 1;
409 static int silent = 0;
410#ifdef CR_DEBUG_BACKDOOR_ENABLE
411 typedef DECLCALLBACK(void) FNCRGEDUGBACKDOOR(char* pcszStr);
412 typedef FNCRGEDUGBACKDOOR *PFNCRGEDUGBACKDOOR;
413 static PFNCRGEDUGBACKDOOR pfnLogBackdoor = NULL;
414#endif
415#ifdef CR_DEBUG_DBGPRINT_ENABLE
416 static int dbgPrintEnable = 0;
417#endif
418
419 if (first_time)
420 {
421 const char *fname = crGetenv( "CR_DEBUG_FILE" );
422 const char *fnamePrefix = crGetenv( "CR_DEBUG_FILE_PREFIX" );
423 char str[2048];
424#ifdef CR_DEBUG_CONSOLE_ENABLE
425 int logToConsole = 0;
426#endif
427#ifdef CR_DEBUG_BACKDOOR_ENABLE
428 if (crGetenv( "CR_DEBUG_BACKDOOR" ))
429 {
430 int rc = VBoxDispMpLoggerInit();
431 if (RT_SUCCESS(rc))
432 pfnLogBackdoor = crDebugBackdoorDispMp;
433 else
434 pfnLogBackdoor = crDebugBackdoorRt;
435 }
436#endif
437#ifdef CR_DEBUG_DBGPRINT_ENABLE
438 if (crGetenv( "CR_DEBUG_DBGPRINT" ))
439 {
440 dbgPrintEnable = 1;
441 }
442#endif
443
444 if (!fname && fnamePrefix)
445 {
446 char pname[1024];
447 if (crStrlen(fnamePrefix) < sizeof (str) - sizeof (pname) - 20)
448 {
449 crGetProcName(pname, 1024);
450 sprintf(str,
451#ifdef RT_OS_WINDOWS
452 "%s_%s_%u.txt", fnamePrefix, pname, GetCurrentProcessId()
453#else
454 "%s_%s_%lu.txt", fnamePrefix, pname, crGetPID()
455#endif
456 );
457 fname = &str[0];
458 }
459 }
460
461 first_time = 0;
462 if (fname)
463 {
464 char debugFile[2048], *p;
465 crStrcpy(debugFile, fname);
466 p = crStrstr(debugFile, "%p");
467 if (p) {
468 /* replace %p with process number */
469 unsigned long n = (unsigned long) crGetPID();
470 sprintf(p, "%lu", n);
471 }
472 fname = debugFile;
473 output = fopen( fname, "w" );
474 if (!output)
475 {
476 crError( "Couldn't open debug log %s", fname );
477 }
478 }
479 else
480 {
481#ifdef CR_DEBUG_CONSOLE_ENABLE
482 if (crGetenv( "CR_DEBUG_CONSOLE" ))
483 {
484 crRedirectIOToConsole();
485 logToConsole = 1;
486 }
487#endif
488 output = stderr;
489 }
490
491#if !defined(DEBUG)/* || defined(DEBUG_misha)*/
492 /* Release mode: only emit crDebug messages if CR_DEBUG
493 * or CR_DEBUG_FILE is set.
494 */
495 if (!fname && !crGetenv("CR_DEBUG")
496#ifdef CR_DEBUG_CONSOLE_ENABLE
497 && !logToConsole
498#endif
499#ifdef CR_DEBUG_BACKDOOR_ENABLE
500 && !pfnLogBackdoor
501#endif
502#ifdef CR_DEBUG_DBGPRINT_ENABLE
503 && !dbgPrintEnable
504#endif
505 )
506 silent = 1;
507#endif
508 }
509
510 if (silent)
511 return;
512
513 __crCheckCanada();
514 __crCheckSwedishChef();
515 __crCheckAustralia();
516 if (!my_hostname[0])
517 __getHostInfo();
518
519#ifdef WINDOWS
520 if ((err = GetLastError()) != 0 && crGetenv( "CR_WINDOWS_ERRORS" ) != NULL )
521 {
522 static char buf[8092], *temp;
523
524 SetLastError(0);
525 sprintf( buf, "err=%d", err );
526
527 FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
528 FORMAT_MESSAGE_FROM_SYSTEM |
529 FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, err,
530 MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
531 (LPTSTR) &temp, 0, NULL );
532 if ( temp )
533 {
534 crStrncpy( buf, temp, sizeof(buf)-1 );
535 buf[sizeof(buf)-1] = 0;
536 }
537
538 temp = buf + crStrlen(buf) - 1;
539 while ( temp > buf && isspace( *temp ) )
540 {
541 *temp = '\0';
542 temp--;
543 }
544
545 offset = sprintf( txt, "\t-----------------------\n\tWindows ERROR: %s\n\t-----------------\nCR Debug(%s:%d): ", buf, my_hostname, my_pid );
546 }
547 else
548 {
549 offset = sprintf( txt, "[0x%x.0x%x] OpenGL Debug: ", GetCurrentProcessId(), crThreadID());
550 }
551#else
552 offset = sprintf( txt, "[0x%lx.0x%lx] OpenGL Debug: ", crGetPID(), crThreadID());
553#endif
554 va_start( args, format );
555 vsprintf( txt + offset, format, args );
556#ifdef CR_DEBUG_BACKDOOR_ENABLE
557 if (pfnLogBackdoor)
558 {
559 pfnLogBackdoor(txt);
560 }
561#endif
562#ifdef CR_DEBUG_DBGPRINT_ENABLE
563 if (dbgPrintEnable)
564 {
565 crDebugDbgPrint(txt);
566 }
567#endif
568#if defined(IN_GUEST)
569 outputChromiumMessage( output, txt );
570#else
571 if (!output
572#ifndef DEBUG_misha
573 || output==stderr
574#endif
575 )
576 {
577 LogRel(("%s\n", txt));
578 }
579 else
580 {
581 LogRel(("%s\n", txt));
582 outputChromiumMessage(output, txt);
583 }
584#endif
585 va_end( args );
586}
587
588#if defined(DEBUG_misha) && defined(RT_OS_WINDOWS)
589BOOL WINAPI DllMain(HINSTANCE hDLLInst, DWORD fdwReason, LPVOID lpvReserved)
590{
591 (void) lpvReserved;
592
593 switch (fdwReason)
594 {
595 case DLL_PROCESS_ATTACH:
596 {
597 char aName[MAX_PATH];
598 GetModuleFileNameA(hDLLInst, aName, RT_ELEMENTS(aName));
599 crDbgCmdSymLoadPrint(aName, hDLLInst);
600 break;
601 }
602 default:
603 break;
604 }
605
606 return TRUE;
607}
608#endif
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette