root/eaccelerator/tags/0.9.4/debug.c

Revision 144, 7.6 kB (checked in by zoeloelip, 3 years ago)

Fix for bug 1238736

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /*
2    +----------------------------------------------------------------------+
3    | eAccelerator project                                                 |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 2004 - 2005 eAccelerator                               |
6    | http://eaccelerator.net                                              |
7    +----------------------------------------------------------------------+
8    | This program is free software; you can redistribute it and/or        |
9    | modify it under the terms of the GNU General Public License          |
10    | as published by the Free Software Foundation; either version 2       |
11    | of the License, or (at your option) any later version.               |
12    |                                                                      |
13    | This program is distributed in the hope that it will be useful,      |
14    | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
15    | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        |
16    | GNU General Public License for more details.                         |
17    |                                                                      |
18    | You should have received a copy of the GNU General Public License    |
19    | along with this program; if not, write to the Free Software          |
20    | Foundation, Inc., 59 Temple Place - Suite 330, Boston,               |
21    | MA  02111-1307, USA.                                                 |
22    |                                                                      |
23    | A copy is availble at http://www.gnu.org/copyleft/gpl.txt            |
24    +----------------------------------------------------------------------+
25    | Author(s): Dmitry Stogov <dstogov@users.sourceforge.net>             |
26    |            Bart Vanbrabant <zoeloelip@users.sourceforge.net>         |
27    +----------------------------------------------------------------------+
28    $Id$
29 */
30
31 #include "eaccelerator.h"
32
33 #ifdef HAVE_EACCELERATOR
34
35 #include "debug.h"
36 #include <ctype.h>
37 #include <stdio.h>
38 #include <unistd.h>
39 #include <fcntl.h>
40
41 static FILE *F_fp = NULL;
42 static int file_no = 0;
43 long eaccelerator_debug = 0;
44
45 /**
46  * Init the debug system. This must be called before any debug
47  * functions are used.
48  */
49 void ea_debug_init (TSRMLS_D)
50 {
51     /* register ini entries */
52     REGISTER_MAIN_LONG_CONSTANT ("EA_LOG", EA_LOG, CONST_PERSISTENT | CONST_CS);
53     REGISTER_MAIN_LONG_CONSTANT ("EA_DEBUG", EA_DEBUG, CONST_PERSISTENT | CONST_CS);
54     REGISTER_MAIN_LONG_CONSTANT ("EA_PROFILE_OPCODES", EA_PROFILE_OPCODES, CONST_PERSISTENT | CONST_CS);
55     REGISTER_MAIN_LONG_CONSTANT ("EA_TEST_PERFORMANCE", EA_TEST_PERFORMANCE, CONST_PERSISTENT | CONST_CS);
56     REGISTER_MAIN_LONG_CONSTANT ("EA_LOG_HASHKEYS", EA_LOG_HASHKEYS, CONST_PERSISTENT | CONST_CS);
57
58     F_fp = fopen (EAG (eaccelerator_log_file), "a");
59     if (!F_fp)
60         F_fp = stderr;
61     file_no = fileno(F_fp);
62 }
63
64 /**
65  * Close the debug system.
66  */
67 void ea_debug_shutdown ()
68 {
69     fflush (F_fp);
70     if (F_fp != stderr)
71         fclose (F_fp);
72     F_fp = NULL;
73 }
74
75 /* lock the log file, don't lock stderr */
76 static void ea_debug_lock() {
77     int rc;
78     struct flock l;
79     if (F_fp != stderr) {
80         l.l_whence   = SEEK_SET;
81         l.l_start    = 0;
82         l.l_len      = 0;
83         l.l_pid      = 0;
84         l.l_type     = F_WRLCK;
85         do {
86             rc = fcntl(file_no, F_SETLKW, &l);
87         } while (rc < 0 && errno == EINTR);
88     }
89 }
90
91 static void ea_debug_unlock() {
92     int rc;
93     struct flock l;
94     if (F_fp != stderr) {
95         l.l_whence   = SEEK_SET;
96         l.l_start    = 0;
97         l.l_len      = 0;
98         l.l_pid      = 0;
99         l.l_type     = F_UNLCK;
100         do {
101             rc = fcntl(file_no, F_SETLKW, &l);
102         } while (rc < 0 && errno == EINTR);
103     }
104 }
105
106 /**
107  * Print a log message that will be print when the debug level is
108  * equal to EA_LOG. This function is always called even if ea isn't
109  * compiled with DEBUG and the log level is not equal to EA_LOG.
110  */
111 void ea_debug_log (char *format, ...)
112 {
113     if (eaccelerator_debug & EA_LOG) {
114         char output_buf[512];
115         va_list args;
116
117         va_start (args, format);
118         vsnprintf (output_buf, sizeof (output_buf), format, args);
119         va_end (args);
120
121         ea_debug_lock();
122 #ifdef ZEND_WIN32
123         OutputDebugString (output_buf);
124 #else
125         fputs (output_buf, F_fp);
126         fflush (F_fp);
127 #endif
128         ea_debug_unlock();
129     }
130 }
131
132 /**
133  * Output an error message to stderr. This message are always printed
134  * no matter what log level is used.
135  */
136 void ea_debug_error (char *format, ...)
137 {
138     char output_buf[512];
139     va_list args;
140
141     va_start (args, format);
142     vsnprintf (output_buf, sizeof (output_buf), format, args);
143     va_end (args);
144
145 #ifdef ZEND_WIN32
146     OutputDebugString (output_buf);
147 #else
148     fputs (output_buf, stderr);
149     fflush (stderr);
150 #endif
151 }
152
153 /*
154  * All these functions aren't compiled when eA isn't compiled with DEBUG. They
155  * are replaced with function with no body, so it's optimized away by the compiler.
156  * Even if the debug level is ok.
157  */
158
159 /**
160  * Print a debug message
161  */
162 #ifdef DEBUG
163 void ea_debug_printf (long debug_level, char *format, ...)
164 {
165     if (eaccelerator_debug & debug_level) {
166         char output_buf[512];
167         va_list args;
168
169         va_start (args, format);
170         vsnprintf (output_buf, sizeof (output_buf), format, args);
171         va_end (args);
172        
173         ea_debug_lock();
174         fputs (output_buf, F_fp);
175         fflush (F_fp);
176         ea_debug_unlock();
177     }
178 }
179 #else
180 void ea_debug_printf (long debug_level, char *format, ...)
181 {
182 }
183 #endif
184
185 /**
186  * Put a debug message
187  */
188 #ifdef DEBUG
189 void ea_debug_put (long debug_level, char *message)
190 {
191     if (debug_level & eaccelerator_debug) {
192         ea_debug_lock();
193         fputs (message, F_fp);
194         fflush (F_fp);
195         ea_debug_unlock();
196     }
197 }
198 #else
199 void ea_debug_put (long debug_level, char *message)
200 {
201 }
202 #endif
203
204 /**
205  * Print a binary message
206  */
207 #ifdef DEBUG
208 void ea_debug_binary_print (long debug_level, char *p, int len)
209 {
210     if (eaccelerator_debug & debug_level) {
211         ea_debug_lock();
212         while (len--) {
213             fputc (*p++, F_fp);
214         }
215         fputc ('\n', F_fp);
216         fflush (F_fp);
217         ea_debug_unlock();
218     }
219 }
220 #else
221 void ea_debug_binary_print (long debug_level, char *p, int len)
222 {
223 }
224 #endif
225
226 /**
227  * Log a hashkey
228  */
229 #ifdef DEBUG
230 void ea_debug_log_hashkeys (char *p, HashTable * ht)
231 {
232     if (eaccelerator_debug & EA_LOG_HASHKEYS) {
233         Bucket *b;
234         int i = 0;
235
236         b = ht->pListHead;
237
238         ea_debug_lock();
239         fputs(p, F_fp);
240         fflush(F_fp);
241         ea_debug_unlock();
242         while (b) {
243             fprintf (F_fp, "[%d] ", i);
244             ea_debug_binary_print (EA_LOG_HASHKEYS, b->arKey, b->nKeyLength);
245
246             b = b->pListNext;
247             i++;
248         }
249     }
250 }
251 #else
252 void ea_debug_log_hashkeys (char *p, HashTable * ht)
253 {
254 }
255 #endif
256
257 /**
258  * Pad the message with the current pad level.
259  */
260 #ifdef DEBUG
261 void ea_debug_pad (long debug_level TSRMLS_DC)
262 {
263     if (eaccelerator_debug & debug_level) {
264         ea_debug_lock();
265         int i = EAG (xpad);
266         while (i-- > 0) {
267             fputc ('\t', F_fp);
268         }
269         ea_debug_unlock();
270     }
271 }
272 #else
273 void ea_debug_pad (long debug_level TSRMLS_DC)
274 {
275 }
276 #endif
277
278 void ea_debug_start_time (struct timeval *tvstart)
279 {
280     gettimeofday (tvstart, NULL);
281 }
282
283 long ea_debug_elapsed_time (struct timeval *tvstart)
284 {
285     struct timeval tvend;
286     int sec, usec;
287     gettimeofday (&tvend, NULL);
288     sec = tvend.tv_sec - tvstart->tv_sec;
289     usec = tvend.tv_usec - tvstart->tv_usec;
290     return sec * 1000000 + usec;
291 }
292
293 #endif /* #ifdef HAVE_EACCELERATOR */
Note: See TracBrowser for help on using the browser.