tor  0.4.2.0-alpha-dev
torerr.c
Go to the documentation of this file.
1 /* Copyright (c) 2001, Matej Pfajfar.
2  * Copyright (c) 2001-2004, Roger Dingledine.
3  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4  * Copyright (c) 2007-2019, The Tor Project, Inc. */
5 /* See LICENSE for licensing information */
6 
22 #include "orconfig.h"
23 #include <stdarg.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <stdio.h>
27 #ifdef HAVE_SYS_TIME_H
28 #include <sys/time.h>
29 #endif
30 #ifdef HAVE_TIME_H
31 #include <time.h>
32 #endif
33 #ifdef HAVE_UNISTD_H
34 #include <unistd.h>
35 #endif
36 #ifdef HAVE_SYS_TYPES_H
37 #include <sys/types.h>
38 #endif
39 
40 #include "lib/err/torerr.h"
41 #include "lib/err/backtrace.h"
42 
44 static int sigsafe_log_fds[TOR_SIGSAFE_LOG_MAX_FDS] = { STDERR_FILENO };
46 static int n_sigsafe_log_fds = 1;
48 static int log_granularity = 1000;
49 
52 static int
54 {
55  int i;
56  ssize_t r;
57  size_t len = strlen(s);
58  int err = 0;
59  for (i=0; i < n_sigsafe_log_fds; ++i) {
60  r = write(sigsafe_log_fds[i], s, len);
61  err += (r != (ssize_t)len);
62  }
63  return err ? -1 : 0;
64 }
65 
69 void
70 tor_log_err_sigsafe(const char *m, ...)
71 {
72  va_list ap;
73  const char *x;
74  char timebuf[33];
75  time_t now = time(NULL);
76 
77  if (!m)
78  return;
79  if (log_granularity >= 2000) {
80  int g = log_granularity / 1000;
81  now -= now % g;
82  }
83  timebuf[0] = now < 0 ? '-' : ' ';
84  if (now < 0) now = -now;
85  timebuf[1] = '\0';
86  format_dec_number_sigsafe(now, timebuf+1, sizeof(timebuf)-1);
87  tor_log_err_sigsafe_write("\n=========================================="
88  "================== T=");
92  va_start(ap, m);
93  while ((x = va_arg(ap, const char*))) {
95  }
96  va_end(ap);
97 }
98 
102 int
104 {
105  *out = sigsafe_log_fds;
106  return n_sigsafe_log_fds;
107 }
108 
114 void
115 tor_log_set_sigsafe_err_fds(const int *fds, int n)
116 {
117  if (n > TOR_SIGSAFE_LOG_MAX_FDS) {
119  }
120 
121  memcpy(sigsafe_log_fds, fds, n * sizeof(int));
122  n_sigsafe_log_fds = n;
123 }
124 
128 void
130 {
131  int fds[] = { STDERR_FILENO };
133 }
134 
139 void
141 {
142  log_granularity = ms;
143 }
144 
151 void
152 tor_raw_assertion_failed_msg_(const char *file, int line, const char *expr,
153  const char *msg)
154 {
155  char linebuf[16];
156  format_dec_number_sigsafe(line, linebuf, sizeof(linebuf));
157  tor_log_err_sigsafe("INTERNAL ERROR: Raw assertion failed at ",
158  file, ":", linebuf, ": ", expr, NULL);
159  if (msg) {
162  }
163 
164  dump_stack_symbols_to_error_fds();
165 }
166 
167 /* As format_{hex,dex}_number_sigsafe, but takes a <b>radix</b> argument
168  * in range 2..16 inclusive. */
169 static int
170 format_number_sigsafe(unsigned long x, char *buf, int buf_len,
171  unsigned int radix)
172 {
173  unsigned long tmp;
174  int len;
175  char *cp;
176 
177  /* NOT tor_assert. This needs to be safe to run from within a signal
178  * handler, and from within the 'tor_assert() has failed' code. Not even
179  * raw_assert(), since raw_assert() calls this function on failure. */
180  if (radix < 2 || radix > 16)
181  return 0;
182 
183  /* Count how many digits we need. */
184  tmp = x;
185  len = 1;
186  while (tmp >= radix) {
187  tmp /= radix;
188  ++len;
189  }
190 
191  /* Not long enough */
192  if (!buf || len >= buf_len)
193  return 0;
194 
195  cp = buf + len;
196  *cp = '\0';
197  do {
198  unsigned digit = (unsigned) (x % radix);
199  if (cp <= buf) {
200  /* Not tor_assert(); see above. */
201  abort();
202  }
203  --cp;
204  *cp = "0123456789ABCDEF"[digit];
205  x /= radix;
206  } while (x);
207 
208  /* NOT tor_assert; see above. */
209  if (cp != buf) {
210  abort(); // LCOV_EXCL_LINE
211  }
212 
213  return len;
214 }
215 
237 int
238 format_hex_number_sigsafe(unsigned long x, char *buf, int buf_len)
239 {
240  return format_number_sigsafe(x, buf, buf_len, 16);
241 }
242 
244 int
245 format_dec_number_sigsafe(unsigned long x, char *buf, int buf_len)
246 {
247  return format_number_sigsafe(x, buf, buf_len, 10);
248 }
void tor_raw_assertion_failed_msg_(const char *file, int line, const char *expr, const char *msg)
Definition: torerr.c:152
Header for backtrace.c.
void tor_log_err_sigsafe(const char *m,...)
Definition: torerr.c:70
Definitions for timing-related constants.
void tor_log_sigsafe_err_set_granularity(int ms)
Definition: torerr.c:140
void tor_log_set_sigsafe_err_fds(const int *fds, int n)
Definition: torerr.c:115
static int sigsafe_log_fds[TOR_SIGSAFE_LOG_MAX_FDS]
Definition: torerr.c:44
int format_hex_number_sigsafe(unsigned long x, char *buf, int buf_len)
Definition: torerr.c:238
static int log_granularity
Definition: torerr.c:48
static int tor_log_err_sigsafe_write(const char *s)
Definition: torerr.c:53
#define TOR_SIGSAFE_LOG_MAX_FDS
Definition: torerr.h:37
int format_dec_number_sigsafe(unsigned long x, char *buf, int buf_len)
Definition: torerr.c:245
void tor_log_reset_sigsafe_err_fds(void)
Definition: torerr.c:129
Headers for torerr.c.
static int n_sigsafe_log_fds
Definition: torerr.c:46
int tor_log_get_sigsafe_err_fds(const int **out)
Definition: torerr.c:103