summaryrefslogtreecommitdiff
path: root/cesar
diff options
context:
space:
mode:
authorschodet2008-10-16 13:23:39 +0000
committerschodet2008-10-16 13:23:39 +0000
commit8b7ad762ff0cab7725d70468f4b5415f33237158 (patch)
treefc848c6ee6ea5fd3e995a70c5a811a58612b5a6b /cesar
parent5c7bd780f9d3dfac5bea5e38fe120804bffeff67 (diff)
* lib/trace:
- added trace bundles. git-svn-id: svn+ssh://pessac/svn/cesar/trunk@3292 017c9cb6-072f-447c-8318-d5b54f68fe89
Diffstat (limited to 'cesar')
-rw-r--r--cesar/lib/src/trace.c94
-rw-r--r--cesar/lib/test/trace/src/test_trace.c153
-rw-r--r--cesar/lib/trace.h41
3 files changed, 248 insertions, 40 deletions
diff --git a/cesar/lib/src/trace.c b/cesar/lib/src/trace.c
index 48cca1fa73..5be937102a 100644
--- a/cesar/lib/src/trace.c
+++ b/cesar/lib/src/trace.c
@@ -218,6 +218,7 @@ trace_buffer_add (trace_buffer_t *buf, const char *name, uint drop_level,
buf->drop_level = drop_level;
buf->preload = preload;
buf->locked = locked;
+ buf->name = name;
buf->namespace = namespace;
/* Allocate chunks. */
blk_t *tail;
@@ -341,6 +342,25 @@ trace_buffer_dump (trace_buffer_t *buf, trace_dump_callback_t cb, void *user)
trace_chunk_t *head, *tail;
u32 *data, *data_end;
int sum = 0;
+ dbg_assert (buf);
+ dbg_assert (buf->head);
+ dbg_assert (buf->tail);
+ dbg_assert (buf->name);
+ dbg_assert (cb);
+ /* Dump buffer name. */
+ static const char trace_start_before[] = "---trace-begin[";
+ static const char trace_start_after[] = "]---\n";
+ static const char trace_stop[] = "---trace-end---\n";
+ uint name_len = strlen (buf->name);
+ memcpy (text + text_size, trace_start_before,
+ sizeof (trace_start_before) - 1);
+ text_size += sizeof (trace_start_before) - 1;
+ memcpy (text + text_size, buf->name, name_len);
+ text_size += name_len;
+ memcpy (text + text_size, trace_start_after,
+ sizeof (trace_start_after) - 1);
+ text_size += sizeof (trace_start_after) - 1;
+ dbg_assert ((uint) text_size < sizeof (text) - DUMP_TEXT_SLACK);
/* TODO: acquire lock, increment reference counter. */
tail = buf->tail;
head = buf->head;
@@ -376,8 +396,11 @@ trace_buffer_dump (trace_buffer_t *buf, trace_dump_callback_t cb, void *user)
head = head->next;
} while (1);
/* Final text. */
- if (sum != -1 && text_size)
+ if (sum != -1)
{
+ dbg_assert (sizeof (trace_stop) - 1 < DUMP_TEXT_SLACK);
+ memcpy (text + text_size, trace_stop, sizeof (trace_stop) - 1);
+ text_size += sizeof (trace_stop) - 1;
if (cb (user, text, text_size) != text_size)
sum = -1;
else
@@ -386,8 +409,69 @@ trace_buffer_dump (trace_buffer_t *buf, trace_dump_callback_t cb, void *user)
return sum;
}
+int
+trace_bundle_start (const char *name, trace_dump_callback_t cb, void *user)
+{
+ int name_len = 0;
+ dbg_assert (cb);
+ static const char bundle_start_before[] = "---trace-bundle-begin[";
+ static const char bundle_start_after[] = "]---\n";
+ if (cb (user, bundle_start_before, sizeof (bundle_start_before) - 1)
+ != sizeof (bundle_start_before) - 1)
+ return -1;
+ if (name)
+ {
+ name_len = strlen (name);
+ if (cb (user, name, name_len) != name_len)
+ return -1;
+ }
+ if (cb (user, bundle_start_after, sizeof (bundle_start_after) - 1)
+ != sizeof (bundle_start_after) - 1)
+ return -1;
+ return sizeof (bundle_start_before) - 1 + sizeof (bundle_start_after) - 1
+ + name_len;
+}
+
+int
+trace_bundle_stop (trace_dump_callback_t cb, void *user)
+{
+ dbg_assert (cb);
+ static const char bundle_stop[] = "---trace-bundle-end---\n";
+ if (cb (user, bundle_stop, sizeof (bundle_stop) - 1)
+ != sizeof (bundle_stop) - 1)
+ return -1;
+ return sizeof (bundle_stop) - 1;
+}
+
+int
+trace_bundle_dump_all (const char *name, trace_dump_callback_t cb, void *user)
+{
+ trace_t * const ctx = &trace_global;
+ int sum = 0, r;
+ /* Header. */
+ r = trace_bundle_start (name, cb, user);
+ if (r == -1) return -1;
+ sum += r;
+ /* Dump all. */
+ list_node_t *i, *end;
+ i = list_begin (&ctx->buffers);
+ end = list_end (&ctx->buffers);
+ for (; i != end; i = list_next (i))
+ {
+ trace_buffer_t *buf = PARENT_OF (trace_buffer_t, node, i);
+ r = trace_buffer_dump (buf, cb, user);
+ if (r == -1) return -1;
+ sum += r;
+ }
+ /* Footer. */
+ r = trace_bundle_stop (cb, user);
+ if (r == -1) return -1;
+ sum += r;
+ return sum;
+}
+
static int
-trace_buffer_dbg_dump_callback (void *user, char *text, uint text_size)
+trace_buffer_dbg_dump_callback (void *user, const char *text, uint text_size)
{
dbg_assert (text && text_size);
arch_io_write (text, text_size);
@@ -400,6 +484,12 @@ trace_buffer_dbg_dump (trace_buffer_t *buf)
trace_buffer_dump (buf, trace_buffer_dbg_dump_callback, NULL);
}
+void
+trace_dbg_dump_all (void)
+{
+ trace_bundle_dump_all ("dbg", trace_buffer_dbg_dump_callback, NULL);
+}
+
static void
trace_printn_prepare (trace_buffer_t *buf, uint count)
{
diff --git a/cesar/lib/test/trace/src/test_trace.c b/cesar/lib/test/trace/src/test_trace.c
index c2d1f0e8ff..0351b6b02d 100644
--- a/cesar/lib/test/trace/src/test_trace.c
+++ b/cesar/lib/test/trace/src/test_trace.c
@@ -34,23 +34,48 @@ struct growing_buffer_t
};
typedef struct growing_buffer_t growing_buffer_t;
-int
-dump_callback (void *user, char *text, uint text_size)
+void
+growing_init (growing_buffer_t *g)
{
- dbg_assert (user);
- dbg_assert (text && text_size != 0);
- growing_buffer_t *g = user;
- /* Grow buffer if necessary. */
- if (g->buf_pos + text_size >= g->buf_size)
+ dbg_assert (g);
+ g->buf_pos = 0;
+ g->buf_size = 128;
+ g->buf = malloc (g->buf_size);
+ dbg_assert (g->buf);
+}
+
+void
+growing_uninit (growing_buffer_t *g)
+{
+ dbg_assert (g);
+ free (g->buf);
+}
+
+static void
+growing_grow (growing_buffer_t *g, uint size)
+{
+ dbg_assert (g);
+ if (g->buf_pos + size >= g->buf_size)
{
- g->buf_size = (g->buf_size + text_size) * 2;
+ g->buf_size = (g->buf_size + size) * 2;
g->buf = realloc (g->buf, g->buf_size);
dbg_assert (g->buf);
}
- /* Copy data. */
- memcpy (g->buf + g->buf_pos, text, text_size);
- g->buf_pos += text_size;
- return text_size;
+}
+
+void
+growing_memcpy (growing_buffer_t *g, const char *text, uint text_size)
+{
+ dbg_assert (g);
+ dbg_assert (text);
+ if (text_size)
+ {
+ /* Grow buffer if necessary. */
+ growing_grow (g, text_size);
+ /* Copy data. */
+ memcpy (g->buf + g->buf_pos, text, text_size);
+ g->buf_pos += text_size;
+ }
}
void
@@ -79,6 +104,17 @@ growing_sprintf (growing_buffer_t *g, const char *fmt, ...)
} while (1);
}
+int
+dump_callback (void *user, const char *text, uint text_size)
+{
+ dbg_assert (user);
+ dbg_assert (text && text_size != 0);
+ growing_buffer_t *g = user;
+ /* Copy data. */
+ growing_memcpy (g, text, text_size);
+ return text_size;
+}
+
void
trace_basic_test_case (test_t t)
{
@@ -220,32 +256,30 @@ trace_basic_test_case (test_t t)
trace_buffer_remove (&trace_buf[1]);
trace_buffer_remove (&trace_buf[2]);
} test_end;
+ enum
+ {
+ TEST_TRACE_TRACE_ONE,
+ TEST_TRACE_TRACE_TWO,
+ TEST_TRACE_TRACE_THREE,
+ TEST_TRACE_TRACE_FOUR,
+ };
+ static const trace_event_id_t ei[] = {
+ TRACE_EVENT (TEST_TRACE_TRACE_ONE, "one"),
+ TRACE_EVENT (TEST_TRACE_TRACE_TWO, "two %d", TIMESTAMP),
+ TRACE_EVENT (TEST_TRACE_TRACE_THREE, "three %u, %x, %d, %b, %b"),
+ TRACE_EVENT (TEST_TRACE_TRACE_FOUR, "four %m, %d"),
+ };
+ trace_namespace_t ns;
+ trace_namespace_init (&ns, ei, COUNT (ei));
test_begin (t, "dump")
{
#define TEST_TRACE_TRACE(id, args...) \
TRACE_SHORT (TEST_TRACE_TRACE_, &trace_buf[0], id, ## args)
- enum
- {
- TEST_TRACE_TRACE_ONE,
- TEST_TRACE_TRACE_TWO,
- TEST_TRACE_TRACE_THREE,
- TEST_TRACE_TRACE_FOUR,
- };
- static const trace_event_id_t ei[] = {
- TRACE_EVENT (TEST_TRACE_TRACE_ONE, "one"),
- TRACE_EVENT (TEST_TRACE_TRACE_TWO, "two %d", TIMESTAMP),
- TRACE_EVENT (TEST_TRACE_TRACE_THREE, "three %u, %x, %d, %b, %b"),
- TRACE_EVENT (TEST_TRACE_TRACE_FOUR, "four %m, %d"),
- };
- trace_namespace_t ns;
- trace_namespace_init (&ns, ei, COUNT (ei));
trace_buffer_add (&trace_buf[0], "trace", 2, 1, false, &ns);
/* Trace and record expected trace. */
growing_buffer_t expected_dump;
- expected_dump.buf_pos = 0;
- expected_dump.buf_size = 100;
- expected_dump.buf = malloc (expected_dump.buf_size);
- dbg_assert (expected_dump.buf);
+ growing_init (&expected_dump);
+ growing_sprintf (&expected_dump, "---trace-begin[%s]---\n", "trace");
for (i = 0; i < NB_PRINT; i++)
{
trace_print0 (&trace_buf[0], TEST_TRACE_TRACE_ONE);
@@ -262,13 +296,11 @@ trace_basic_test_case (test_t t)
growing_sprintf (&expected_dump,
"[.] four 12:34:56:78:9a:bc, %d\n", i);
}
+ growing_sprintf (&expected_dump, "---trace-end---\n");
test_verbose_print ("%s", expected_dump.buf);
/* Dump to memory. */
growing_buffer_t dump;
- dump.buf_pos = 0;
- dump.buf_size = 100;
- dump.buf = malloc (dump.buf_size);
- dbg_assert (dump.buf);
+ growing_init (&dump);
int ret = trace_buffer_dump (&trace_buf[0], dump_callback, &dump);
/* Check dump. */
test_fail_unless (expected_dump.buf_pos == dump.buf_pos);
@@ -276,9 +308,56 @@ trace_basic_test_case (test_t t)
test_fail_unless (memcmp (expected_dump.buf, dump.buf, dump.buf_pos)
== 0);
/* Cleanup. */
- free (expected_dump.buf);
- free (dump.buf);
+ growing_uninit (&expected_dump);
+ growing_uninit (&dump);
+ trace_buffer_remove (&trace_buf[0]);
+#undef TEST_TRACE_TRACE
+ } test_end;
+ test_begin (t, "dump all")
+ {
+#define TEST_TRACE_TRACE(buf, id, args...) \
+ TRACE_SHORT (TEST_TRACE_TRACE_, &trace_buf[buf], id, ## args)
+ trace_buffer_add (&trace_buf[0], "trace0", 2, 1, false, &ns);
+ trace_buffer_add (&trace_buf[1], "trace1", 2, 1, false, &ns);
+ /* Trace and record expected trace. */
+ growing_buffer_t expected_dump;
+ growing_init (&expected_dump);
+ growing_buffer_t expected_dump1;
+ growing_init (&expected_dump1);
+ growing_sprintf (&expected_dump, "---trace-bundle-begin[%s]---\n", "thebundle");
+ growing_sprintf (&expected_dump, "---trace-begin[%s]---\n", "trace0");
+ for (i = 0; i < NB_PRINT / 10; i++)
+ {
+ TEST_TRACE_TRACE (0, ONE);
+ growing_sprintf (&expected_dump, "[.] one\n");
+ TEST_TRACE_TRACE (0, TWO, i, i + 1);
+ growing_sprintf (&expected_dump, "[0x%08x] two %d\n", i, i + 1);
+ TEST_TRACE_TRACE (1, TWO, i, i * 2);
+ growing_sprintf (&expected_dump1, "[0x%08x] two %d\n", i, i * 2);
+ }
+ growing_sprintf (&expected_dump, "---trace-end---\n");
+ growing_sprintf (&expected_dump, "---trace-begin[%s]---\n", "trace1");
+ growing_memcpy (&expected_dump, expected_dump1.buf,
+ expected_dump1.buf_pos);
+ growing_sprintf (&expected_dump, "---trace-end---\n");
+ growing_sprintf (&expected_dump, "---trace-bundle-end---\n");
+ test_verbose_print ("%s", expected_dump.buf);
+ /* Dump to memory. */
+ growing_buffer_t dump;
+ growing_init (&dump);
+ int ret = trace_bundle_dump_all ("thebundle", dump_callback, &dump);
+ /* Check dump. */
+ test_fail_unless (expected_dump.buf_pos == dump.buf_pos);
+ test_fail_unless ((int) dump.buf_pos == ret);
+ test_fail_unless (memcmp (expected_dump.buf, dump.buf, dump.buf_pos)
+ == 0);
+ /* Cleanup. */
+ growing_uninit (&expected_dump);
+ growing_uninit (&expected_dump1);
+ growing_uninit (&dump);
trace_buffer_remove (&trace_buf[0]);
+ trace_buffer_remove (&trace_buf[1]);
+#undef TEST_TRACE_TRACE
} test_end;
/* Uninit. */
trace_uninit ();
diff --git a/cesar/lib/trace.h b/cesar/lib/trace.h
index 10da874ddf..fd8debaca8 100644
--- a/cesar/lib/trace.h
+++ b/cesar/lib/trace.h
@@ -175,7 +175,8 @@ struct trace_namespace_t
* \param text_size size of text to write, i.e. number of characters
* \return should return size, any other value will stop dump
*/
-typedef int (*trace_dump_callback_t) (void *user, char *text, uint text_size);
+typedef int (*trace_dump_callback_t) (void *user, const char *text,
+ uint text_size);
BEGIN_DECLS
@@ -283,6 +284,38 @@ int
trace_buffer_dump (trace_buffer_t *buf, trace_dump_callback_t cb, void *user);
/**
+ * Start a text trace bundle.
+ * \param name bundle name, may be NULL for no name
+ * \param cb callback called several times with text data
+ * \param user user data passed to the callback
+ * \return number of character written or -1 on any error (if one callback
+ * did not return its size parameter)
+ */
+int
+trace_bundle_start (const char *name, trace_dump_callback_t cb, void *user);
+
+/**
+ * Stop a text trace bundle.
+ * \param cb callback called several times with text data
+ * \param user user data passed to the callback
+ * \return number of character written or -1 on any error (if one callback
+ * did not return its size parameter)
+ */
+int
+trace_bundle_stop (trace_dump_callback_t cb, void *user);
+
+/**
+ * Dump all trace buffers as a text trace bundle.
+ * \param name bundle name, may be NULL for no name
+ * \param cb callback called several times with text data
+ * \param user user data passed to the callback
+ * \return number of character written or -1 on any error (if one callback
+ * did not return its size parameter)
+ */
+int
+trace_bundle_dump_all (const char *name, trace_dump_callback_t cb, void *user);
+
+/**
* Dump a full trace buffer as text during debug.
* \param buf trace buffer
*
@@ -292,6 +325,12 @@ void
trace_buffer_dbg_dump (trace_buffer_t *buf);
/**
+ * Dump all trace buffer as a text bundle during debug.
+ */
+void
+trace_dbg_dump_all (void);
+
+/**
* Write event to trace buffer.
* \param buf the trace buffer to write to
* \param id event identifier