Hi,
I've created a patch that provides a workaround for the segmentation
fault:
--- a/src/rtdk/rt_print.c 2009-05-21 16:34:54.000000000 +0200
+++ b/src/rtdk/rt_print.c 2009-09-04 10:09:19.000000000 +0200
@@ -40,6 +40,7 @@
struct entry_head {
FILE *dest;
uint32_t seq_no;
+ uint32_t len;
char text[1];
} __attribute__((packed));
@@ -113,6 +114,7 @@
/* Write out empty entry */
head = buffer->ring + write_pos;
head->seq_no = __seq_no;
+ head->len = 0;
head->text[0] = 0;
/* Forward to the ring buffer start */
@@ -146,6 +148,7 @@
/* If we were able to write some text, finalise the entry */
if (len > 0) {
head->seq_no = ++__seq_no;
+ head->len = len;
head->dest = stream;
/* Move forward by text and head length */
@@ -158,6 +161,7 @@
/* An empty entry marks the wrap-around */
head = buffer->ring + write_pos;
head->seq_no = __seq_no;
+ head->len = 0;
head->text[0] = 0;
write_pos = 0;
@@ -373,7 +377,7 @@
read_pos = buffer->read_pos;
head = buffer->ring + read_pos;
- len = strlen(head->text);
+ len = head->len;
if (len) {
/* Print out non-empty entry and proceed */
With this patch I get no segfaults anymore, but of course it would be
interesting why parts of the ring buffer are overwritten with null
characters.
Christoph
Am Freitag, den 28.08.2009, 11:07 +0200 schrieb Jan Kiszka:
> Christoph Permes wrote:
> > Am Freitag, den 28.08.2009, 09:38 +0200 schrieb Jan Kiszka:
> >> Hmm, strange. Code meditation didn't help, so I need to keep you busy
> >> with testing. Could you try this instrumentation? It should choke if the
> >> rt_vfprintf actually overwrites already written data.
> >>
> >> Thanks,
> >> Jan
> >>
> >> diff --git a/src/rtdk/rt_print.c b/src/rtdk/rt_print.c
> >> index 0615247..bcd8c88 100644
> >> --- a/src/rtdk/rt_print.c
> >> +++ b/src/rtdk/rt_print.c
> >> @@ -16,6 +16,7 @@
> >> * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
> >> USA.
> >> */
> >>
> >> +#include <assert.h>
> >> #include <errno.h>
> >> #include <inttypes.h>
> >> #include <limits.h>
> >> @@ -37,7 +38,10 @@
> >>
> >> #define RT_PRINT_LINE_BREAK 256
> >>
> >> +#define RT_PRINT_HEAD_MAGIC 0xDEADBEAF
> >> +
> >> struct entry_head {
> >> + uint32_t magic;
> >> FILE *dest;
> >> uint32_t seq_no;
> >> char text[1];
> >> @@ -103,6 +107,10 @@ int rt_vfprintf(FILE *stream, const char *format,
> >> va_list args)
> >> read_pos = buffer->read_pos;
> >> xnarch_read_memory_barrier();
> >>
> >> + assert(write_pos == read_pos ||
> >> + ((struct entry_head *)buffer->read_pos)->magic ==
> >> + RT_PRINT_HEAD_MAGIC);
> >> +
> >> /* Is our write limit the end of the ring buffer? */
> >> if (write_pos >= read_pos) {
> >> /* Keep a savety margin to the end for at least an empty entry
> >> */
> >> @@ -114,6 +122,7 @@ int rt_vfprintf(FILE *stream, const char *format,
> >> va_list args)
> >> if (len == 0 && read_pos > sizeof(struct entry_head)) {
> >> /* Write out empty entry */
> >> head = buffer->ring + write_pos;
> >> + head->magic = RT_PRINT_HEAD_MAGIC;
> >> head->seq_no = seq_no;
> >> head->text[0] = 0;
> >>
> >> @@ -136,6 +145,10 @@ int rt_vfprintf(FILE *stream, const char *format,
> >> va_list args)
> >>
> >> res = vsnprintf(head->text, len, format, args);
> >>
> >> + assert(write_pos == read_pos ||
> >> + ((struct entry_head *)buffer->read_pos)->magic ==
> >> + RT_PRINT_HEAD_MAGIC);
> >> +
> >> if (res < len) {
> >> /* Text was written completely, res contains its length */
> >> len = res;
> >> @@ -147,6 +160,7 @@ int rt_vfprintf(FILE *stream, const char *format,
> >> va_list args)
> >>
> >> /* If we were able to write some text, finalise the entry */
> >> if (len > 0) {
> >> + head->magic = RT_PRINT_HEAD_MAGIC;
> >> head->seq_no = ++seq_no;
> >> head->dest = stream;
> >>
> >> @@ -159,6 +173,7 @@ int rt_vfprintf(FILE *stream, const char *format,
> >> va_list args)
> >> read_pos <= write_pos && read_pos > buffer->size - write_pos) {
> >> /* An empty entry marks the wrap-around */
> >> head = buffer->ring + write_pos;
> >> + head->magic = RT_PRINT_HEAD_MAGIC;
> >> head->seq_no = seq_no;
> >> head->text[0] = 0;
> >>
> >> @@ -382,6 +397,8 @@ static void print_buffers(void)
> >> head = buffer->ring + read_pos;
> >> len = strlen(head->text);
> >>
> >> + assert(head->magic == RT_PRINT_HEAD_MAGIC);
> >> +
> >> if (len) {
> >> /* Print out non-empty entry and proceed */
> >> fprintf(head->dest, "%s", head->text);
> >>
> >
> > Now I get a SEGV at the first line of the first assert statement
> > (assert(write_pos == read_pos || ) in rt_vfprintf.
> > This happens at the first rt_printf call, also with the rtprint example
> > program.
>
> Untested stuff as I should already be on the road. Here is another try,
> but please don't expect replies from me over this weekend.
>
> Jan
>
> diff --git a/src/rtdk/rt_print.c b/src/rtdk/rt_print.c
> index 0615247..06dabc1 100644
> --- a/src/rtdk/rt_print.c
> +++ b/src/rtdk/rt_print.c
> @@ -16,6 +16,7 @@
> * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
> */
>
> +#include <assert.h>
> #include <errno.h>
> #include <inttypes.h>
> #include <limits.h>
> @@ -37,7 +38,10 @@
>
> #define RT_PRINT_LINE_BREAK 256
>
> +#define RT_PRINT_HEAD_MAGIC 0xDEADBEAF
> +
> struct entry_head {
> + uint32_t magic;
> FILE *dest;
> uint32_t seq_no;
> char text[1];
> @@ -103,6 +107,10 @@ int rt_vfprintf(FILE *stream, const char *format,
> va_list args)
> read_pos = buffer->read_pos;
> xnarch_read_memory_barrier();
>
> + assert(write_pos == read_pos ||
> + ((struct entry_head *)buffer->ring + buffer->read_pos)->magic ==
> + RT_PRINT_HEAD_MAGIC);
> +
> /* Is our write limit the end of the ring buffer? */
> if (write_pos >= read_pos) {
> /* Keep a savety margin to the end for at least an empty entry
> */
> @@ -114,6 +122,7 @@ int rt_vfprintf(FILE *stream, const char *format, va_list
> args)
> if (len == 0 && read_pos > sizeof(struct entry_head)) {
> /* Write out empty entry */
> head = buffer->ring + write_pos;
> + head->magic = RT_PRINT_HEAD_MAGIC;
> head->seq_no = seq_no;
> head->text[0] = 0;
>
> @@ -136,6 +145,10 @@ int rt_vfprintf(FILE *stream, const char *format,
> va_list args)
>
> res = vsnprintf(head->text, len, format, args);
>
> + assert(write_pos == read_pos ||
> + ((struct entry_head *)buffer->ring + buffer->read_pos)->magic ==
> + RT_PRINT_HEAD_MAGIC);
> +
> if (res < len) {
> /* Text was written completely, res contains its length */
> len = res;
> @@ -147,6 +160,7 @@ int rt_vfprintf(FILE *stream, const char *format, va_list
> args)
>
> /* If we were able to write some text, finalise the entry */
> if (len > 0) {
> + head->magic = RT_PRINT_HEAD_MAGIC;
> head->seq_no = ++seq_no;
> head->dest = stream;
>
> @@ -159,6 +173,7 @@ int rt_vfprintf(FILE *stream, const char *format, va_list
> args)
> read_pos <= write_pos && read_pos > buffer->size - write_pos) {
> /* An empty entry marks the wrap-around */
> head = buffer->ring + write_pos;
> + head->magic = RT_PRINT_HEAD_MAGIC;
> head->seq_no = seq_no;
> head->text[0] = 0;
>
> @@ -382,6 +397,8 @@ static void print_buffers(void)
> head = buffer->ring + read_pos;
> len = strlen(head->text);
>
> + assert(head->magic == RT_PRINT_HEAD_MAGIC);
> +
> if (len) {
> /* Print out non-empty entry and proceed */
> fprintf(head->dest, "%s", head->text);
>
_______________________________________________
Xenomai-help mailing list
[email protected]
https://mail.gna.org/listinfo/xenomai-help