1 /*
2  * Copyright (c) 2012 The Native Client Authors. All rights reserved.
3  * Use of this source code is governed by a BSD-style license that can be
4  * found in the LICENSE file.
5  */
6 
7 /*
8  * NaCl logging module.
9  *
10  * This module is used in many parts of Native Client to generate
11  * logging output.
12  *
13  * Example usage:
14  *
15  *   #include "native_client/src/trusted/platform/nacl_log.h"
16  *
17  *   NaClLog(3, "Hello %s\n", "world");
18  *
19  * The 3 is a "detail level" for this particular log message, the
20  * "Hello %s\n" is the familiar printf-style format string, and all
21  * subsequent arguments are the corresponding arguments.  Type
22  * checking for these arguments are done when gcc-compatible compilers
23  * are used.
24  *
25  * When running the program (assuming the main function invoked the
26  * module initializer(s) appropriately [see NaClLogModuleInit*
27  * below]), you can set the global verbosity level by running the
28  * program with the NACLVERBOSITY environment variable, e.g.:
29  *
30  *   NACLVERBOSITY=3
31  *
32  * Pre-defined logging detail levels of LOG_INFO, LOG_WARNING,
33  * LOG_ERROR, and LOG_FATAL may also be used.  When LOG_FATAL is used,
34  * the application aborts after the log message is generated.
35  * Messages at these levels cannot be suppressed.
36  *
37  *
38  * The default logging output is standard error.  NB: on Windows, both
39  * stdout and stderr are discarded for Windowed applications.
40  *
41  * All logging output may be redirected to a file using the NACLLOG
42  * environment variable, the value of which should be the path to a
43  * file.  NOTE: when running in Chrome, the outer sandbox is by
44  * default enabled, so the log module will be unable to open the log
45  * file.  In order to enable this for testing, use the --no-sandbox
46  * flag to Chrome.  (This is not recommended for normal use, since it
47  * eliminates a layer of defense.)
48  */
49 
50 #ifndef NATIVE_CLIENT_SRC_TRUSTED_PLATFORM_NACL_LOG_H__
51 #define NATIVE_CLIENT_SRC_TRUSTED_PLATFORM_NACL_LOG_H__
52 
53 #include <stdarg.h>
54 
55 #include "native_client/src/include/build_config.h"
56 #include "native_client/src/include/nacl_base.h"
57 
58 #ifdef __native_client__
59 # define ATTRIBUTE_FORMAT_PRINTF(m, n) __attribute__((format(printf, m, n)))
60 #else
61 # include "native_client/src/include/portability.h"
62 #endif
63 
64 struct Gio;
65 
66 EXTERN_C_BEGIN
67 
68 /*
69  * PreInit functions may be used to set default module parameter
70  * values before the module initializer is called.  This is needed in
71  * some cases, such as by users of NaClNrdModuleInit or
72  * NaClAllModuleInit, where a list of module initializer is invoked,
73  * and the caller wants to crank up logging to get logging output from
74  * functions invoked in the module initializers that occur after
75  * NaClLogModuleInit (and prior to NaClNrdModuleInit returning).
76  */
77 void NaClLogPreInitSetVerbosity(int verb);
78 void NaClLogPreInitSetGio(struct Gio *out_stream);
79 
80 /*
81  * NaClLogModuleInit() is idempotent, provided that all the calls to
82  * it originate from a single thread.
83  */
84 void NaClLogModuleInit(void);
85 
86 void NaClLogModuleInitExtended(int        initial_verbosity,
87                                struct Gio *log_gio);
88 
89 /*
90  * Convenience functions, in case only one needs to be overridden.
91  * Also useful for setting a new default, e.g., invoking
92  * NaClLogPreInitSetVerbosity with the maximum of the verbosity level
93  * supplied from higher level code such as chrome's command line
94  * flags, and the default value from the environment as returned by
95  * NaClLogDefaultLogVerbosity().
96  */
97 int NaClLogDefaultLogVerbosity(void);
98 struct Gio *NaClLogDefaultLogGio(void);
99 
100 /*
101  * Sets the log file to the named file.  Aborts program if the open
102  * fails.  A GioFile object is associated with the file.
103  *
104  * The GioFile object is dynamically allocated, so caller is
105  * responsible for obtaining it via NaClLogGetGio and freeing it as
106  * appropriate, since otherwise a memory leak will occur.  This
107  * includes closing the wrapped FILE *, if appropriate (e.g., not the
108  * default of stderr).
109  */
110 void NaClLogSetFile(char const *log_file);
111 
112 void NaClLogModuleFini(void);
113 
114 void NaClLogSetVerbosity(int verb);
115 
116 int NaClLogGetVerbosity(void);
117 
118 void NaClLogIncrVerbosity(void);
119 
120 void NaClLogSetGio(struct Gio *out_stream);
121 
122 struct Gio *NaClLogGetGio(void);
123 
124 /*
125  * Timestamps on log entries may be disabled, e.g., to make it easier to
126  * write test that compare logging output.
127  */
128 
129 void NaClLogEnableTimestamp(void);
130 
131 void NaClLogDisableTimestamp(void);
132 
133 /*
134  * Users of NaClLogV should add ATTRIBUTE_FORMAT_PRINTF(m,n) to their
135  * function prototype, where m is the argument position of the format
136  * string and n is the position of the first argument to be consumed
137  * by the format specifier.
138  */
139 void NaClLogV(int         detail_level,
140               char const  *fmt,
141               va_list     ap);
142 
143 void NaClLog(int         detail_level,
144              char const  *fmt,
145              ...) ATTRIBUTE_FORMAT_PRINTF(2, 3);
146 
147 #define LOG_INFO    (-1)
148 #define LOG_WARNING (-2)
149 #define LOG_ERROR   (-3)
150 #define LOG_FATAL   (-4)
151 
152 /*
153  * Low-level logging code that requires manual lock manipulation.
154  * Should be used carefully!
155  */
156 void NaClLogLock(void);
157 void NaClLogUnlock(void);
158 
159 /*
160  * Caller is responsible for grabbing the NaClLog mutex lock (via
161  * NaClLogLock) before calling NaClLogV_mu or NaClLog_mu and for
162  * releasing it (via NaClLogUnlock) afterward.
163  *
164  * Users of NaClLogV_mu should also use ATTRIBUTE_FORMAT_PRINTF as
165  * above.
166  *
167  * Only the first call to NaClLog_mu or NaClLogV_mu after the
168  * NaClLogLock will get a timestamp tag prepended.  No newline
169  * detection is done, so a multi-line output must be (1) split into
170  * multiple calls to NaClLog_mu or NaClLogV_mu so that newlines are
171  * the last character in the format string to the NaClLog_mu or
172  * NaClLogV_mu calls, and (2) are followed by NaClLogTagNext_mu() so
173  * that the next output will know to generate a tag.
174  */
175 void NaClLogV_mu(int         detail_level,
176                  char const  *fmt,
177                  va_list     ap);
178 
179 void NaClLog_mu(int         detail_level,
180                 char const  *fmt,
181                 ...) ATTRIBUTE_FORMAT_PRINTF(2, 3);
182 
183 void NaClLogTagNext_mu(void);
184 
185 /*
186  * The function at |fn| is invoked when NaClLog's family of logging
187  * functions are invoked with LOG_FATAL.  This defaults to NaClAbort
188  * (see nacl_exit.h), but may be overridden to do other things prior
189  * to aborting.  NB: it is not a good idea to depend on too much
190  * within |fn|, since the application state is likely
191  * inconsistent/unstable.  It is probably a good idea to only use
192  * low-level routines or system calls directly.
193  */
194 void NaClLogSetAbortBehavior(void (*fn)(void));
195 
196 /*
197  * Run the current abort behavior hook.
198  */
199 void NaClLogRunAbortBehavior(void);
200 
201 EXTERN_C_END
202 
203 #endif  /* NATIVE_CLIENT_SRC_TRUSTED_PLATFORM_NACL_LOG_H__ */
204