VerifyAndMapCode: Only map the code if it passes validation
[nativeclient.git] / service_runtime / nacl_log.c
blob4a8d82529777470606bda85d157708aa0f9a813a
1 /*
2 * Copyright 2008, Google Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 * NaCl Server Runtime logging code.
35 #include "native_client/include/portability.h"
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <stdarg.h>
41 #define NON_THREAD_SAFE_DETAIL_CHECK 1
43 * If set, check detail_level without grabbing a mutex. This makes
44 * logging much cheaper, but implies that the verbosity level should
45 * only be changed prior to going multithreaded.
48 #include "native_client/service_runtime/gio.h"
49 #include "native_client/service_runtime/nacl_sync.h"
50 #include "native_client/service_runtime/nacl_log.h"
51 #include "native_client/service_runtime/nacl_threads.h"
52 #include "native_client/service_runtime/nacl_timestamp.h"
54 static struct NaClMutex log_mu;
56 static int verbosity = 0;
57 static struct Gio *log_stream = NULL;
58 static struct GioFile log_file_stream;
59 static int timestamp_enabled = 1;
61 void NaClLogModuleInit()
63 NaClMutexCtor(&log_mu);
66 void NaClLogModuleFini()
68 NaClMutexDtor(&log_mu);
71 void NaClLogLock()
73 NaClMutexLock(&log_mu);
76 void NaClLogUnlock(void)
78 NaClMutexUnlock(&log_mu);
81 static INLINE struct Gio *NaClLogGetGio_mu()
83 if (NULL == log_stream) {
84 (void) GioFileRefCtor(&log_file_stream, stderr);
85 log_stream = (struct Gio *) &log_file_stream;
87 return log_stream;
90 void NaClLogSetVerbosity(int verb)
92 NaClLogLock();
93 verbosity = verb;
94 NaClLogUnlock();
97 void NaClLogIncrVerbosity(void)
99 NaClLogLock();
100 ++verbosity;
101 NaClLogUnlock();
104 int NaClLogGetVerbosity(void)
106 int v;
108 NaClLogLock();
109 v = verbosity;
110 NaClLogUnlock();
112 return v;
115 void NaClLogSetGio(struct Gio *stream)
117 NaClLogLock();
118 if (NULL != log_stream) {
119 (void) (*log_stream->vtbl->Flush)(log_stream);
121 log_stream = stream;
122 NaClLogUnlock();
125 struct Gio *NaClLogGetGio(void)
127 struct Gio *s;
129 NaClLogLock();
130 s = NaClLogGetGio_mu();
131 NaClLogUnlock();
133 return s;
136 void NaClLogEnableTimestamp(void)
138 timestamp_enabled = 1;
141 void NaClLogDisableTimestamp(void)
143 timestamp_enabled = 0;
147 * Output a printf-style formatted message if the log verbosity level
148 * is set higher than the log output's detail level. Note that since
149 * this is not a macro, log message arguments that have side effects
150 * will have their side effects regardless of whether the
151 * corresponding log message is printed or not. This is good from a
152 * consistency point of view, but it means that should a logging
153 * argument be expensive to compute, the log statement needs to be
154 * surrounded by something like
156 * if (detail_level <= NaClLogGetVerbosity()) {
157 * NaClLog(detail_level, "format string", expensive_arg(), ...);
160 * The log message, if written, is prepended by a microsecond
161 * resolution timestamp on linux and a millisecond resolution
162 * timestamp on windows. This means that if the NaCl app can read its
163 * own logs, it can distinguish which host OS it is running on.
165 void NaClLogV_mu(int detail_level,
166 char *fmt,
167 va_list ap)
169 struct Gio *s;
170 char timestamp[128];
172 s = NaClLogGetGio_mu();
174 if (detail_level <= verbosity) {
175 if (timestamp_enabled) {
176 int pid;
177 pid = GETPID();
178 gprintf(s, "[%d,%u:%s] ",
179 pid,
180 NaClThreadId(),
181 NaClTimeStampString(timestamp, sizeof timestamp));
184 (void) gvprintf(s, fmt, ap);
185 (void) (*s->vtbl->Flush)(s);
188 if (LOG_FATAL == detail_level) {
189 abort();
193 void NaClLogV(int detail_level,
194 char *fmt,
195 va_list ap)
197 #if NON_THREAD_SAFE_DETAIL_CHECK
198 if (detail_level > verbosity) {
199 return;
201 #endif
202 NaClLogLock();
203 NaClLogV_mu(detail_level, fmt, ap);
204 NaClLogUnlock();
207 void NaClLog(int detail_level,
208 char *fmt,
209 ...)
211 va_list ap;
213 #if NON_THREAD_SAFE_DETAIL_CHECK
214 if (detail_level > verbosity) {
215 return;
217 #endif
219 NaClLogLock();
220 va_start(ap, fmt);
221 NaClLogV_mu(detail_level, fmt, ap);
222 va_end(ap);
223 NaClLogUnlock();