VirtualBox

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

Last change on this file since 53726 was 53726, checked in by vboxsync, 10 years ago

properties.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 17.4 KB
Line 
1/* $Id: error.c 53726 2015-01-04 05:05:41Z vboxsync $ */
2/** @file
3 * VBox crOpenGL error logging
4 */
5
6/*
7 * Copyright (C) 2014 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17#if 1
18
19#define LOG_GROUP LOG_GROUP_SHARED_CROPENGL
20
21#include <iprt/string.h>
22#include <iprt/stream.h>
23#include <iprt/initterm.h>
24#include <VBox/log.h>
25
26#ifdef RT_OS_WINDOWS
27# include <windows.h>
28# include "cr_environment.h"
29#endif
30
31#include <signal.h>
32#include <stdlib.h>
33
34static void logMessageV(const char *pszPrefix, const char *pszFormat, va_list va)
35{
36 va_list vaCopy;
37 if (RTR3InitIsInitialized())
38 {
39 va_copy(vaCopy, va);
40 LogRel(("%s%N\n", pszPrefix, pszFormat, &vaCopy));
41 va_end(vaCopy);
42 }
43
44#ifdef IN_GUEST /** @todo Could be subject to pre-iprt-init issues, but hopefully not... */
45 va_copy(vaCopy, va);
46 RTStrmPrintf(g_pStdErr, "%s%N\n", pszPrefix, pszFormat, &vaCopy);
47 va_end(vaCopy);
48#endif
49}
50
51static void logMessage(const char *pszPrefix, const char *pszFormat, ...)
52{
53 va_list va;
54
55 va_start(va, pszFormat);
56 logMessageV(pszPrefix, pszFormat, va);
57 va_end(va);
58}
59
60DECLEXPORT(void) crError(const char *pszFormat, ...)
61{
62 va_list va;
63#ifdef WINDOWS
64 DWORD dwLastErr;
65#endif
66
67#ifdef WINDOWS
68 /* Log last error on windows. */
69 dwLastErr = GetLastError();
70 if (dwLastErr != 0 && crGetenv("CR_WINDOWS_ERRORS") != NULL)
71 {
72 LPTSTR pszWindowsMessage;
73
74 SetLastError(0);
75 FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER
76 | FORMAT_MESSAGE_FROM_SYSTEM
77 | FORMAT_MESSAGE_MAX_WIDTH_MASK,
78 NULL, dwLastErr,
79 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
80 (LPTSTR)&pszWindowsMessage, 0, NULL);
81 if (pszWindowsMessage)
82 {
83 logMessage("OpenGL, Windows error: ", "%u\n%s", dwLastErr, pszWindowsMessage);
84 LocalFree(pszWindowsMessage);
85 }
86 else
87 logMessage("OpenGL, Windows error: ", "%u", dwLastErr);
88 }
89#endif
90
91 /* The message. */
92 va_start(va, pszFormat);
93 logMessageV("OpenGL Error: ", pszFormat, va);
94 va_end(va);
95
96 /* Dump core or activate the debugger in debug builds. */
97 AssertFailed();
98
99#ifdef IN_GUEST
100 /* Give things a chance to close down. */
101 raise(SIGTERM);
102 exit(1);
103#endif
104}
105
106DECLEXPORT(void) crWarning(const char *pszFormat, ...)
107{
108 if (RTR3InitIsInitialized())
109 {
110 va_list va;
111
112 va_start(va, pszFormat);
113 logMessageV("OpenGL Warning: ", pszFormat, va);
114 va_end(va);
115 }
116}
117
118DECLEXPORT(void) crInfo(const char *pszFormat, ...)
119{
120 if (RTR3InitIsInitialized())
121 {
122 va_list va;
123
124 va_start(va, pszFormat);
125 logMessageV("OpenGL Info: ", pszFormat, va);
126 va_end(va);
127 }
128}
129
130DECLEXPORT(void) crDebug(const char *pszFormat, ...)
131{
132 if (RTR3InitIsInitialized())
133 {
134 va_list va;
135
136 va_start(va, pszFormat);
137#if defined(DEBUG_vgalitsy) || defined(DEBUG_galitsyn)
138 LogRel(("OpenGL Debug: %N\n", pszFormat, &va));
139#else
140 Log(("OpenGL Debug: %N\n", pszFormat, &va));
141#endif
142 va_end(va);
143 }
144}
145
146#else
147/* Copyright (c) 2001, Stanford University
148 * All rights reserved
149 *
150 * See the file LICENSE.txt for information on redistributing this software.
151 */
152
153#include "cr_environment.h"
154#include "cr_error.h"
155#include "cr_string.h"
156#include "cr_net.h"
157#include "cr_process.h"
158
159#ifdef WINDOWS
160#define WIN32_LEAN_AND_MEAN
161#include <windows.h>
162#include <io.h>
163#include <fcntl.h>
164#endif
165
166#include <stdio.h>
167#include <stdlib.h>
168#include <stdarg.h>
169#include <signal.h>
170
171#ifndef IN_GUEST
172#define LOG_GROUP LOG_GROUP_SHARED_CROPENGL
173#endif
174#if !defined(IN_GUEST) || defined(CR_DEBUG_BACKDOOR_ENABLE)
175#include <VBox/log.h>
176#endif
177
178#if defined(WINDOWS)
179# define CR_DEBUG_CONSOLE_ENABLE
180
181# include "Shlwapi.h"
182#endif
183
184#if defined(WINDOWS) && defined(IN_GUEST)
185# ifndef CR_DEBUG_BACKDOOR_ENABLE
186# error "CR_DEBUG_BACKDOOR_ENABLE is expected!"
187# endif
188#else
189# ifdef CR_DEBUG_BACKDOOR_ENABLE
190# error "CR_DEBUG_BACKDOOR_ENABLE is NOT expected!"
191# endif
192#endif
193
194
195#ifdef CR_DEBUG_BACKDOOR_ENABLE
196# include <VBoxDispMpLogger.h>
197# include <iprt/err.h>
198#endif
199
200
201static char my_hostname[256];
202#ifdef WINDOWS
203static HANDLE my_pid;
204#else
205static int my_pid = 0;
206#endif
207static int canada = 0;
208static int swedish_chef = 0;
209static int australia = 0;
210static int warnings_enabled = 1;
211
212#ifdef DEBUG_misha
213//int g_VBoxFbgFBreakDdi = 0;
214#define DebugBreak() Assert(0)
215#endif
216
217void __getHostInfo( void )
218{
219 char *temp;
220 /* on windows guests we're typically get called in a context of VBoxOGL!DllMain ( which calls VBoxOGLcrutil!crNetInit ),
221 * which may lead to deadlocks..
222 * Avoid it as it is needed for debugging purposes only */
223#if !defined(IN_GUEST) || !defined(RT_OS_WINDOWS)
224 if ( crGetHostname( my_hostname, sizeof( my_hostname ) ) )
225#endif
226 {
227 crStrcpy( my_hostname, "????" );
228 }
229 temp = crStrchr( my_hostname, '.' );
230 if (temp)
231 {
232 *temp = '\0';
233 }
234 my_pid = crGetPID();
235}
236
237static void __crCheckCanada(void)
238{
239 static int first = 1;
240 if (first)
241 {
242 const char *env = crGetenv( "CR_CANADA" );
243 if (env)
244 canada = 1;
245 first = 0;
246 }
247}
248
249static void __crCheckSwedishChef(void)
250{
251 static int first = 1;
252 if (first)
253 {
254 const char *env = crGetenv( "CR_SWEDEN" );
255 if (env)
256 swedish_chef = 1;
257 first = 0;
258 }
259}
260
261static void __crCheckAustralia(void)
262{
263 static int first = 1;
264 if (first)
265 {
266 const char *env = crGetenv( "CR_AUSTRALIA" );
267 const char *env2 = crGetenv( "CR_AUSSIE" );
268 if (env || env2)
269 australia = 1;
270 first = 0;
271 }
272}
273
274static void outputChromiumMessage( FILE *output, char *str )
275{
276 fprintf( output, "%s%s%s%s\n", str,
277 swedish_chef ? " BORK BORK BORK!" : "",
278 canada ? ", eh?" : "",
279 australia ? ", mate!" : ""
280 );
281 fflush( output );
282}
283
284#ifdef WINDOWS
285static void crRedirectIOToConsole()
286{
287 int hConHandle;
288 HANDLE StdHandle;
289 FILE *fp;
290
291 AllocConsole();
292
293 StdHandle = GetStdHandle(STD_OUTPUT_HANDLE);
294 hConHandle = _open_osfhandle((long)StdHandle, _O_TEXT);
295 fp = _fdopen( hConHandle, "w" );
296 *stdout = *fp;
297 *stderr = *fp;
298
299 StdHandle = GetStdHandle(STD_INPUT_HANDLE);
300 hConHandle = _open_osfhandle((long)StdHandle, _O_TEXT);
301 fp = _fdopen( hConHandle, "r" );
302 *stdin = *fp;
303}
304#endif
305
306
307DECLEXPORT(void) crError(const char *format, ... )
308{
309 va_list args;
310 static char txt[8092];
311 int offset;
312#ifdef WINDOWS
313 DWORD err;
314#endif
315
316 __crCheckCanada();
317 __crCheckSwedishChef();
318 __crCheckAustralia();
319 if (!my_hostname[0])
320 __getHostInfo();
321#ifdef WINDOWS
322 if ((err = GetLastError()) != 0 && crGetenv( "CR_WINDOWS_ERRORS" ) != NULL )
323 {
324 static char buf[8092], *temp;
325
326 SetLastError(0);
327 sprintf( buf, "err=%d", err );
328
329 FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
330 FORMAT_MESSAGE_FROM_SYSTEM |
331 FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, err,
332 MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
333 (LPTSTR) &temp, 0, NULL );
334 if ( temp )
335 {
336 crStrncpy( buf, temp, sizeof(buf)-1 );
337 buf[sizeof(buf)-1] = 0;
338 }
339
340 temp = buf + crStrlen(buf) - 1;
341 while ( temp > buf && isspace( *temp ) )
342 {
343 *temp = '\0';
344 temp--;
345 }
346
347 offset = sprintf( txt, "\t-----------------------\n\tWindows ERROR: %s\n\t----------------------\nCR Error(%s:%d): ", buf, my_hostname, my_pid );
348 }
349 else
350 {
351 offset = sprintf( txt, "OpenGL Error: ");
352 }
353#else
354 offset = sprintf( txt, "OpenGL Error: " );
355#endif
356 va_start( args, format );
357 vsprintf( txt + offset, format, args );
358#if defined(IN_GUEST)
359 crDebug("%s", txt);
360 outputChromiumMessage( stderr, txt );
361#else
362 LogRel(("%s\n", txt));
363#endif
364#ifdef WINDOWS
365 if (crGetenv( "CR_GUI_ERROR" ) != NULL)
366 {
367 MessageBox( NULL, txt, "Chromium Error", MB_OK );
368 }
369 else
370 {
371#endif
372 va_end( args );
373#ifdef WINDOWS
374 }
375#if !defined(DEBUG_leo) && !defined(DEBUG_ll158262) && !defined(DEBUG_misha)
376 if (crGetenv( "CR_DEBUG_ON_ERROR" ) != NULL)
377#endif
378 {
379 DebugBreak();
380 }
381#endif
382
383#ifdef IN_GUEST
384 /* Give chance for things to close down */
385 raise( SIGTERM );
386
387 exit(1);
388#endif
389}
390
391void crEnableWarnings(int onOff)
392{
393 warnings_enabled = onOff;
394}
395
396#ifdef DEBUG_misha
397# undef crWarning
398#endif
399DECLEXPORT(void) crWarning(const char *format, ... )
400{
401 if (warnings_enabled) {
402 va_list args;
403 static char txt[8092];
404 int offset;
405
406 __crCheckCanada();
407 __crCheckSwedishChef();
408 __crCheckAustralia();
409 if (!my_hostname[0])
410 __getHostInfo();
411 offset = sprintf( txt, "OpenGL Warning: ");
412 va_start( args, format );
413 vsprintf( txt + offset, format, args );
414#if defined(IN_GUEST)
415 crDebug("%s", txt);
416 outputChromiumMessage( stderr, txt );
417#else
418 LogRel(("%s\n", txt));
419#endif
420 va_end( args );
421
422#if defined(WINDOWS) && defined(DEBUG) && !defined(IN_GUEST) && defined(DEBUG_misha)
423 DebugBreak();
424#endif
425 }
426}
427
428DECLEXPORT(void) crInfo(const char *format, ... )
429{
430 va_list args;
431 static char txt[8092];
432 int offset;
433
434 __crCheckCanada();
435 __crCheckSwedishChef();
436 __crCheckAustralia();
437 if (!my_hostname[0])
438 __getHostInfo();
439 offset = sprintf( txt, "OpenGL Info: ");
440 va_start( args, format );
441 vsprintf( txt + offset, format, args );
442#if defined(IN_GUEST)
443 crDebug("%s", txt);
444 outputChromiumMessage( stderr, txt );
445#else
446 LogRel(("%s\n", txt));
447#endif
448 va_end( args );
449}
450
451#ifdef CR_DEBUG_BACKDOOR_ENABLE
452static DECLCALLBACK(void) crDebugBackdoorRt(char* pcszStr)
453{
454 RTLogBackdoorPrintf("%s", pcszStr);
455}
456
457static DECLCALLBACK(void) crDebugBackdoorDispMp(char* pcszStr)
458{
459 VBoxDispMpLoggerLog(pcszStr);
460}
461#endif
462
463
464#if defined(WINDOWS) /* && (!defined(DEBUG_misha) || !defined(IN_GUEST) ) */
465# define CR_DEBUG_DBGPRINT_ENABLE
466#endif
467
468#ifdef CR_DEBUG_DBGPRINT_ENABLE
469static void crDebugDbgPrint(const char *str)
470{
471 OutputDebugString(str);
472 OutputDebugString("\n");
473}
474
475static void crDebugDbgPrintF(const char * szString, ...)
476{
477 char szBuffer[4096] = {0};
478 va_list pArgList;
479 va_start(pArgList, szString);
480 vsprintf( szBuffer, szString, pArgList );
481 va_end(pArgList);
482
483 OutputDebugStringA(szBuffer);
484}
485
486static void crDebugDmlPrint(const char* pszDesc, const char* pszCmd)
487{
488 crDebugDbgPrintF("<?dml?><exec cmd=\"%s\">%s</exec>, ( %s )\n", pszCmd, pszDesc, pszCmd);
489}
490
491
492DECLEXPORT(void) crDbgCmdPrint(const char *description1, const char *description2, const char *cmd, ...)
493{
494 va_list args;
495 char aTxt[8092];
496 char aCmd[8092];
497
498 sprintf( aTxt, "%s%s", description1, description2 );
499
500 va_start( args, cmd );
501
502 vsprintf( aCmd, cmd, args );
503
504 va_end( args );
505
506 crDebugDmlPrint(aTxt, aCmd);
507
508 crDebug("%s: %s", aTxt, aCmd);
509}
510
511DECLEXPORT(void) crDbgCmdSymLoadPrint(const char *modName, const void*pvAddress)
512{
513 static bool fEnable = false;
514 static bool fInitialized = false;
515 const char * pszName;
516 static const char * pszModulePath = NULL;
517
518 if (!fInitialized)
519 {
520#ifndef DEBUG_misha
521 if (crGetenv( "CR_DEBUG_MODULE_ENABLE" ))
522#endif
523 {
524 fEnable = true;
525 }
526
527 fInitialized = true;
528 }
529
530 if (!fEnable)
531 return;
532
533 pszName = PathFindFileNameA(modName);
534
535 if (!pszModulePath)
536 pszModulePath = crGetenv("CR_DEBUG_MODULE_PATH");
537 if (!pszModulePath)
538 pszModulePath = "c:\\Users\\senmk\\Downloads\\Data\\Data";
539
540 crDbgCmdPrint("load modules for ", pszName, ".reload /i /f %s\\%s=%#p", pszModulePath, pszName, pvAddress);
541}
542
543#endif
544
545DECLEXPORT(void) crDebug(const char *format, ... )
546{
547 va_list args;
548 static char txt[8092];
549 int offset;
550#ifdef WINDOWS
551 DWORD err;
552#endif
553 static FILE *output;
554 static int first_time = 1;
555 static int silent = 0;
556#ifdef CR_DEBUG_BACKDOOR_ENABLE
557 typedef DECLCALLBACK(void) FNCRGEDUGBACKDOOR(char* pcszStr);
558 typedef FNCRGEDUGBACKDOOR *PFNCRGEDUGBACKDOOR;
559 static PFNCRGEDUGBACKDOOR pfnLogBackdoor = NULL;
560#endif
561#ifdef CR_DEBUG_DBGPRINT_ENABLE
562 static int dbgPrintEnable = 0;
563#endif
564
565 if (first_time)
566 {
567 const char *fname = crGetenv( "CR_DEBUG_FILE" );
568 const char *fnamePrefix = crGetenv( "CR_DEBUG_FILE_PREFIX" );
569 char str[2048];
570#ifdef CR_DEBUG_CONSOLE_ENABLE
571 int logToConsole = 0;
572#endif
573#ifdef CR_DEBUG_BACKDOOR_ENABLE
574 if (crGetenv( "CR_DEBUG_BACKDOOR" ))
575 {
576 int rc = VBoxDispMpLoggerInit();
577 if (RT_SUCCESS(rc))
578 pfnLogBackdoor = crDebugBackdoorDispMp;
579 else
580 pfnLogBackdoor = crDebugBackdoorRt;
581 }
582#endif
583#ifdef CR_DEBUG_DBGPRINT_ENABLE
584 if (crGetenv( "CR_DEBUG_DBGPRINT" ))
585 {
586 dbgPrintEnable = 1;
587 }
588#endif
589
590 if (!fname && fnamePrefix)
591 {
592 char pname[1024];
593 if (crStrlen(fnamePrefix) < sizeof (str) - sizeof (pname) - 20)
594 {
595 crGetProcName(pname, 1024);
596 sprintf(str,
597#ifdef RT_OS_WINDOWS
598 "%s_%s_%u.txt", fnamePrefix, pname, GetCurrentProcessId()
599#else
600 "%s_%s_%lu.txt", fnamePrefix, pname, crGetPID()
601#endif
602 );
603 fname = &str[0];
604 }
605 }
606
607 first_time = 0;
608 if (fname)
609 {
610 char debugFile[2048], *p;
611 crStrcpy(debugFile, fname);
612 p = crStrstr(debugFile, "%p");
613 if (p) {
614 /* replace %p with process number */
615 unsigned long n = (unsigned long) crGetPID();
616 sprintf(p, "%lu", n);
617 }
618 fname = debugFile;
619 output = fopen( fname, "w" );
620 if (!output)
621 {
622 crError( "Couldn't open debug log %s", fname );
623 }
624 }
625 else
626 {
627#ifdef CR_DEBUG_CONSOLE_ENABLE
628 if (crGetenv( "CR_DEBUG_CONSOLE" ))
629 {
630 crRedirectIOToConsole();
631 logToConsole = 1;
632 }
633#endif
634 output = stderr;
635 }
636
637#if !defined(DEBUG)/* || defined(DEBUG_misha)*/
638 /* Release mode: only emit crDebug messages if CR_DEBUG
639 * or CR_DEBUG_FILE is set.
640 */
641 if (!fname && !crGetenv("CR_DEBUG")
642#ifdef CR_DEBUG_CONSOLE_ENABLE
643 && !logToConsole
644#endif
645#ifdef CR_DEBUG_BACKDOOR_ENABLE
646 && !pfnLogBackdoor
647#endif
648#ifdef CR_DEBUG_DBGPRINT_ENABLE
649 && !dbgPrintEnable
650#endif
651 )
652 silent = 1;
653#endif
654 }
655
656 if (silent)
657 return;
658
659 __crCheckCanada();
660 __crCheckSwedishChef();
661 __crCheckAustralia();
662 if (!my_hostname[0])
663 __getHostInfo();
664
665#ifdef WINDOWS
666 if ((err = GetLastError()) != 0 && crGetenv( "CR_WINDOWS_ERRORS" ) != NULL )
667 {
668 static char buf[8092], *temp;
669
670 SetLastError(0);
671 sprintf( buf, "err=%d", err );
672
673 FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
674 FORMAT_MESSAGE_FROM_SYSTEM |
675 FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, err,
676 MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
677 (LPTSTR) &temp, 0, NULL );
678 if ( temp )
679 {
680 crStrncpy( buf, temp, sizeof(buf)-1 );
681 buf[sizeof(buf)-1] = 0;
682 }
683
684 temp = buf + crStrlen(buf) - 1;
685 while ( temp > buf && isspace( *temp ) )
686 {
687 *temp = '\0';
688 temp--;
689 }
690
691 offset = sprintf( txt, "\t-----------------------\n\tWindows ERROR: %s\n\t-----------------\nCR Debug(%s:%d): ", buf, my_hostname, my_pid );
692 }
693 else
694 {
695 offset = sprintf( txt, "[0x%x.0x%x] OpenGL Debug: ", GetCurrentProcessId(), crThreadID());
696 }
697#else
698 offset = sprintf( txt, "[0x%lx.0x%lx] OpenGL Debug: ", crGetPID(), crThreadID());
699#endif
700 va_start( args, format );
701 vsprintf( txt + offset, format, args );
702#ifdef CR_DEBUG_BACKDOOR_ENABLE
703 if (pfnLogBackdoor)
704 {
705 pfnLogBackdoor(txt);
706 }
707#endif
708#ifdef CR_DEBUG_DBGPRINT_ENABLE
709 if (dbgPrintEnable)
710 {
711 crDebugDbgPrint(txt);
712 }
713#endif
714#if defined(IN_GUEST)
715 outputChromiumMessage( output, txt );
716#else
717 if (!output
718#ifndef DEBUG_misha
719 || output==stderr
720#endif
721 )
722 {
723 LogRel(("%s\n", txt));
724 }
725 else
726 {
727 LogRel(("%s\n", txt));
728 outputChromiumMessage(output, txt);
729 }
730#endif
731 va_end( args );
732}
733
734#if defined(DEBUG_misha) && defined(RT_OS_WINDOWS)
735BOOL WINAPI DllMain(HINSTANCE hDLLInst, DWORD fdwReason, LPVOID lpvReserved)
736{
737 (void) lpvReserved;
738
739 switch (fdwReason)
740 {
741 case DLL_PROCESS_ATTACH:
742 {
743 char aName[MAX_PATH];
744 GetModuleFileNameA(hDLLInst, aName, RT_ELEMENTS(aName));
745 crDbgCmdSymLoadPrint(aName, hDLLInst);
746 break;
747 }
748 default:
749 break;
750 }
751
752 return TRUE;
753}
754#endif
755#endif
Note: See TracBrowser for help on using the repository browser.

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