diff options
Diffstat (limited to 'tools/lib/traceevent/trace-seq.c')
| -rw-r--r-- | tools/lib/traceevent/trace-seq.c | 67 | 
1 files changed, 52 insertions, 15 deletions
diff --git a/tools/lib/traceevent/trace-seq.c b/tools/lib/traceevent/trace-seq.c index d7f2e68bc5b9..ec3bd16a5488 100644 --- a/tools/lib/traceevent/trace-seq.c +++ b/tools/lib/traceevent/trace-seq.c @@ -22,6 +22,7 @@  #include <string.h>  #include <stdarg.h> +#include <asm/bug.h>  #include "event-parse.h"  #include "event-utils.h" @@ -32,10 +33,21 @@  #define TRACE_SEQ_POISON	((void *)0xdeadbeef)  #define TRACE_SEQ_CHECK(s)						\  do {									\ -	if ((s)->buffer == TRACE_SEQ_POISON)			\ -		die("Usage of trace_seq after it was destroyed");	\ +	if (WARN_ONCE((s)->buffer == TRACE_SEQ_POISON,			\ +		      "Usage of trace_seq after it was destroyed"))	\ +		(s)->state = TRACE_SEQ__BUFFER_POISONED;		\  } while (0) +#define TRACE_SEQ_CHECK_RET_N(s, n)		\ +do {						\ +	TRACE_SEQ_CHECK(s);			\ +	if ((s)->state != TRACE_SEQ__GOOD)	\ +		return n; 			\ +} while (0) + +#define TRACE_SEQ_CHECK_RET(s)   TRACE_SEQ_CHECK_RET_N(s, ) +#define TRACE_SEQ_CHECK_RET0(s)  TRACE_SEQ_CHECK_RET_N(s, 0) +  /**   * trace_seq_init - initialize the trace_seq structure   * @s: a pointer to the trace_seq structure to initialize @@ -45,7 +57,11 @@ void trace_seq_init(struct trace_seq *s)  	s->len = 0;  	s->readpos = 0;  	s->buffer_size = TRACE_SEQ_BUF_SIZE; -	s->buffer = malloc_or_die(s->buffer_size); +	s->buffer = malloc(s->buffer_size); +	if (s->buffer != NULL) +		s->state = TRACE_SEQ__GOOD; +	else +		s->state = TRACE_SEQ__MEM_ALLOC_FAILED;  }  /** @@ -71,17 +87,23 @@ void trace_seq_destroy(struct trace_seq *s)  {  	if (!s)  		return; -	TRACE_SEQ_CHECK(s); +	TRACE_SEQ_CHECK_RET(s);  	free(s->buffer);  	s->buffer = TRACE_SEQ_POISON;  }  static void expand_buffer(struct trace_seq *s)  { +	char *buf; + +	buf = realloc(s->buffer, s->buffer_size + TRACE_SEQ_BUF_SIZE); +	if (WARN_ONCE(!buf, "Can't allocate trace_seq buffer memory")) { +		s->state = TRACE_SEQ__MEM_ALLOC_FAILED; +		return; +	} + +	s->buffer = buf;  	s->buffer_size += TRACE_SEQ_BUF_SIZE; -	s->buffer = realloc(s->buffer, s->buffer_size); -	if (!s->buffer) -		die("Can't allocate trace_seq buffer memory");  }  /** @@ -105,9 +127,9 @@ trace_seq_printf(struct trace_seq *s, const char *fmt, ...)  	int len;  	int ret; -	TRACE_SEQ_CHECK(s); -   try_again: +	TRACE_SEQ_CHECK_RET0(s); +  	len = (s->buffer_size - 1) - s->len;  	va_start(ap, fmt); @@ -141,9 +163,9 @@ trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args)  	int len;  	int ret; -	TRACE_SEQ_CHECK(s); -   try_again: +	TRACE_SEQ_CHECK_RET0(s); +  	len = (s->buffer_size - 1) - s->len;  	ret = vsnprintf(s->buffer + s->len, len, fmt, args); @@ -172,13 +194,15 @@ int trace_seq_puts(struct trace_seq *s, const char *str)  {  	int len; -	TRACE_SEQ_CHECK(s); +	TRACE_SEQ_CHECK_RET0(s);  	len = strlen(str);  	while (len > ((s->buffer_size - 1) - s->len))  		expand_buffer(s); +	TRACE_SEQ_CHECK_RET0(s); +  	memcpy(s->buffer + s->len, str, len);  	s->len += len; @@ -187,11 +211,13 @@ int trace_seq_puts(struct trace_seq *s, const char *str)  int trace_seq_putc(struct trace_seq *s, unsigned char c)  { -	TRACE_SEQ_CHECK(s); +	TRACE_SEQ_CHECK_RET0(s);  	while (s->len >= (s->buffer_size - 1))  		expand_buffer(s); +	TRACE_SEQ_CHECK_RET0(s); +  	s->buffer[s->len++] = c;  	return 1; @@ -199,7 +225,7 @@ int trace_seq_putc(struct trace_seq *s, unsigned char c)  void trace_seq_terminate(struct trace_seq *s)  { -	TRACE_SEQ_CHECK(s); +	TRACE_SEQ_CHECK_RET(s);  	/* There's always one character left on the buffer */  	s->buffer[s->len] = 0; @@ -208,5 +234,16 @@ void trace_seq_terminate(struct trace_seq *s)  int trace_seq_do_printf(struct trace_seq *s)  {  	TRACE_SEQ_CHECK(s); -	return printf("%.*s", s->len, s->buffer); + +	switch (s->state) { +	case TRACE_SEQ__GOOD: +		return printf("%.*s", s->len, s->buffer); +	case TRACE_SEQ__BUFFER_POISONED: +		puts("Usage of trace_seq after it was destroyed"); +		break; +	case TRACE_SEQ__MEM_ALLOC_FAILED: +		puts("Can't allocate trace_seq buffer memory"); +		break; +	} +	return -1;  }  |