diff options
author | Namhyung Kim <namhyung@kernel.org> | 2013-12-19 04:17:44 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2014-01-15 13:10:19 -0500 |
commit | 3c6d8d84423932f1d9949179c6acdf2405515ee4 (patch) | |
tree | 3a4d71442a447666dc3993049abb60f03323b757 /tools/lib | |
parent | 7d16c634233c411f54b89d0f1d51750dc85c5f7e (diff) |
tools lib traceevent: Add state member to struct trace_seq
The trace_seq->state is for tracking errors during the use of trace_seq
APIs and getting rid of die() in it.
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Reviewed-by: Jiri Olsa <jolsa@redhat.com>
Acked-by: Steven Rostedt <rostedt@goodmis.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung.kim@lge.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Steven Rostedt <rostedt@goodmis.org>
Link: http://lkml.kernel.org/r/87fvopalbb.fsf@sejong.aot.lge.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/lib')
-rw-r--r-- | tools/lib/traceevent/Makefile | 2 | ||||
-rw-r--r-- | tools/lib/traceevent/event-parse.h | 7 | ||||
-rw-r--r-- | tools/lib/traceevent/trace-seq.c | 55 |
3 files changed, 50 insertions, 14 deletions
diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile index f778d48ac609..56d52a33a3df 100644 --- a/tools/lib/traceevent/Makefile +++ b/tools/lib/traceevent/Makefile | |||
@@ -136,7 +136,7 @@ export Q VERBOSE | |||
136 | 136 | ||
137 | EVENT_PARSE_VERSION = $(EP_VERSION).$(EP_PATCHLEVEL).$(EP_EXTRAVERSION) | 137 | EVENT_PARSE_VERSION = $(EP_VERSION).$(EP_PATCHLEVEL).$(EP_EXTRAVERSION) |
138 | 138 | ||
139 | INCLUDES = -I. $(CONFIG_INCLUDES) | 139 | INCLUDES = -I. -I $(srctree)/../../include $(CONFIG_INCLUDES) |
140 | 140 | ||
141 | # Set compile option CFLAGS if not set elsewhere | 141 | # Set compile option CFLAGS if not set elsewhere |
142 | CFLAGS ?= -g -Wall | 142 | CFLAGS ?= -g -Wall |
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h index cf5db9013f2c..3c890cb28db7 100644 --- a/tools/lib/traceevent/event-parse.h +++ b/tools/lib/traceevent/event-parse.h | |||
@@ -58,6 +58,12 @@ struct pevent_record { | |||
58 | #endif | 58 | #endif |
59 | }; | 59 | }; |
60 | 60 | ||
61 | enum trace_seq_fail { | ||
62 | TRACE_SEQ__GOOD, | ||
63 | TRACE_SEQ__BUFFER_POISONED, | ||
64 | TRACE_SEQ__MEM_ALLOC_FAILED, | ||
65 | }; | ||
66 | |||
61 | /* | 67 | /* |
62 | * Trace sequences are used to allow a function to call several other functions | 68 | * Trace sequences are used to allow a function to call several other functions |
63 | * to create a string of data to use (up to a max of PAGE_SIZE). | 69 | * to create a string of data to use (up to a max of PAGE_SIZE). |
@@ -68,6 +74,7 @@ struct trace_seq { | |||
68 | unsigned int buffer_size; | 74 | unsigned int buffer_size; |
69 | unsigned int len; | 75 | unsigned int len; |
70 | unsigned int readpos; | 76 | unsigned int readpos; |
77 | enum trace_seq_fail state; | ||
71 | }; | 78 | }; |
72 | 79 | ||
73 | void trace_seq_init(struct trace_seq *s); | 80 | void trace_seq_init(struct trace_seq *s); |
diff --git a/tools/lib/traceevent/trace-seq.c b/tools/lib/traceevent/trace-seq.c index d7f2e68bc5b9..f7112138e6af 100644 --- a/tools/lib/traceevent/trace-seq.c +++ b/tools/lib/traceevent/trace-seq.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <string.h> | 22 | #include <string.h> |
23 | #include <stdarg.h> | 23 | #include <stdarg.h> |
24 | 24 | ||
25 | #include <asm/bug.h> | ||
25 | #include "event-parse.h" | 26 | #include "event-parse.h" |
26 | #include "event-utils.h" | 27 | #include "event-utils.h" |
27 | 28 | ||
@@ -32,10 +33,21 @@ | |||
32 | #define TRACE_SEQ_POISON ((void *)0xdeadbeef) | 33 | #define TRACE_SEQ_POISON ((void *)0xdeadbeef) |
33 | #define TRACE_SEQ_CHECK(s) \ | 34 | #define TRACE_SEQ_CHECK(s) \ |
34 | do { \ | 35 | do { \ |
35 | if ((s)->buffer == TRACE_SEQ_POISON) \ | 36 | if (WARN_ONCE((s)->buffer == TRACE_SEQ_POISON, \ |
36 | die("Usage of trace_seq after it was destroyed"); \ | 37 | "Usage of trace_seq after it was destroyed")) \ |
38 | (s)->state = TRACE_SEQ__BUFFER_POISONED; \ | ||
37 | } while (0) | 39 | } while (0) |
38 | 40 | ||
41 | #define TRACE_SEQ_CHECK_RET_N(s, n) \ | ||
42 | do { \ | ||
43 | TRACE_SEQ_CHECK(s); \ | ||
44 | if ((s)->state != TRACE_SEQ__GOOD) \ | ||
45 | return n; \ | ||
46 | } while (0) | ||
47 | |||
48 | #define TRACE_SEQ_CHECK_RET(s) TRACE_SEQ_CHECK_RET_N(s, ) | ||
49 | #define TRACE_SEQ_CHECK_RET0(s) TRACE_SEQ_CHECK_RET_N(s, 0) | ||
50 | |||
39 | /** | 51 | /** |
40 | * trace_seq_init - initialize the trace_seq structure | 52 | * trace_seq_init - initialize the trace_seq structure |
41 | * @s: a pointer to the trace_seq structure to initialize | 53 | * @s: a pointer to the trace_seq structure to initialize |
@@ -46,6 +58,7 @@ void trace_seq_init(struct trace_seq *s) | |||
46 | s->readpos = 0; | 58 | s->readpos = 0; |
47 | s->buffer_size = TRACE_SEQ_BUF_SIZE; | 59 | s->buffer_size = TRACE_SEQ_BUF_SIZE; |
48 | s->buffer = malloc_or_die(s->buffer_size); | 60 | s->buffer = malloc_or_die(s->buffer_size); |
61 | s->state = TRACE_SEQ__GOOD; | ||
49 | } | 62 | } |
50 | 63 | ||
51 | /** | 64 | /** |
@@ -71,7 +84,7 @@ void trace_seq_destroy(struct trace_seq *s) | |||
71 | { | 84 | { |
72 | if (!s) | 85 | if (!s) |
73 | return; | 86 | return; |
74 | TRACE_SEQ_CHECK(s); | 87 | TRACE_SEQ_CHECK_RET(s); |
75 | free(s->buffer); | 88 | free(s->buffer); |
76 | s->buffer = TRACE_SEQ_POISON; | 89 | s->buffer = TRACE_SEQ_POISON; |
77 | } | 90 | } |
@@ -80,8 +93,9 @@ static void expand_buffer(struct trace_seq *s) | |||
80 | { | 93 | { |
81 | s->buffer_size += TRACE_SEQ_BUF_SIZE; | 94 | s->buffer_size += TRACE_SEQ_BUF_SIZE; |
82 | s->buffer = realloc(s->buffer, s->buffer_size); | 95 | s->buffer = realloc(s->buffer, s->buffer_size); |
83 | if (!s->buffer) | 96 | if (WARN_ONCE(!s->buffer, |
84 | die("Can't allocate trace_seq buffer memory"); | 97 | "Can't allocate trace_seq buffer memory")) |
98 | s->state = TRACE_SEQ__MEM_ALLOC_FAILED; | ||
85 | } | 99 | } |
86 | 100 | ||
87 | /** | 101 | /** |
@@ -105,9 +119,9 @@ trace_seq_printf(struct trace_seq *s, const char *fmt, ...) | |||
105 | int len; | 119 | int len; |
106 | int ret; | 120 | int ret; |
107 | 121 | ||
108 | TRACE_SEQ_CHECK(s); | ||
109 | |||
110 | try_again: | 122 | try_again: |
123 | TRACE_SEQ_CHECK_RET0(s); | ||
124 | |||
111 | len = (s->buffer_size - 1) - s->len; | 125 | len = (s->buffer_size - 1) - s->len; |
112 | 126 | ||
113 | va_start(ap, fmt); | 127 | va_start(ap, fmt); |
@@ -141,9 +155,9 @@ trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args) | |||
141 | int len; | 155 | int len; |
142 | int ret; | 156 | int ret; |
143 | 157 | ||
144 | TRACE_SEQ_CHECK(s); | ||
145 | |||
146 | try_again: | 158 | try_again: |
159 | TRACE_SEQ_CHECK_RET0(s); | ||
160 | |||
147 | len = (s->buffer_size - 1) - s->len; | 161 | len = (s->buffer_size - 1) - s->len; |
148 | 162 | ||
149 | ret = vsnprintf(s->buffer + s->len, len, fmt, args); | 163 | ret = vsnprintf(s->buffer + s->len, len, fmt, args); |
@@ -172,13 +186,15 @@ int trace_seq_puts(struct trace_seq *s, const char *str) | |||
172 | { | 186 | { |
173 | int len; | 187 | int len; |
174 | 188 | ||
175 | TRACE_SEQ_CHECK(s); | 189 | TRACE_SEQ_CHECK_RET0(s); |
176 | 190 | ||
177 | len = strlen(str); | 191 | len = strlen(str); |
178 | 192 | ||
179 | while (len > ((s->buffer_size - 1) - s->len)) | 193 | while (len > ((s->buffer_size - 1) - s->len)) |
180 | expand_buffer(s); | 194 | expand_buffer(s); |
181 | 195 | ||
196 | TRACE_SEQ_CHECK_RET0(s); | ||
197 | |||
182 | memcpy(s->buffer + s->len, str, len); | 198 | memcpy(s->buffer + s->len, str, len); |
183 | s->len += len; | 199 | s->len += len; |
184 | 200 | ||
@@ -187,11 +203,13 @@ int trace_seq_puts(struct trace_seq *s, const char *str) | |||
187 | 203 | ||
188 | int trace_seq_putc(struct trace_seq *s, unsigned char c) | 204 | int trace_seq_putc(struct trace_seq *s, unsigned char c) |
189 | { | 205 | { |
190 | TRACE_SEQ_CHECK(s); | 206 | TRACE_SEQ_CHECK_RET0(s); |
191 | 207 | ||
192 | while (s->len >= (s->buffer_size - 1)) | 208 | while (s->len >= (s->buffer_size - 1)) |
193 | expand_buffer(s); | 209 | expand_buffer(s); |
194 | 210 | ||
211 | TRACE_SEQ_CHECK_RET0(s); | ||
212 | |||
195 | s->buffer[s->len++] = c; | 213 | s->buffer[s->len++] = c; |
196 | 214 | ||
197 | return 1; | 215 | return 1; |
@@ -199,7 +217,7 @@ int trace_seq_putc(struct trace_seq *s, unsigned char c) | |||
199 | 217 | ||
200 | void trace_seq_terminate(struct trace_seq *s) | 218 | void trace_seq_terminate(struct trace_seq *s) |
201 | { | 219 | { |
202 | TRACE_SEQ_CHECK(s); | 220 | TRACE_SEQ_CHECK_RET(s); |
203 | 221 | ||
204 | /* There's always one character left on the buffer */ | 222 | /* There's always one character left on the buffer */ |
205 | s->buffer[s->len] = 0; | 223 | s->buffer[s->len] = 0; |
@@ -208,5 +226,16 @@ void trace_seq_terminate(struct trace_seq *s) | |||
208 | int trace_seq_do_printf(struct trace_seq *s) | 226 | int trace_seq_do_printf(struct trace_seq *s) |
209 | { | 227 | { |
210 | TRACE_SEQ_CHECK(s); | 228 | TRACE_SEQ_CHECK(s); |
211 | return printf("%.*s", s->len, s->buffer); | 229 | |
230 | switch (s->state) { | ||
231 | case TRACE_SEQ__GOOD: | ||
232 | return printf("%.*s", s->len, s->buffer); | ||
233 | case TRACE_SEQ__BUFFER_POISONED: | ||
234 | puts("Usage of trace_seq after it was destroyed"); | ||
235 | break; | ||
236 | case TRACE_SEQ__MEM_ALLOC_FAILED: | ||
237 | puts("Can't allocate trace_seq buffer memory"); | ||
238 | break; | ||
239 | } | ||
240 | return -1; | ||
212 | } | 241 | } |