Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[PATCH 4/4] tools lib traceevent: Get rid of die() finally!!

5 views
Skip to first unread message

Namhyung Kim

unread,
Dec 19, 2013, 4:40:01 AM12/19/13
to
From: Namhyung Kim <namhyu...@lge.com>

Now all of its users were gone. :)

Signed-off-by: Namhyung Kim <namh...@kernel.org>
---
tools/lib/traceevent/event-utils.h | 4 ----
tools/lib/traceevent/parse-utils.c | 44 --------------------------------------
2 files changed, 48 deletions(-)

diff --git a/tools/lib/traceevent/event-utils.h b/tools/lib/traceevent/event-utils.h
index e76c9acb92cd..d1dc2170e402 100644
--- a/tools/lib/traceevent/event-utils.h
+++ b/tools/lib/traceevent/event-utils.h
@@ -23,18 +23,14 @@
#include <ctype.h>

/* Can be overridden */
-void die(const char *fmt, ...);
-void *malloc_or_die(unsigned int size);
void warning(const char *fmt, ...);
void pr_stat(const char *fmt, ...);
void vpr_stat(const char *fmt, va_list ap);

/* Always available */
-void __die(const char *fmt, ...);
void __warning(const char *fmt, ...);
void __pr_stat(const char *fmt, ...);

-void __vdie(const char *fmt, ...);
void __vwarning(const char *fmt, ...);
void __vpr_stat(const char *fmt, ...);

diff --git a/tools/lib/traceevent/parse-utils.c b/tools/lib/traceevent/parse-utils.c
index bba701cf10e6..eda07fa31dca 100644
--- a/tools/lib/traceevent/parse-utils.c
+++ b/tools/lib/traceevent/parse-utils.c
@@ -25,40 +25,6 @@

#define __weak __attribute__((weak))

-void __vdie(const char *fmt, va_list ap)
-{
- int ret = errno;
-
- if (errno)
- perror("trace-cmd");
- else
- ret = -1;
-
- fprintf(stderr, " ");
- vfprintf(stderr, fmt, ap);
-
- fprintf(stderr, "\n");
- exit(ret);
-}
-
-void __die(const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- __vdie(fmt, ap);
- va_end(ap);
-}
-
-void __weak die(const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- __vdie(fmt, ap);
- va_end(ap);
-}
-
void __vwarning(const char *fmt, va_list ap)
{
if (errno)
@@ -117,13 +83,3 @@ void __weak pr_stat(const char *fmt, ...)
__vpr_stat(fmt, ap);
va_end(ap);
}
-
-void __weak *malloc_or_die(unsigned int size)
-{
- void *data;
-
- data = malloc(size);
- if (!data)
- die("malloc");
- return data;
-}
--
1.7.11.7

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majo...@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

Namhyung Kim

unread,
Dec 19, 2013, 4:40:02 AM12/19/13
to
From: Namhyung Kim <namhyu...@lge.com>

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 <namh...@kernel.org>
---
tools/lib/traceevent/event-parse.h | 7 +++++++
tools/lib/traceevent/trace-seq.c | 41 ++++++++++++++++++++++++++++++++++----
2 files changed, 44 insertions(+), 4 deletions(-)

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 {
#endif
};

+enum trace_seq_fail {
+ TRACE_SEQ__GOOD,
+ TRACE_SEQ__BUFFER_POISONED,
+ TRACE_SEQ__MEM_ALLOC_FAILED,
+};
+
/*
* Trace sequences are used to allow a function to call several other functions
* to create a string of data to use (up to a max of PAGE_SIZE).
@@ -68,6 +74,7 @@ struct trace_seq {
unsigned int buffer_size;
unsigned int len;
unsigned int readpos;
+ enum trace_seq_fail state;
};

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..976ad2a146b3 100644
--- a/tools/lib/traceevent/trace-seq.c
+++ b/tools/lib/traceevent/trace-seq.c
@@ -32,8 +32,8 @@
#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 ((s)->buffer == TRACE_SEQ_POISON) \
+ (s)->state = TRACE_SEQ__BUFFER_POISONED; \
} while (0)

/**
@@ -46,6 +46,7 @@ void trace_seq_init(struct trace_seq *s)
s->readpos = 0;
s->buffer_size = TRACE_SEQ_BUF_SIZE;
s->buffer = malloc_or_die(s->buffer_size);
+ s->state = TRACE_SEQ__GOOD;
}

/**
@@ -81,7 +82,7 @@ static void expand_buffer(struct trace_seq *s)
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");
+ s->state = TRACE_SEQ__MEM_ALLOC_FAILED;
}

/**
@@ -108,6 +109,9 @@ trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
TRACE_SEQ_CHECK(s);

try_again:
+ if (s->state != TRACE_SEQ__GOOD)
+ return 0;
+
len = (s->buffer_size - 1) - s->len;

va_start(ap, fmt);
@@ -144,6 +148,9 @@ trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args)
TRACE_SEQ_CHECK(s);

try_again:
+ if (s->state != TRACE_SEQ__GOOD)
+ return 0;
+
len = (s->buffer_size - 1) - s->len;

ret = vsnprintf(s->buffer + s->len, len, fmt, args);
@@ -174,11 +181,17 @@ int trace_seq_puts(struct trace_seq *s, const char *str)

TRACE_SEQ_CHECK(s);

+ if (s->state != TRACE_SEQ__GOOD)
+ return 0;
+
len = strlen(str);

while (len > ((s->buffer_size - 1) - s->len))
expand_buffer(s);

+ if (s->state != TRACE_SEQ__GOOD)
+ return 0;
+
memcpy(s->buffer + s->len, str, len);
s->len += len;

@@ -189,9 +202,15 @@ int trace_seq_putc(struct trace_seq *s, unsigned char c)
{
TRACE_SEQ_CHECK(s);

+ if (s->state != TRACE_SEQ__GOOD)
+ return 0;
+
while (s->len >= (s->buffer_size - 1))
expand_buffer(s);

+ if (s->state != TRACE_SEQ__GOOD)
+ return 0;
+
s->buffer[s->len++] = c;

return 1;
@@ -201,6 +220,9 @@ void trace_seq_terminate(struct trace_seq *s)
{
TRACE_SEQ_CHECK(s);

+ if (s->state != TRACE_SEQ__GOOD)
+ return;
+
/* There's always one character left on the buffer */
s->buffer[s->len] = 0;
}
@@ -208,5 +230,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;

Namhyung Kim

unread,
Dec 19, 2013, 4:40:02 AM12/19/13
to
From: Namhyung Kim <namhyu...@lge.com>

If realloc() fails, it'll leak the buffer. Also increate buffer size
only if the allocation succeeded.

Signed-off-by: Namhyung Kim <namh...@kernel.org>
---
tools/lib/traceevent/trace-seq.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/tools/lib/traceevent/trace-seq.c b/tools/lib/traceevent/trace-seq.c
index 976ad2a146b3..57405652f26d 100644
--- a/tools/lib/traceevent/trace-seq.c
+++ b/tools/lib/traceevent/trace-seq.c
@@ -79,10 +79,16 @@ void trace_seq_destroy(struct trace_seq *s)

static void expand_buffer(struct trace_seq *s)
{
- s->buffer_size += TRACE_SEQ_BUF_SIZE;
- s->buffer = realloc(s->buffer, s->buffer_size);
- if (!s->buffer)
+ char *buf;
+
+ buf = realloc(s->buffer, s->buffer_size + TRACE_SEQ_BUF_SIZE);
+ if (!buf) {
s->state = TRACE_SEQ__MEM_ALLOC_FAILED;
+ return;
+ }
+
+ s->buffer = buf;
+ s->buffer_size += TRACE_SEQ_BUF_SIZE;
}

/**

Namhyung Kim

unread,
Dec 19, 2013, 4:40:02 AM12/19/13
to
From: Namhyung Kim <namhyu...@lge.com>

Use plain malloc() and check its return value.

Signed-off-by: Namhyung Kim <namh...@kernel.org>
---
tools/lib/traceevent/trace-seq.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/tools/lib/traceevent/trace-seq.c b/tools/lib/traceevent/trace-seq.c
index 57405652f26d..d24a33190bb8 100644
--- a/tools/lib/traceevent/trace-seq.c
+++ b/tools/lib/traceevent/trace-seq.c
@@ -45,8 +45,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->state = TRACE_SEQ__GOOD;
+ s->buffer = malloc(s->buffer_size);
+ if (s->buffer != NULL)
+ s->state = TRACE_SEQ__GOOD;
+ else
+ s->state = TRACE_SEQ__MEM_ALLOC_FAILED;
}

/**

Namhyung Kim

unread,
Jan 3, 2014, 2:10:02 AM1/3/14
to
Ping!

Jiri Olsa

unread,
Jan 3, 2014, 8:30:03 AM1/3/14
to
So unless we use trace_seq_do_printf we dont have any
notification that this went wrong..?

How about use some sort of WARN_ONCE any time the state
is set != GOOD ?

thanks,
jirka

Namhyung Kim

unread,
Jan 6, 2014, 2:50:01 AM1/6/14
to
Hi Jiri,
Right.

>
> How about use some sort of WARN_ONCE any time the state
> is set != GOOD ?

I'm not sure what's the right thing to do for that case. Printing a
warning message might disturb user's output since it can be in a middle
of some (other) processing and she doesn't want to print anything during
the processing for some reason.

I just thought that it's not so important to print message so keeps the
error internally until it gets printed. But I can be wrong as usual...

Thanks,
Namhyung

Jiri Olsa

unread,
Jan 6, 2014, 9:40:01 AM1/6/14
to
On Mon, Jan 06, 2014 at 04:44:18PM +0900, Namhyung Kim wrote:

SNIP

> >> + (s)->state = TRACE_SEQ__BUFFER_POISONED; \
> >
> > So unless we use trace_seq_do_printf we dont have any
> > notification that this went wrong..?
>
> Right.
>
> >
> > How about use some sort of WARN_ONCE any time the state
> > is set != GOOD ?
>
> I'm not sure what's the right thing to do for that case. Printing a
> warning message might disturb user's output since it can be in a middle
> of some (other) processing and she doesn't want to print anything during
> the processing for some reason.
>
> I just thought that it's not so important to print message so keeps the
> error internally until it gets printed. But I can be wrong as usual...

I think that if she manages to get one of those errors
the perf would fail soon anyway.. so it feels better
to print it out immediately.

jirka

Steven Rostedt

unread,
Jan 6, 2014, 9:50:01 AM1/6/14
to
On Mon, 6 Jan 2014 15:38:28 +0100
Jiri Olsa <jo...@redhat.com> wrote:


> > I just thought that it's not so important to print message so keeps the
> > error internally until it gets printed. But I can be wrong as usual...
>
> I think that if she manages to get one of those errors
> the perf would fail soon anyway.. so it feels better
> to print it out immediately.

Yeah, using a trace_seq after it has been destroyed is a critical
failure, and a major bug. A print to the user console should not be a
problem here. And actually, crashing is not that bad either, as glibc
does the same with using free() of a freed pointer.

But as this error is major, an unwanted print is minor.

-- Steve

Namhyung Kim

unread,
Jan 6, 2014, 9:50:02 PM1/6/14
to
Hi Steve and Jiri,

2014-01-06 PM 11:45, Steven Rostedt wrote:
> On Mon, 6 Jan 2014 15:38:28 +0100
> Jiri Olsa <jo...@redhat.com> wrote:
>
>
>>> I just thought that it's not so important to print message so keeps the
>>> error internally until it gets printed. But I can be wrong as usual...
>>
>> I think that if she manages to get one of those errors
>> the perf would fail soon anyway.. so it feels better
>> to print it out immediately.
>
> Yeah, using a trace_seq after it has been destroyed is a critical
> failure, and a major bug. A print to the user console should not be a
> problem here. And actually, crashing is not that bad either, as glibc
> does the same with using free() of a freed pointer.
>
> But as this error is major, an unwanted print is minor.

OK, I'll add the WARN_ONCE in the TRACE_SEQ_CHECK then.

Thanks,
Namhyung
0 new messages