VirtualBox

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

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

crOpenGL: use IPRT for logging.

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