OpenOCD
helper/log.c
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005 by Dominic Rath *
3  * Dominic.Rath@gmx.de *
4  * *
5  * Copyright (C) 2007-2010 Øyvind Harboe *
6  * oyvind.harboe@zylin.com *
7  * *
8  * Copyright (C) 2008 by Spencer Oliver *
9  * spen@spen-soft.co.uk *
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  * This program is distributed in the hope that it will be useful, *
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19  * GNU General Public License for more details. *
20  * *
21  * You should have received a copy of the GNU General Public License *
22  * along with this program. If not, see <http://www.gnu.org/licenses/>. *
23  ***************************************************************************/
24 
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28 
29 #include "log.h"
30 #include "command.h"
31 #include "time_support.h"
32 
33 #include <stdarg.h>
34 
35 #ifdef _DEBUG_FREE_SPACE_
36 #ifdef HAVE_MALLOC_H
37 #include <malloc.h>
38 #else
39 #error "malloc.h is required to use --enable-malloc-logging"
40 #endif
41 #endif
42 
44 
45 static FILE *log_output;
46 static struct log_callback *log_callbacks;
47 
48 static int64_t last_time;
49 static int64_t current_time;
50 
51 static int64_t start;
52 
53 static const char * const log_strings[6] = {
54  "User : ",
55  "Error: ",
56  "Warn : ", /* want a space after each colon, all same width, colons aligned */
57  "Info : ",
58  "Debug: ",
59  "Debug: "
60 };
61 
62 static int count;
63 
64 /* forward the log to the listeners */
65 static void log_forward(const char *file, unsigned line, const char *function, const char *string)
66 {
67  struct log_callback *cb, *next;
68  cb = log_callbacks;
69  /* DANGER!!!! the log callback can remove itself!!!! */
70  while (cb) {
71  next = cb->next;
72  cb->fn(cb->priv, file, line, function, string);
73  cb = next;
74  }
75 }
76 
77 /* The log_puts() serves two somewhat different goals:
78  *
79  * - logging
80  * - feeding low-level info to the user in GDB or Telnet
81  *
82  * The latter dictates that strings without newline are not logged, lest there
83  * will be *MANY log lines when sending one char at the time(e.g.
84  * target_request.c).
85  *
86  */
87 static void log_puts(enum log_levels level,
88  const char *file,
89  int line,
90  const char *function,
91  const char *string)
92 {
93  char *f;
94 
95  if (!log_output) {
96  /* log_init() not called yet; print on stderr */
97  fputs(string, stderr);
98  fflush(stderr);
99  return;
100  }
101 
102  if (level == LOG_LVL_OUTPUT) {
103  /* do not prepend any headers, just print out what we were given and return */
104  fputs(string, log_output);
105  fflush(log_output);
106  return;
107  }
108 
109  f = strrchr(file, '/');
110  if (f != NULL)
111  file = f + 1;
112 
113  if (strlen(string) > 0) {
114  if (debug_level >= LOG_LVL_DEBUG) {
115  /* print with count and time information */
116  int64_t t = timeval_ms() - start;
117 #ifdef _DEBUG_FREE_SPACE_
118  struct mallinfo info;
119  info = mallinfo();
120 #endif
121  fprintf(log_output, "%s%d %" PRId64 " %s:%d %s()"
122 #ifdef _DEBUG_FREE_SPACE_
123  " %d"
124 #endif
125  ": %s", log_strings[level + 1], count, t, file, line, function,
126 #ifdef _DEBUG_FREE_SPACE_
127  info.fordblks,
128 #endif
129  string);
130  } else {
131  /* if we are using gdb through pipes then we do not want any output
132  * to the pipe otherwise we get repeated strings */
133  fprintf(log_output, "%s%s",
134  (level > LOG_LVL_USER) ? log_strings[level + 1] : "", string);
135  }
136  } else {
137  /* Empty strings are sent to log callbacks to keep e.g. gdbserver alive, here we do
138  *nothing. */
139  }
140 
141  fflush(log_output);
142 
143  /* Never forward LOG_LVL_DEBUG, too verbose and they can be found in the log if need be */
144  if (level <= LOG_LVL_INFO)
145  log_forward(file, line, function, string);
146 }
147 
148 void log_printf(enum log_levels level,
149  const char *file,
150  unsigned line,
151  const char *function,
152  const char *format,
153  ...)
154 {
155  char *string;
156  va_list ap;
157 
158  count++;
159  if (level > debug_level)
160  return;
161 
162  va_start(ap, format);
163 
164  string = alloc_vprintf(format, ap);
165  if (string != NULL) {
166  log_puts(level, file, line, function, string);
167  free(string);
168  }
169 
170  va_end(ap);
171 }
172 
173 void log_vprintf_lf(enum log_levels level, const char *file, unsigned line,
174  const char *function, const char *format, va_list args)
175 {
176  char *tmp;
177 
178  count++;
179 
180  if (level > debug_level)
181  return;
182 
183  tmp = alloc_vprintf(format, args);
184 
185  if (!tmp)
186  return;
187 
188  /*
189  * Note: alloc_vprintf() guarantees that the buffer is at least one
190  * character longer.
191  */
192  strcat(tmp, "\n");
193  log_puts(level, file, line, function, tmp);
194  free(tmp);
195 }
196 
197 void log_printf_lf(enum log_levels level,
198  const char *file,
199  unsigned line,
200  const char *function,
201  const char *format,
202  ...)
203 {
204  va_list ap;
205 
206  va_start(ap, format);
207  log_vprintf_lf(level, file, line, function, format, ap);
208  va_end(ap);
209 }
210 
211 COMMAND_HANDLER(handle_debug_level_command)
212 {
213  if (CMD_ARGC == 1) {
214  int new_level;
215  COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], new_level);
216  if ((new_level > LOG_LVL_DEBUG_IO) || (new_level < LOG_LVL_SILENT)) {
217  LOG_ERROR("level must be between %d and %d", LOG_LVL_SILENT, LOG_LVL_DEBUG_IO);
219  }
220  debug_level = new_level;
221  } else if (CMD_ARGC > 1)
223 
224  command_print(CMD, "debug_level: %i", debug_level);
225 
226  return ERROR_OK;
227 }
228 
229 COMMAND_HANDLER(handle_log_output_command)
230 {
231  if (CMD_ARGC == 0 || (CMD_ARGC == 1 && strcmp(CMD_ARGV[0], "default") == 0)) {
232  if (log_output != stderr && log_output != NULL) {
233  /* Close previous log file, if it was open and wasn't stderr. */
234  fclose(log_output);
235  }
236  log_output = stderr;
237  LOG_DEBUG("set log_output to default");
238  return ERROR_OK;
239  }
240  if (CMD_ARGC == 1) {
241  FILE *file = fopen(CMD_ARGV[0], "w");
242  if (file == NULL) {
243  LOG_ERROR("failed to open output log '%s'", CMD_ARGV[0]);
244  return ERROR_FAIL;
245  }
246  if (log_output != stderr && log_output != NULL) {
247  /* Close previous log file, if it was open and wasn't stderr. */
248  fclose(log_output);
249  }
250  log_output = file;
251  LOG_DEBUG("set log_output to \"%s\"", CMD_ARGV[0]);
252  return ERROR_OK;
253  }
254 
256 }
257 
259  {
260  .name = "log_output",
261  .handler = handle_log_output_command,
262  .mode = COMMAND_ANY,
263  .help = "redirect logging to a file (default: stderr)",
264  .usage = "[file_name | \"default\"]",
265  },
266  {
267  .name = "debug_level",
268  .handler = handle_debug_level_command,
269  .mode = COMMAND_ANY,
270  .help = "Sets the verbosity level of debugging output. "
271  "0 shows errors only; 1 adds warnings; "
272  "2 (default) adds other info; 3 adds debugging; "
273  "4 adds extra verbose debugging.",
274  .usage = "number",
275  },
277 };
278 
280 {
281  return register_commands(cmd_ctx, NULL, log_command_handlers);
282 }
283 
284 void log_init(void)
285 {
286  /* set defaults for daemon configuration,
287  * if not set by cmdline or cfgfile */
288  char *debug_env = getenv("OPENOCD_DEBUG_LEVEL");
289  if (NULL != debug_env) {
290  int value;
291  int retval = parse_int(debug_env, &value);
292  if (ERROR_OK == retval &&
295  debug_level = value;
296  }
297 
298  if (log_output == NULL)
299  log_output = stderr;
300 
301  start = last_time = timeval_ms();
302 }
303 
304 int set_log_output(struct command_context *cmd_ctx, FILE *output)
305 {
306  log_output = output;
307  return ERROR_OK;
308 }
309 
310 /* add/remove log callback handler */
312 {
313  struct log_callback *cb;
314 
315  /* prevent the same callback to be registered more than once, just for sure */
316  for (cb = log_callbacks; cb; cb = cb->next) {
317  if (cb->fn == fn && cb->priv == priv)
319  }
320 
321  /* alloc memory, it is safe just to return in case of an error, no need for the caller to
322  *check this */
323  cb = malloc(sizeof(struct log_callback));
324  if (cb == NULL)
325  return ERROR_BUF_TOO_SMALL;
326 
327  /* add item to the beginning of the linked list */
328  cb->fn = fn;
329  cb->priv = priv;
330  cb->next = log_callbacks;
331  log_callbacks = cb;
332 
333  return ERROR_OK;
334 }
335 
337 {
338  struct log_callback *cb, **p;
339 
340  for (p = &log_callbacks; (cb = *p); p = &(*p)->next) {
341  if (cb->fn == fn && cb->priv == priv) {
342  *p = cb->next;
343  free(cb);
344  return ERROR_OK;
345  }
346  }
347 
348  /* no such item */
350 }
351 
352 /* return allocated string w/printf() result */
353 char *alloc_vprintf(const char *fmt, va_list ap)
354 {
355  va_list ap_copy;
356  int len;
357  char *string;
358 
359  /* determine the length of the buffer needed */
360  va_copy(ap_copy, ap);
361  len = vsnprintf(NULL, 0, fmt, ap_copy);
362  va_end(ap_copy);
363 
364  /* allocate and make room for terminating zero. */
365  /* FIXME: The old version always allocated at least one byte extra and
366  * other code depend on that. They should be probably be fixed, but for
367  * now reserve the extra byte. */
368  string = malloc(len + 2);
369  if (string == NULL)
370  return NULL;
371 
372  /* do the real work */
373  vsnprintf(string, len + 1, fmt, ap);
374 
375  return string;
376 }
377 
378 char *alloc_printf(const char *format, ...)
379 {
380  char *string;
381  va_list ap;
382  va_start(ap, format);
383  string = alloc_vprintf(format, ap);
384  va_end(ap);
385  return string;
386 }
387 
388 /* Code must return to the server loop before 1000ms has returned or invoke
389  * this function.
390  *
391  * The GDB connection will time out if it spends >2000ms and you'll get nasty
392  * error messages from GDB:
393  *
394  * Ignoring packet error, continuing...
395  * Reply contains invalid hex digit 116
396  *
397  * While it is possible use "set remotetimeout" to more than the default 2000ms
398  * in GDB, OpenOCD guarantees that it sends keep-alive packages on the
399  * GDB protocol and it is a bug in OpenOCD not to either return to the server
400  * loop or invoke keep_alive() every 1000ms.
401  *
402  * This function will send a keep alive packet if >500ms has passed since last time
403  * it was invoked.
404  *
405  * Note that this function can be invoked often, so it needs to be relatively
406  * fast when invoked more often than every 500ms.
407  *
408  */
409 #define KEEP_ALIVE_KICK_TIME_MS 500
410 #define KEEP_ALIVE_TIMEOUT_MS 1000
411 
412 static void gdb_timeout_warning(int64_t delta_time)
413 {
414  extern int gdb_actual_connections;
415 
416  if (gdb_actual_connections)
417  LOG_WARNING("keep_alive() was not invoked in the "
418  "%d ms timelimit. GDB alive packet not "
419  "sent! (%" PRId64 " ms). Workaround: increase "
420  "\"set remotetimeout\" in GDB",
422  delta_time);
423  else
424  LOG_DEBUG("keep_alive() was not invoked in the "
425  "%d ms timelimit (%" PRId64 " ms). This may cause "
426  "trouble with GDB connections.",
428  delta_time);
429 }
430 
431 void keep_alive(void)
432 {
434 
435  int64_t delta_time = current_time - last_time;
436 
437  if (delta_time > KEEP_ALIVE_TIMEOUT_MS) {
438  last_time = current_time;
439 
440  gdb_timeout_warning(delta_time);
441  }
442 
443  if (delta_time > KEEP_ALIVE_KICK_TIME_MS) {
444  last_time = current_time;
445 
446  /* this will keep the GDB connection alive */
447  LOG_USER_N("%s", "");
448 
449  /* DANGER!!!! do not add code to invoke e.g. target event processing,
450  * jim timer processing, etc. it can cause infinite recursion +
451  * jim event callbacks need to happen at a well defined time,
452  * not anywhere keep_alive() is invoked.
453  *
454  * These functions should be invoked at a well defined spot in server.c
455  */
456  }
457 }
458 
459 /* reset keep alive timer without sending message */
460 void kept_alive(void)
461 {
463 
464  int64_t delta_time = current_time - last_time;
465 
466  last_time = current_time;
467 
468  if (delta_time > KEEP_ALIVE_TIMEOUT_MS)
469  gdb_timeout_warning(delta_time);
470 }
471 
472 /* if we sleep for extended periods of time, we must invoke keep_alive() intermittently */
473 void alive_sleep(uint64_t ms)
474 {
475  uint64_t napTime = 10;
476  for (uint64_t i = 0; i < ms; i += napTime) {
477  uint64_t sleep_a_bit = ms - i;
478  if (sleep_a_bit > napTime)
479  sleep_a_bit = napTime;
480 
481  usleep(sleep_a_bit * 1000);
482  keep_alive();
483  }
484 }
485 
486 void busy_sleep(uint64_t ms)
487 {
488  uint64_t then = timeval_ms();
489  while (timeval_ms() - then < ms) {
490  /*
491  * busy wait
492  */
493  }
494 }
495 
496 /* Maximum size of socket error message retrieved from operation system */
497 #define MAX_SOCKET_ERR_MSG_LENGTH 256
498 
499 /* Provide log message for the last socket error.
500  Uses errno on *nix and WSAGetLastError() on Windows */
501 void log_socket_error(const char *socket_desc)
502 {
503  int error_code;
504 #ifdef _WIN32
505  error_code = WSAGetLastError();
506  char error_message[MAX_SOCKET_ERR_MSG_LENGTH];
507  error_message[0] = '\0';
508  DWORD retval = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error_code, 0,
509  error_message, MAX_SOCKET_ERR_MSG_LENGTH, NULL);
510  error_message[MAX_SOCKET_ERR_MSG_LENGTH - 1] = '\0';
511  const bool have_message = (retval != 0) && (error_message[0] != '\0');
512  LOG_ERROR("Error on socket '%s': WSAGetLastError==%d%s%s.", socket_desc, error_code,
513  (have_message ? ", message: " : ""),
514  (have_message ? error_message : ""));
515 #else
516  error_code = errno;
517  LOG_ERROR("Error on socket '%s': errno==%d, message: %s.", socket_desc, error_code, strerror(error_code));
518 #endif
519 }
static int64_t start
Definition: helper/log.c:51
static void log_puts(enum log_levels level, const char *file, int line, const char *function, const char *string)
Definition: helper/log.c:87
static uint16_t output
Definition: ftdi.c:129
int debug_level
Definition: helper/log.c:43
#define ERROR_BUF_TOO_SMALL
Definition: log.h:149
void log_printf_lf(enum log_levels level, const char *file, unsigned line, const char *function, const char *format,...)
Definition: helper/log.c:197
void kept_alive(void)
Definition: helper/log.c:460
int register_commands(struct command_context *cmd_ctx, struct command *parent, const struct command_registration *cmds)
Register one or more commands in the specified context, as children of parent (or top-level commends...
Definition: command.c:398
void keep_alive(void)
Definition: helper/log.c:431
void log_printf(enum log_levels level, const char *file, unsigned line, const char *function, const char *format,...)
Definition: helper/log.c:148
void log_init(void)
Initialize logging module.
Definition: helper/log.c:284
char * alloc_printf(const char *format,...)
Definition: helper/log.c:378
int log_remove_callback(log_callback_fn fn, void *priv)
Definition: helper/log.c:336
#define MAX_SOCKET_ERR_MSG_LENGTH
Definition: helper/log.c:497
COMMAND_HANDLER(handle_debug_level_command)
Definition: helper/log.c:211
#define ERROR_FAIL
Definition: log.h:153
int64_t timeval_ms(void)
log_callback_fn fn
Definition: log.h:91
int log_add_callback(log_callback_fn fn, void *priv)
Definition: helper/log.c:311
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
Definition: command.h:144
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:139
int gdb_actual_connections
Definition: gdb_server.c:122
#define CMD
Use this macro to access the command being handled, rather than accessing the variable directly...
Definition: command.h:129
static const char *const log_strings[6]
Definition: helper/log.c:53
#define KEEP_ALIVE_TIMEOUT_MS
Definition: helper/log.c:410
#define KEEP_ALIVE_KICK_TIME_MS
Definition: helper/log.c:409
void command_print(struct command_invocation *cmd, const char *format,...)
Definition: command.c:505
static const struct command_registration log_command_handlers[]
Definition: helper/log.c:258
static struct log_callback * log_callbacks
Definition: helper/log.c:46
#define LOG_ERROR(expr ...)
Definition: log.h:132
#define COMMAND_PARSE_NUMBER(type, in, out)
parses the string in into out as a type, or prints a command error and passes the error code to the c...
Definition: command.h:368
char * alloc_vprintf(const char *fmt, va_list ap)
Definition: helper/log.c:353
static void gdb_timeout_warning(int64_t delta_time)
Definition: helper/log.c:412
#define LOG_USER_N(expr ...)
Definition: log.h:138
void log_vprintf_lf(enum log_levels level, const char *file, unsigned line, const char *function, const char *format, va_list args)
Definition: helper/log.c:173
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:234
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:328
#define LOG_WARNING(expr ...)
Definition: log.h:129
const char * name
Definition: command.h:216
int log_register_commands(struct command_context *cmd_ctx)
Definition: helper/log.c:279
static int64_t last_time
Definition: helper/log.c:48
void busy_sleep(uint64_t ms)
Definition: helper/log.c:486
static FILE * log_output
Definition: helper/log.c:45
struct log_callback * next
Definition: log.h:93
static void log_forward(const char *file, unsigned line, const char *function, const char *string)
Definition: helper/log.c:65
void * priv
Definition: log.h:92
void(* log_callback_fn)(void *priv, const char *file, unsigned line, const char *function, const char *string)
Definition: log.h:87
#define ERROR_OK
Definition: log.h:147
void alive_sleep(uint64_t ms)
Definition: helper/log.c:473
static int count
Definition: helper/log.c:62
int set_log_output(struct command_context *cmd_ctx, FILE *output)
Definition: helper/log.c:304
#define NULL
Definition: usb.h:27
#define LOG_DEBUG(expr ...)
Definition: log.h:118
static int64_t current_time
Definition: helper/log.c:49
void log_socket_error(const char *socket_desc)
Definition: helper/log.c:501
log_levels
Definition: log.h:51
#define DWORD
Definition: x86_32_common.h:44