I got a kernel crash because inside xnheap_test_and_free a 
invalid pointer contained in variable 'nextpage' is dereferenced:

  /* Mark the released pages as free in the extent's page map. */
  for (pagecont = 0; pagecont < npages; pagecont++)
       extent->pagemap[pagenum + pagecont].type = XNHEAP_PFREE;

  /* Return the sub-list to the free page list, keeping
     an increasing address order to favor coalescence. */

  for (nextpage = extent->freelist, lastpage = NULL;
       nextpage != NULL && nextpage < (caddr_t) block;
       lastpage = nextpage, 
/* PROBLEM IS HERE => */  nextpage = *((caddr_t *) nextpage))
  ; /* Loop */

This error occurs when running the test application on our 
PowerPC target as well as when running it on the x86 host 
with the newest version of Xenomai (2.4.7).

Target setup:
- Xenomai 2.4.4
- Linux 2.6.26
- PowerPC

Host setup:
- Xenomai 2.4.7
- Linux 2.6.26
- i686

You should be able to confirm my problem with 'rtpipetest', a 
small application of which the source code is attached to this 

I got the kernel crash after the following sequence of commands (and
the kernel doesn't crash if I DON'T do the 'echo f> /dev/rtp0'): 

rr10:~# ./rtpipetest &
[1] 2568
rr10:~# Info: rt_pipe_stream is full (ret=0)
cat /dev/rtp0
rr10:~# echo f> /dev/rtp0
rr10:~# kill -s SIGINT 2568

This is the error report from our target. The error report
on the host also tells me that the kernel crashed in 

Unable to handle kernel paging request for data at address 0x64646464
Faulting instruction address: 0xc0054324
Oops: Kernel access of bad area, sig: 11 [#1]
RC8360 CM
Modules linked in: lm75 max6369_wdt rtc_ds1307
NIP: c0054324 LR: c006e4e4 CTR: 00000000
REGS: df13fd80 TRAP: 0300   Not tainted  (2.6.26-1-8360e)
MSR: 00001032 <ME,IR,DR>  CR: 24002488  XER: 00000000
DAR: 64646464, DSISR: 20000000
TASK = df899ce0[2568] 'main' THREAD: df13e000
GPR00: 00000000 df13fe30 df899ce0 e100e9f8 00000009 00000000 c9b26c9b
GPR08: df052240 64646464 00000002 64646464 84004028 1001a6f0 df13ff50
GPR16: c0375eac ffffffff fffeffff 00000040 00000010 c0360000 00000400
GPR24: 00000004 0000000a 00000000 e100e9f8 c0360000 df052240 df052040
NIP [c0054324] xnheap_test_and_free+0x2c4/0x3cc
LR [c006e4e4] rt_pipe_delete+0xf0/0x158
Call Trace:
[df13fe30] [c005dbb8] xntimer_start_aperiodic+0x2dc/0x2e4 (unreliable)
[df13fe70] [c006e4e4] rt_pipe_delete+0xf0/0x158
[df13fe90] [c0068d00] __rt_pipe_delete+0x74/0xac
[df13feb0] [c0060c00] hisyscall_event+0x1cc/0x2c4
[df13fee0] [c0051a38] __ipipe_dispatch_event+0x110/0x21c
[df13ff30] [c0009694] __ipipe_syscall_root+0x40/0xe8
[df13ff40] [c0010f44] DoSyscall+0x20/0x5c
--- Exception: c01 at 0xff7ecdc
    LR = 0xff7ecb4
Instruction dump:
5529103a 7d3f4a14 98090004 4200ffe8 813f0010 2f890000 419e0040 7f89f040 
41bc000c 48000034 40980018 7d2b4b78 <81290000> 2f890000 7f09f040
---[ end trace 90e6f47d0e66c1c4 ]---
#include <rtdk.h>
#include <native/pipe.h>
#include <native/task.h>
#include <errno.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#include <stdlib.h>

static RT_TASK	m_task;
static RT_PIPE	m_pipe;

#define rc_error(fn, ret)	rt_printf("Error: " fn ":%s (%d) %s\n", strerror(-ret), -ret)

int main(void)
	int			err;
	const char*	out_str		= "d";
	int			out_str_len	= 1;
	int			in_str_len	= 32;
	char		in_str[in_str_len];

	// Lock pages in memory

	// Init rtdk framework for rt_printf

	// Add rt shadow
	err	= rt_task_shadow(&m_task, "main", 22, 0);
	if(err) {
		rc_error("rt_task_shadow", err);
		return err;

	// Create pipe
	err	= rt_pipe_create(&m_pipe, "rtp0", 0, 2048);
	if(err) {
		rc_error("rt_pipe_create", err);
		goto cleanup;

	// Deliberately fill pipe without a reader on
	// the other side...
	while(1) {
		err	= rt_pipe_stream(&m_pipe, out_str, out_str_len);
		// Check if there was an error
		if(err < 0) {
			rc_error("rt_pipe_stream", err);
			goto cleanup;
		// Check if all bytes where written to the pipe
		if(err != out_str_len) {
			rt_printf("Info: rt_pipe_stream is full (ret=%d)\n", err);

	// Wait for the user to connect to the pipe and 
	// loop until we are able to read a byte
	while(1) {
		err	= rt_pipe_read(&m_pipe, in_str, in_str_len, TM_NONBLOCK);
		if(err < 0 && err != -EAGAIN) {
			rc_error("rt_pipe_read", err);
			goto cleanup;
		// Check if we received something	
		if(err > 0) {
			rt_printf("Received: %s\n", in_str);

		// Wait 1ms

	return err;
Xenomai-core mailing list

Reply via email to