Christoph Permes wrote:
> Hi,
>
> I have examined the print_buffers() function and my core dump:
>
> #1 0xb8087f61 in print_buffers () at rt_print.c:380
> 380 fprintf(head->dest, "%s", head->text);
> (gdb) print head->dest
> $1 = (FILE *) 0x445b205d
> (gdb) print head->text
> $2 = "_"
> (gdb) print (char*)head
> $3 = 0x8ea5a02 "] [D] [V_MainClampToteRequest ] ===> [1]\n"
> (gdb) print buffer->read_pos
> $4 = 3482
> (gdb) print *(char*)buffer->r...@3500
> $5 = "... [67046.506] [CONTROL] [1104820] [\000] [D] [V_MainClamp"
>
> As the above output shows the head pointer points to a wrong memory
> address, the head->dest FILE pointer results from some text written to
> the buffer.
>
> buffer = get_next_buffer();
> if (!buffer)
> break;
>
> read_pos = buffer->read_pos;
> head = buffer->ring + read_pos;
> len = strlen(head->text);
>
> if (len) {
> /* Print out non-empty entry and proceed */
> fprintf(head->dest, "%s", head->text); // ==> SEGV
> read_pos += sizeof(*head) + len;
> } else {
> /* Emptry entries mark the wrap-around */
> read_pos = 0;
> }
>
> Obviously the value of buffer->read_pos is not correct or the buffer
> pointer returned by get_next_buffer() points to a wrong address.
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);
signature.asc
Description: OpenPGP digital signature
_______________________________________________ Xenomai-help mailing list [email protected] https://mail.gna.org/listinfo/xenomai-help
