1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker * drawElements Quality Program Helper Library
3*35238bceSAndroid Build Coastguard Worker * -------------------------------------------
4*35238bceSAndroid Build Coastguard Worker *
5*35238bceSAndroid Build Coastguard Worker * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker *
7*35238bceSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker *
11*35238bceSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker *
13*35238bceSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker *
19*35238bceSAndroid Build Coastguard Worker *//*!
20*35238bceSAndroid Build Coastguard Worker * \file
21*35238bceSAndroid Build Coastguard Worker * \brief Debug output utilities.
22*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker
24*35238bceSAndroid Build Coastguard Worker #include "qpDebugOut.h"
25*35238bceSAndroid Build Coastguard Worker
26*35238bceSAndroid Build Coastguard Worker #include "qpCrashHandler.h" /*!< for QP_USE_SIGNAL_HANDLER */
27*35238bceSAndroid Build Coastguard Worker
28*35238bceSAndroid Build Coastguard Worker #include <stdio.h>
29*35238bceSAndroid Build Coastguard Worker #include <stdlib.h>
30*35238bceSAndroid Build Coastguard Worker
31*35238bceSAndroid Build Coastguard Worker typedef enum MessageType_e
32*35238bceSAndroid Build Coastguard Worker {
33*35238bceSAndroid Build Coastguard Worker MESSAGETYPE_INFO = 0,
34*35238bceSAndroid Build Coastguard Worker MESSAGETYPE_ERROR,
35*35238bceSAndroid Build Coastguard Worker MESSAGETYPE_NONFATAL_ERROR,
36*35238bceSAndroid Build Coastguard Worker
37*35238bceSAndroid Build Coastguard Worker MESSAGETYPE_LAST
38*35238bceSAndroid Build Coastguard Worker } MessageType;
39*35238bceSAndroid Build Coastguard Worker
40*35238bceSAndroid Build Coastguard Worker static writePtr writeRedirect = 0;
41*35238bceSAndroid Build Coastguard Worker static writeFtmPtr writeFtmRedirect = 0;
42*35238bceSAndroid Build Coastguard Worker
43*35238bceSAndroid Build Coastguard Worker static void printRaw(MessageType type, const char *msg);
44*35238bceSAndroid Build Coastguard Worker static void printFmt(MessageType type, const char *fmt, va_list args);
45*35238bceSAndroid Build Coastguard Worker static void exitProcess(void);
46*35238bceSAndroid Build Coastguard Worker
qpRedirectOut(writePtr w,writeFtmPtr wftm)47*35238bceSAndroid Build Coastguard Worker void qpRedirectOut(writePtr w, writeFtmPtr wftm)
48*35238bceSAndroid Build Coastguard Worker {
49*35238bceSAndroid Build Coastguard Worker writeRedirect = w;
50*35238bceSAndroid Build Coastguard Worker writeFtmRedirect = wftm;
51*35238bceSAndroid Build Coastguard Worker }
52*35238bceSAndroid Build Coastguard Worker
qpPrint(const char * message)53*35238bceSAndroid Build Coastguard Worker void qpPrint(const char *message)
54*35238bceSAndroid Build Coastguard Worker {
55*35238bceSAndroid Build Coastguard Worker printRaw(MESSAGETYPE_INFO, message);
56*35238bceSAndroid Build Coastguard Worker }
57*35238bceSAndroid Build Coastguard Worker
qpPrintf(const char * format,...)58*35238bceSAndroid Build Coastguard Worker void qpPrintf(const char *format, ...)
59*35238bceSAndroid Build Coastguard Worker {
60*35238bceSAndroid Build Coastguard Worker va_list args;
61*35238bceSAndroid Build Coastguard Worker va_start(args, format);
62*35238bceSAndroid Build Coastguard Worker printFmt(MESSAGETYPE_INFO, format, args);
63*35238bceSAndroid Build Coastguard Worker va_end(args);
64*35238bceSAndroid Build Coastguard Worker }
65*35238bceSAndroid Build Coastguard Worker
qpPrintErrorf(const char * format,...)66*35238bceSAndroid Build Coastguard Worker void qpPrintErrorf(const char *format, ...)
67*35238bceSAndroid Build Coastguard Worker {
68*35238bceSAndroid Build Coastguard Worker va_list args;
69*35238bceSAndroid Build Coastguard Worker va_start(args, format);
70*35238bceSAndroid Build Coastguard Worker printFmt(MESSAGETYPE_NONFATAL_ERROR, format, args);
71*35238bceSAndroid Build Coastguard Worker va_end(args);
72*35238bceSAndroid Build Coastguard Worker }
73*35238bceSAndroid Build Coastguard Worker
qpPrintv(const char * format,va_list args)74*35238bceSAndroid Build Coastguard Worker void qpPrintv(const char *format, va_list args)
75*35238bceSAndroid Build Coastguard Worker {
76*35238bceSAndroid Build Coastguard Worker printFmt(MESSAGETYPE_INFO, format, args);
77*35238bceSAndroid Build Coastguard Worker }
78*35238bceSAndroid Build Coastguard Worker
qpPrintErrorv(const char * format,va_list args)79*35238bceSAndroid Build Coastguard Worker void qpPrintErrorv(const char *format, va_list args)
80*35238bceSAndroid Build Coastguard Worker {
81*35238bceSAndroid Build Coastguard Worker printFmt(MESSAGETYPE_NONFATAL_ERROR, format, args);
82*35238bceSAndroid Build Coastguard Worker }
83*35238bceSAndroid Build Coastguard Worker
qpDief(const char * format,...)84*35238bceSAndroid Build Coastguard Worker void qpDief(const char *format, ...)
85*35238bceSAndroid Build Coastguard Worker {
86*35238bceSAndroid Build Coastguard Worker va_list args;
87*35238bceSAndroid Build Coastguard Worker va_start(args, format);
88*35238bceSAndroid Build Coastguard Worker printFmt(MESSAGETYPE_ERROR, format, args);
89*35238bceSAndroid Build Coastguard Worker va_end(args);
90*35238bceSAndroid Build Coastguard Worker
91*35238bceSAndroid Build Coastguard Worker exitProcess();
92*35238bceSAndroid Build Coastguard Worker }
93*35238bceSAndroid Build Coastguard Worker
qpDiev(const char * format,va_list args)94*35238bceSAndroid Build Coastguard Worker void qpDiev(const char *format, va_list args)
95*35238bceSAndroid Build Coastguard Worker {
96*35238bceSAndroid Build Coastguard Worker printFmt(MESSAGETYPE_ERROR, format, args);
97*35238bceSAndroid Build Coastguard Worker exitProcess();
98*35238bceSAndroid Build Coastguard Worker }
99*35238bceSAndroid Build Coastguard Worker
100*35238bceSAndroid Build Coastguard Worker /* print() implementation. */
101*35238bceSAndroid Build Coastguard Worker #if (DE_OS == DE_OS_ANDROID)
102*35238bceSAndroid Build Coastguard Worker
103*35238bceSAndroid Build Coastguard Worker #include <android/log.h>
104*35238bceSAndroid Build Coastguard Worker
getLogPriority(MessageType type)105*35238bceSAndroid Build Coastguard Worker static android_LogPriority getLogPriority(MessageType type)
106*35238bceSAndroid Build Coastguard Worker {
107*35238bceSAndroid Build Coastguard Worker switch (type)
108*35238bceSAndroid Build Coastguard Worker {
109*35238bceSAndroid Build Coastguard Worker case MESSAGETYPE_INFO:
110*35238bceSAndroid Build Coastguard Worker return ANDROID_LOG_INFO;
111*35238bceSAndroid Build Coastguard Worker case MESSAGETYPE_ERROR:
112*35238bceSAndroid Build Coastguard Worker return ANDROID_LOG_FATAL;
113*35238bceSAndroid Build Coastguard Worker default:
114*35238bceSAndroid Build Coastguard Worker return ANDROID_LOG_DEBUG;
115*35238bceSAndroid Build Coastguard Worker }
116*35238bceSAndroid Build Coastguard Worker }
117*35238bceSAndroid Build Coastguard Worker
printRaw(MessageType type,const char * message)118*35238bceSAndroid Build Coastguard Worker void printRaw(MessageType type, const char *message)
119*35238bceSAndroid Build Coastguard Worker {
120*35238bceSAndroid Build Coastguard Worker if (writeRedirect && !writeRedirect(type, message))
121*35238bceSAndroid Build Coastguard Worker return;
122*35238bceSAndroid Build Coastguard Worker
123*35238bceSAndroid Build Coastguard Worker __android_log_write(getLogPriority(type), "dEQP", message);
124*35238bceSAndroid Build Coastguard Worker }
125*35238bceSAndroid Build Coastguard Worker
printFmt(MessageType type,const char * format,va_list args)126*35238bceSAndroid Build Coastguard Worker void printFmt(MessageType type, const char *format, va_list args)
127*35238bceSAndroid Build Coastguard Worker {
128*35238bceSAndroid Build Coastguard Worker if (writeFtmRedirect && !writeFtmRedirect(type, format, args))
129*35238bceSAndroid Build Coastguard Worker return;
130*35238bceSAndroid Build Coastguard Worker
131*35238bceSAndroid Build Coastguard Worker __android_log_vprint(getLogPriority(type), "dEQP", format, args);
132*35238bceSAndroid Build Coastguard Worker }
133*35238bceSAndroid Build Coastguard Worker
134*35238bceSAndroid Build Coastguard Worker #else
135*35238bceSAndroid Build Coastguard Worker
getOutFile(MessageType type)136*35238bceSAndroid Build Coastguard Worker static FILE *getOutFile(MessageType type)
137*35238bceSAndroid Build Coastguard Worker {
138*35238bceSAndroid Build Coastguard Worker if (type == MESSAGETYPE_ERROR || type == MESSAGETYPE_NONFATAL_ERROR)
139*35238bceSAndroid Build Coastguard Worker return stderr;
140*35238bceSAndroid Build Coastguard Worker else
141*35238bceSAndroid Build Coastguard Worker return stdout;
142*35238bceSAndroid Build Coastguard Worker }
143*35238bceSAndroid Build Coastguard Worker
printRaw(MessageType type,const char * message)144*35238bceSAndroid Build Coastguard Worker void printRaw(MessageType type, const char *message)
145*35238bceSAndroid Build Coastguard Worker {
146*35238bceSAndroid Build Coastguard Worker if (writeRedirect && !writeRedirect(type, message))
147*35238bceSAndroid Build Coastguard Worker return;
148*35238bceSAndroid Build Coastguard Worker
149*35238bceSAndroid Build Coastguard Worker FILE *out = getOutFile(type);
150*35238bceSAndroid Build Coastguard Worker
151*35238bceSAndroid Build Coastguard Worker if (type == MESSAGETYPE_ERROR)
152*35238bceSAndroid Build Coastguard Worker fprintf(out, "FATAL ERROR: ");
153*35238bceSAndroid Build Coastguard Worker
154*35238bceSAndroid Build Coastguard Worker fputs(message, out);
155*35238bceSAndroid Build Coastguard Worker
156*35238bceSAndroid Build Coastguard Worker if (type == MESSAGETYPE_ERROR)
157*35238bceSAndroid Build Coastguard Worker {
158*35238bceSAndroid Build Coastguard Worker putc('\n', out);
159*35238bceSAndroid Build Coastguard Worker fflush(out);
160*35238bceSAndroid Build Coastguard Worker }
161*35238bceSAndroid Build Coastguard Worker }
162*35238bceSAndroid Build Coastguard Worker
printFmt(MessageType type,const char * format,va_list args)163*35238bceSAndroid Build Coastguard Worker void printFmt(MessageType type, const char *format, va_list args)
164*35238bceSAndroid Build Coastguard Worker {
165*35238bceSAndroid Build Coastguard Worker if (writeFtmRedirect && !writeFtmRedirect(type, format, args))
166*35238bceSAndroid Build Coastguard Worker return;
167*35238bceSAndroid Build Coastguard Worker
168*35238bceSAndroid Build Coastguard Worker FILE *out = getOutFile(type);
169*35238bceSAndroid Build Coastguard Worker
170*35238bceSAndroid Build Coastguard Worker if (type == MESSAGETYPE_ERROR)
171*35238bceSAndroid Build Coastguard Worker fprintf(out, "FATAL ERROR: ");
172*35238bceSAndroid Build Coastguard Worker
173*35238bceSAndroid Build Coastguard Worker vfprintf(out, format, args);
174*35238bceSAndroid Build Coastguard Worker
175*35238bceSAndroid Build Coastguard Worker if (type == MESSAGETYPE_ERROR)
176*35238bceSAndroid Build Coastguard Worker {
177*35238bceSAndroid Build Coastguard Worker putc('\n', out);
178*35238bceSAndroid Build Coastguard Worker fflush(out);
179*35238bceSAndroid Build Coastguard Worker }
180*35238bceSAndroid Build Coastguard Worker }
181*35238bceSAndroid Build Coastguard Worker
182*35238bceSAndroid Build Coastguard Worker #endif
183*35238bceSAndroid Build Coastguard Worker
184*35238bceSAndroid Build Coastguard Worker /* exitProcess() implementation. */
185*35238bceSAndroid Build Coastguard Worker #if (DE_OS == DE_OS_WIN32)
186*35238bceSAndroid Build Coastguard Worker
187*35238bceSAndroid Build Coastguard Worker #define NOMINMAX
188*35238bceSAndroid Build Coastguard Worker #define VC_EXTRALEAN
189*35238bceSAndroid Build Coastguard Worker #define WIN32_LEAN_AND_MEAN
190*35238bceSAndroid Build Coastguard Worker #include <windows.h>
191*35238bceSAndroid Build Coastguard Worker
exitProcess(void)192*35238bceSAndroid Build Coastguard Worker static void exitProcess(void)
193*35238bceSAndroid Build Coastguard Worker {
194*35238bceSAndroid Build Coastguard Worker /* Some API implementations register atexit() functions that may hang.
195*35238bceSAndroid Build Coastguard Worker By using TerminateProcess() we can avoid calling any potentially hanging exit routines. */
196*35238bceSAndroid Build Coastguard Worker HANDLE curProc = GetCurrentProcess();
197*35238bceSAndroid Build Coastguard Worker TerminateProcess(curProc, -1);
198*35238bceSAndroid Build Coastguard Worker }
199*35238bceSAndroid Build Coastguard Worker
200*35238bceSAndroid Build Coastguard Worker #else
201*35238bceSAndroid Build Coastguard Worker
202*35238bceSAndroid Build Coastguard Worker #if (DE_OS == DE_OS_IOS)
203*35238bceSAndroid Build Coastguard Worker #include "deThread.h" /*!< for deSleep() */
204*35238bceSAndroid Build Coastguard Worker #endif
205*35238bceSAndroid Build Coastguard Worker
206*35238bceSAndroid Build Coastguard Worker #if defined(QP_USE_SIGNAL_HANDLER)
207*35238bceSAndroid Build Coastguard Worker #include <signal.h>
208*35238bceSAndroid Build Coastguard Worker #endif
209*35238bceSAndroid Build Coastguard Worker
exitProcess(void)210*35238bceSAndroid Build Coastguard Worker static void exitProcess(void)
211*35238bceSAndroid Build Coastguard Worker {
212*35238bceSAndroid Build Coastguard Worker #if (DE_OS == DE_OS_IOS)
213*35238bceSAndroid Build Coastguard Worker /* Since tests are in the same process as execserver, we want to give it
214*35238bceSAndroid Build Coastguard Worker a chance to stream complete log data before terminating. */
215*35238bceSAndroid Build Coastguard Worker deSleep(5000);
216*35238bceSAndroid Build Coastguard Worker #endif
217*35238bceSAndroid Build Coastguard Worker
218*35238bceSAndroid Build Coastguard Worker #if defined(QP_USE_SIGNAL_HANDLER)
219*35238bceSAndroid Build Coastguard Worker /* QP_USE_SIGNAL_HANDLER defined, this means this function could have
220*35238bceSAndroid Build Coastguard Worker been called from a signal handler. Calling exit() inside a signal
221*35238bceSAndroid Build Coastguard Worker handler is not safe. */
222*35238bceSAndroid Build Coastguard Worker
223*35238bceSAndroid Build Coastguard Worker /* Flush all open FILES */
224*35238bceSAndroid Build Coastguard Worker fflush(DE_NULL);
225*35238bceSAndroid Build Coastguard Worker
226*35238bceSAndroid Build Coastguard Worker /* Kill without calling any _at_exit handlers as those might hang */
227*35238bceSAndroid Build Coastguard Worker raise(SIGKILL);
228*35238bceSAndroid Build Coastguard Worker #else
229*35238bceSAndroid Build Coastguard Worker exit(-1);
230*35238bceSAndroid Build Coastguard Worker #endif
231*35238bceSAndroid Build Coastguard Worker }
232*35238bceSAndroid Build Coastguard Worker
233*35238bceSAndroid Build Coastguard Worker #endif
234