[PATCH 3/3] record: Add rtems_record_dump()

Sebastian Huber sebastian.huber at embedded-brains.de
Fri Mar 13 12:02:04 UTC 2020


Add rtems_record_dump_base64() and rtems_record_dump_zlib_base64().

Add CONFIGURE_RECORD_FATAL_DUMP_BASE64 and
CONFIGURE_RECORD_FATAL_DUMP_ZLIB_BASE64 configuration options.

Update #3904.
---
 cpukit/Makefile.am                           |   5 +
 cpukit/headers.am                            |   1 +
 cpukit/include/rtems/confdefs/extensions.h   |  18 ++-
 cpukit/include/rtems/record.h                |  32 +++---
 cpukit/include/rtems/recorddump.h            | 118 ++++++++++++++++++++
 cpukit/libtrace/record/record-dump-base64.c  | 110 ++++++++++++++++++
 cpukit/libtrace/record/record-dump-fatal.c   |  50 +++++++++
 cpukit/libtrace/record/record-dump-zbase64.c | 160 +++++++++++++++++++++++++++
 cpukit/libtrace/record/record-dump-zfatal.c  |  52 +++++++++
 cpukit/libtrace/record/record-dump.c         | 108 ++++++++++++++++++
 testsuites/libtests/Makefile.am              |   1 +
 testsuites/libtests/record02/init.c          |  38 +++++--
 12 files changed, 664 insertions(+), 29 deletions(-)
 create mode 100644 cpukit/include/rtems/recorddump.h
 create mode 100644 cpukit/libtrace/record/record-dump-base64.c
 create mode 100644 cpukit/libtrace/record/record-dump-fatal.c
 create mode 100644 cpukit/libtrace/record/record-dump-zbase64.c
 create mode 100644 cpukit/libtrace/record/record-dump-zfatal.c
 create mode 100644 cpukit/libtrace/record/record-dump.c

diff --git a/cpukit/Makefile.am b/cpukit/Makefile.am
index 633f063b7d..3af69bd615 100644
--- a/cpukit/Makefile.am
+++ b/cpukit/Makefile.am
@@ -471,6 +471,11 @@ librtemscpu_a_SOURCES += libstdthreads/thrd.c
 librtemscpu_a_SOURCES += libstdthreads/tss.c
 librtemscpu_a_SOURCES += libtrace/record/record.c
 librtemscpu_a_SOURCES += libtrace/record/record-client.c
+librtemscpu_a_SOURCES += libtrace/record/record-dump.c
+librtemscpu_a_SOURCES += libtrace/record/record-dump-fatal.c
+librtemscpu_a_SOURCES += libtrace/record/record-dump-zfatal.c
+librtemscpu_a_SOURCES += libtrace/record/record-dump-base64.c
+librtemscpu_a_SOURCES += libtrace/record/record-dump-zbase64.c
 librtemscpu_a_SOURCES += libtrace/record/record-server.c
 librtemscpu_a_SOURCES += libtrace/record/record-sysinit.c
 librtemscpu_a_SOURCES += libtrace/record/record-text.c
diff --git a/cpukit/headers.am b/cpukit/headers.am
index 4a93e7b224..fcf679f09d 100644
--- a/cpukit/headers.am
+++ b/cpukit/headers.am
@@ -139,6 +139,7 @@ include_rtems_HEADERS += include/rtems/rbtree.h
 include_rtems_HEADERS += include/rtems/record.h
 include_rtems_HEADERS += include/rtems/recordclient.h
 include_rtems_HEADERS += include/rtems/recorddata.h
+include_rtems_HEADERS += include/rtems/recorddump.h
 include_rtems_HEADERS += include/rtems/recordserver.h
 include_rtems_HEADERS += include/rtems/ringbuf.h
 include_rtems_HEADERS += include/rtems/rtc.h
diff --git a/cpukit/include/rtems/confdefs/extensions.h b/cpukit/include/rtems/confdefs/extensions.h
index cf53e0d573..3aa43973ea 100644
--- a/cpukit/include/rtems/confdefs/extensions.h
+++ b/cpukit/include/rtems/confdefs/extensions.h
@@ -79,7 +79,23 @@ extern "C" {
   const User_extensions_Table _User_extensions_Initial_extensions[] = {
     #if CONFIGURE_RECORD_PER_PROCESSOR_ITEMS > 0 \
       && defined(CONFIGURE_RECORD_EXTENSIONS_ENABLED)
-      RECORD_EXTENSION,
+      {
+        _Record_Thread_create,
+        _Record_Thread_start,
+        _Record_Thread_restart,
+        _Record_Thread_delete,
+        _Record_Thread_switch,
+        _Record_Thread_begin,
+        _Record_Thread_exitted,
+        #ifdef CONFIGURE_RECORD_FATAL_DUMP_ZLIB_BASE64
+          _Record_Fatal_dump_zlib_base64,
+        #elif defined(CONFIGURE_RECORD_FATAL_DUMP_BASE64)
+          _Record_Fatal_dump_base64,
+        #else
+          NULL,
+        #endif
+        _Record_Thread_terminate
+      },
     #endif
     #ifdef _CONFIGURE_ENABLE_NEWLIB_REENTRANCY
       RTEMS_NEWLIB_EXTENSION,
diff --git a/cpukit/include/rtems/record.h b/cpukit/include/rtems/record.h
index 4e1c469173..7c57476c64 100644
--- a/cpukit/include/rtems/record.h
+++ b/cpukit/include/rtems/record.h
@@ -1,7 +1,7 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
 /*
- * SPDX-License-Identifier: BSD-2-Clause
- *
- * Copyright (C) 2018, 2019 embedded brains GmbH
+ * Copyright (C) 2018, 2020 embedded brains GmbH (http://www.embedded-brains.de)
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -32,6 +32,7 @@
 
 #include <rtems/score/atomic.h>
 #include <rtems/score/cpu.h>
+#include <rtems/score/interr.h>
 #include <rtems/score/percpu.h>
 #include <rtems/score/watchdog.h>
 #include <rtems/counter.h>
@@ -95,23 +96,22 @@ void _Record_Thread_begin( struct _Thread_Control *executing );
 
 void _Record_Thread_exitted( struct _Thread_Control *executing );
 
+void _Record_Fatal_dump_base64(
+  Internal_errors_Source source,
+  bool                   always_set_to_false,
+  Internal_errors_t      code
+);
+
+void _Record_Fatal_dump_zlib_base64(
+  Internal_errors_Source source,
+  bool                   always_set_to_false,
+  Internal_errors_t      code
+);
+
 void _Record_Thread_terminate(
   struct _Thread_Control *executing
 );
 
-#define RECORD_EXTENSION \
-  { \
-    _Record_Thread_create, \
-    _Record_Thread_start, \
-    _Record_Thread_restart, \
-    _Record_Thread_delete, \
-    _Record_Thread_switch, \
-    _Record_Thread_begin, \
-    _Record_Thread_exitted, \
-    NULL, \
-    _Record_Thread_terminate \
-  }
-
 RTEMS_INLINE_ROUTINE unsigned int _Record_Index(
   const Record_Control *control,
   unsigned int          index
diff --git a/cpukit/include/rtems/recorddump.h b/cpukit/include/rtems/recorddump.h
new file mode 100644
index 0000000000..ad7039312b
--- /dev/null
+++ b/cpukit/include/rtems/recorddump.h
@@ -0,0 +1,118 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTEMS_RECORDDUMP_H
+#define _RTEMS_RECORDDUMP_H
+
+#include <rtems/record.h>
+
+#include <zlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @addtogroup RTEMSRecord
+ *
+ * @{
+ */
+
+/**
+ * @brief Handler for record dumps to output a chunk of data.
+ *
+ * @param arg The argument passed to rtems_record_dump().
+ * @param data The begin of the data chunk.
+ * @param length The length in bytes of the data chunk.
+ */
+typedef void ( *rtems_record_dump_chunk )(
+  void       *arg,
+  const void *data,
+  size_t      length
+);
+
+/**
+ * @brief Dumps the record header, the thread names, and all items of all
+ * processors.
+ *
+ * @param chunk Handler to dump a chunk of data.
+ * @param flush Handler to flush the data.
+ * @param arg The argument for the handlers.
+ */
+void rtems_record_dump(
+  rtems_record_dump_chunk  chunk,
+  void                    *arg
+);
+
+/**
+ * @brief Dumps the event records in base64 encoding.
+ *
+ * @param put_char The put char handler.
+ * @param arg The argument for the put char handler.
+ *
+ * @see rtems_record_dump().
+ */
+void rtems_record_dump_base64( void ( *put_char )( int, void * ), void *arg );
+
+/**
+ * @brief The context for record dumps with zlib compression and base64
+ * encoding.
+ */
+typedef struct {
+  void        ( *put_char )( int, void * );
+  void          *arg;
+  int            out;
+  unsigned char  buf[ 57 ];
+  z_stream       stream;
+  char          *mem_begin;
+  size_t         mem_available;
+  char           mem[ 0x80000 ];
+} rtems_record_dump_zlib_base64_context;
+
+/**
+ * @brief Dumps the event records compressed with zlib in base64 encoding.
+ *
+ * @param ctx The context to perform the record dump with zlib compression and
+ *   base64 encoding.  This context is too large for normal stack sizes.
+ * @param put_char The put char handler.
+ * @param arg The argument for the put char handler.
+ *
+ * @see rtems_record_dump().
+ */
+void rtems_record_dump_zlib_base64(
+  rtems_record_dump_zlib_base64_context *ctx,
+  void                                ( *put_char )( int, void * ),
+  void                                  *arg
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_RECORDDUMP_H */
diff --git a/cpukit/libtrace/record/record-dump-base64.c b/cpukit/libtrace/record/record-dump-base64.c
new file mode 100644
index 0000000000..618a00414e
--- /dev/null
+++ b/cpukit/libtrace/record/record-dump-base64.c
@@ -0,0 +1,110 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/recorddump.h>
+#include <rtems/score/io.h>
+
+#include <limits.h>
+#include <string.h>
+
+typedef struct {
+  IO_Put_char  put_char;
+  void        *arg;
+  int          out;
+  size_t       index;
+  char         buf[ 57 ];
+} dump_context;
+
+static void put_char( int c, void *arg )
+{
+  dump_context *ctx;
+
+  ctx = arg;
+
+  ( *ctx->put_char )( c, ctx->arg );
+  ++ctx->out;
+
+  if ( ctx->out >= 76 ) {
+    ctx->out = 0;
+    ( *ctx->put_char )( '\n', ctx->arg );
+  }
+}
+
+static void chunk( void *arg, const void *data, size_t length )
+{
+  dump_context *ctx;
+  size_t        index;
+  const char   *in;
+  const void   *end;
+
+  ctx = arg;
+  index = ctx->index;
+  in = data;
+  end = in + length;
+
+  while ( in != end ) {
+    ctx->buf[ index ] = *in;
+    ++in;
+
+    if ( index == RTEMS_ARRAY_SIZE( ctx->buf ) - 1 ) {
+      index = 0;
+      _IO_Base64(
+        put_char,
+        ctx,
+        ctx->buf,
+        sizeof( ctx->buf ),
+        NULL,
+        INT_MAX
+      );
+    } else {
+      ++index;
+    }
+  }
+
+  ctx->index = index;
+}
+
+static void flush( dump_context *ctx )
+{
+  _IO_Base64( put_char, ctx, ctx->buf, ctx->index, NULL, INT_MAX );
+}
+
+void rtems_record_dump_base64( IO_Put_char put_char, void *arg )
+{
+  dump_context ctx;
+
+  memset( &ctx, 0, sizeof( ctx ) );
+  ctx.put_char = put_char;
+  ctx.arg = arg;
+
+  rtems_record_dump( chunk, &ctx );
+  flush( &ctx );
+}
diff --git a/cpukit/libtrace/record/record-dump-fatal.c b/cpukit/libtrace/record/record-dump-fatal.c
new file mode 100644
index 0000000000..faadfeb201
--- /dev/null
+++ b/cpukit/libtrace/record/record-dump-fatal.c
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/recorddump.h>
+#include <rtems/bspIo.h>
+
+void _Record_Fatal_dump_base64(
+  Internal_errors_Source source,
+  bool                   always_set_to_false,
+  Internal_errors_t      code
+)
+{
+  rtems_record_produce_2(
+    RTEMS_RECORD_FATAL_SOURCE,
+    source,
+    RTEMS_RECORD_FATAL_CODE,
+    code
+  );
+  printk( "\n*** BEGIN OF BASE64 RECORDS ***\n" );
+  rtems_record_dump_base64( rtems_put_char, NULL );
+  printk( "\n*** END OF BASE64 RECORDS ***\n" );
+}
diff --git a/cpukit/libtrace/record/record-dump-zbase64.c b/cpukit/libtrace/record/record-dump-zbase64.c
new file mode 100644
index 0000000000..937a2528c5
--- /dev/null
+++ b/cpukit/libtrace/record/record-dump-zbase64.c
@@ -0,0 +1,160 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/recorddump.h>
+#include <rtems/score/io.h>
+
+#include <limits.h>
+#include <string.h>
+
+static void *dump_zalloc( void *opaque, unsigned items, unsigned size )
+{
+  rtems_record_dump_zlib_base64_context *ctx;
+  char                                  *mem_begin;
+  size_t                                 mem_available;
+
+  ctx = opaque;
+  size *= items;
+  mem_available = ctx->mem_available;
+
+  if ( mem_available < size ) {
+    return NULL;
+  }
+
+  mem_begin = ctx->mem_begin;
+  ctx->mem_begin = mem_begin + size;
+  ctx->mem_available = mem_available - size;
+  return mem_begin;
+}
+
+static void dump_zfree( void *opaque, void *ptr )
+{
+  (void) opaque;
+  (void) ptr;
+}
+
+static void put_char( int c, void *arg )
+{
+  rtems_record_dump_zlib_base64_context *ctx;
+
+  ctx = arg;
+
+  ( *ctx->put_char )( c, ctx->arg );
+  ++ctx->out;
+
+  if ( ctx->out >= 76 ) {
+    ctx->out = 0;
+    ( *ctx->put_char )( '\n', ctx->arg );
+  }
+}
+
+static void chunk( void *arg, const void *data, size_t length )
+{
+  rtems_record_dump_zlib_base64_context *ctx;
+
+  ctx = arg;
+  ctx->stream.next_in = RTEMS_DECONST( void *, data );
+  ctx->stream.avail_in = length;
+
+  while ( ctx->stream.avail_in > 0 ) {
+    int err;
+
+    err = deflate( &ctx->stream, Z_NO_FLUSH );
+    if ( err != Z_OK ) {
+      return;
+    }
+
+    if ( ctx->stream.avail_out == 0 ) {
+      ctx->stream.next_out = &ctx->buf[ 0 ];
+      ctx->stream.avail_out = sizeof( ctx->buf );
+
+      _IO_Base64( put_char, ctx, ctx->buf, sizeof( ctx->buf ), NULL, INT_MAX );
+    }
+  }
+}
+
+static void flush( rtems_record_dump_zlib_base64_context *ctx )
+{
+  while ( true ) {
+    int err;
+
+    err = deflate( &ctx->stream, Z_FINISH );
+    if ( err != Z_OK ) {
+      break;
+    }
+
+    if ( ctx->stream.avail_out == 0 ) {
+      ctx->stream.next_out = &ctx->buf[ 0 ];
+      ctx->stream.avail_out = sizeof( ctx->buf );
+
+      _IO_Base64( put_char, ctx, ctx->buf, sizeof( ctx->buf ), NULL, INT_MAX );
+    }
+  }
+
+  _IO_Base64(
+    put_char,
+    ctx,
+    ctx->buf,
+    sizeof( ctx->buf ) - ctx->stream.avail_out,
+    NULL,
+    INT_MAX
+  );
+}
+
+void rtems_record_dump_zlib_base64(
+  rtems_record_dump_zlib_base64_context *ctx,
+  void                                ( *put_char )( int, void * ),
+  void                                  *arg
+)
+{
+  int err;
+
+  ctx->put_char = put_char;
+  ctx->arg = arg;
+  ctx->out = 0;
+  ctx->stream.zalloc = dump_zalloc;
+  ctx->stream.zfree = dump_zfree;
+  ctx->stream.opaque = ctx;
+  ctx->mem_begin = &ctx->mem[ 0 ];
+  ctx->mem_available = sizeof( ctx->mem );
+
+  err = deflateInit( &ctx->stream, Z_BEST_COMPRESSION );
+  if (err != Z_OK) {
+    return;
+  }
+
+  ctx->stream.next_out = &ctx->buf[ 0 ];
+  ctx->stream.avail_out = sizeof( ctx->buf );
+
+  rtems_record_dump( chunk, ctx );
+  flush( ctx );
+  deflateEnd( &ctx->stream );
+}
diff --git a/cpukit/libtrace/record/record-dump-zfatal.c b/cpukit/libtrace/record/record-dump-zfatal.c
new file mode 100644
index 0000000000..7decf26b9e
--- /dev/null
+++ b/cpukit/libtrace/record/record-dump-zfatal.c
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/recorddump.h>
+#include <rtems/bspIo.h>
+
+static rtems_record_dump_zlib_base64_context context;
+
+void _Record_Fatal_dump_zlib_base64(
+  Internal_errors_Source source,
+  bool                   always_set_to_false,
+  Internal_errors_t      code
+)
+{
+  rtems_record_produce_2(
+    RTEMS_RECORD_FATAL_SOURCE,
+    source,
+    RTEMS_RECORD_FATAL_CODE,
+    code
+  );
+  printk( "\n*** BEGIN OF ZLIB BASE64 RECORDS ***\n" );
+  rtems_record_dump_zlib_base64( &context, rtems_put_char, NULL );
+  printk( "\n*** END OF ZLIB BASE64 RECORDS ***\n" );
+}
diff --git a/cpukit/libtrace/record/record-dump.c b/cpukit/libtrace/record/record-dump.c
new file mode 100644
index 0000000000..b3c757226a
--- /dev/null
+++ b/cpukit/libtrace/record/record-dump.c
@@ -0,0 +1,108 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/recorddump.h>
+#include <rtems/score/threadimpl.h>
+
+typedef struct {
+  rtems_record_dump_chunk  chunk;
+  void                    *arg;
+} dump_context;
+
+static void dump_chunk( dump_context *ctx, const void *data, size_t length )
+{
+  ( *ctx->chunk )( ctx->arg, data, length );
+}
+
+static bool thread_names_visitor( rtems_tcb *tcb, void *arg )
+{
+  dump_context      *ctx;
+  char               name[ 2 * THREAD_DEFAULT_MAXIMUM_NAME_SIZE ];
+  size_t             n;
+  size_t             i;
+  rtems_record_item  item;
+  rtems_record_data  data;
+
+  ctx = arg;
+  item.event = RTEMS_RECORD_THREAD_ID;
+  item.data = tcb->Object.id;
+  dump_chunk( ctx, &item, sizeof( item ) );
+
+  n = _Thread_Get_name( tcb, name, sizeof( name ) );
+  i = 0;
+
+  while ( i < n ) {
+    size_t j;
+
+    data = 0;
+
+    for ( j = 0; i < n && j < sizeof( data ); ++j ) {
+      rtems_record_data c;
+
+      c = (unsigned char) name[ i ];
+      data |= c << ( j * 8 );
+      ++i;
+    }
+
+    item.event = RTEMS_RECORD_THREAD_NAME;
+    item.data = data;
+    dump_chunk( ctx, &item, sizeof( item ) );
+  }
+
+  return false;
+}
+
+static void drain_visitor(
+  const rtems_record_item *items,
+  size_t                   count,
+  void                    *arg
+)
+{
+  dump_chunk( arg, items, count * sizeof( *items ) );
+}
+
+void rtems_record_dump(
+  rtems_record_dump_chunk  chunk,
+  void                    *arg
+)
+{
+  Record_Stream_header header;
+  size_t               size;
+  dump_context         ctx;
+
+  ctx.chunk = chunk;
+  ctx.arg = arg;
+
+  size = _Record_Stream_header_initialize( &header );
+  dump_chunk( &ctx, &header, size );
+  rtems_task_iterate( thread_names_visitor, &ctx );
+  rtems_record_drain( drain_visitor, &ctx );
+}
diff --git a/testsuites/libtests/Makefile.am b/testsuites/libtests/Makefile.am
index 7917c98656..e493e3d8a8 100644
--- a/testsuites/libtests/Makefile.am
+++ b/testsuites/libtests/Makefile.am
@@ -1124,6 +1124,7 @@ lib_docs += record02/record02.doc
 record02_SOURCES = record02/init.c
 record02_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_FLAGS_record02) \
 	$(support_includes)
+record02_LDADD = $(RTEMS_ROOT)cpukit/librtemscpu.a $(RTEMS_ROOT)cpukit/libz.a $(LDADD)
 endif
 
 if TEST_rtmonuse
diff --git a/testsuites/libtests/record02/init.c b/testsuites/libtests/record02/init.c
index 22671a7c0a..7f9608ea74 100644
--- a/testsuites/libtests/record02/init.c
+++ b/testsuites/libtests/record02/init.c
@@ -1,7 +1,7 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
 /*
- * SPDX-License-Identifier: BSD-2-Clause
- *
- * Copyright (C) 2018, 2019 embedded brains GmbH
+ * Copyright (C) 2018, 2020 embedded brains GmbH (http://www.embedded-brains.de)
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -94,18 +94,11 @@ static void drain_visitor(
   rtems_test_assert(cs == RTEMS_RECORD_CLIENT_SUCCESS);
 }
 
-static void Init(rtems_task_argument arg)
+static void generate_events(void)
 {
-  test_context *ctx;
-  Record_Stream_header header;
-  size_t size;
-  rtems_record_client_status cs;
   int i;
   uint32_t level;
 
-  TEST_BEGIN();
-  ctx = &test_instance;
-
   for (i = 0; i < 10; ++i) {
     rtems_task_wake_after(1);
   }
@@ -160,6 +153,19 @@ static void Init(rtems_task_argument arg)
   rtems_record_exit_10(RTEMS_RECORD_USER_4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
   level = rtems_record_interrupt_disable();
   rtems_record_interrupt_enable(level);
+}
+
+static void Init(rtems_task_argument arg)
+{
+  test_context *ctx;
+  Record_Stream_header header;
+  size_t size;
+  rtems_record_client_status cs;
+
+  TEST_BEGIN();
+  ctx = &test_instance;
+
+  generate_events();
 
   rtems_record_client_init(&ctx->client, client_handler, NULL);
   size = _Record_Stream_header_initialize(&header);
@@ -168,6 +174,12 @@ static void Init(rtems_task_argument arg)
   rtems_record_drain(drain_visitor, ctx);
   rtems_record_client_destroy(&ctx->client);
 
+  generate_events();
+
+  _Record_Fatal_dump_base64(RTEMS_FATAL_SOURCE_APPLICATION, false, 123);
+
+  generate_events();
+
   TEST_END();
   rtems_test_exit(0);
 }
@@ -182,10 +194,12 @@ static void Init(rtems_task_argument arg)
 
 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
 
-#define CONFIGURE_RECORD_PER_PROCESSOR_ITEMS 256
+#define CONFIGURE_RECORD_PER_PROCESSOR_ITEMS 512
 
 #define CONFIGURE_RECORD_EXTENSIONS_ENABLED
 
+#define CONFIGURE_RECORD_FATAL_DUMP_ZLIB_BASE64
+
 #define CONFIGURE_INIT
 
 #include <rtems/confdefs.h>
-- 
2.16.4



More information about the devel mailing list