Hello,

I have been trying to debug a xenomai-cobalt application which uses
the POSIX API.
Target environment:
hw = ARM64,
linux kernel = 4.12.14,
"cat /proc/xenomai/version" = 3.1-devel,
"cat /proc/ipipe/version" = 2.

Debugger/compiler info:
gdb (on the target board): GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
gcc (on the target board):(Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609
Installed Xenomai 3 libraries from the latest xenomai-next package
with the target's default toolchain mentioned above using :
./scripts/bootstrap
./configure CFLAGS="-march=armv8-a" LDFLAGS="-march=armv8-a"
--with-core=cobalt --enable-smp --enable-pshared
make
sudo make install

Compiled the Posix App on the target using the attached makefile. Then
ran the application - works perfectly fine. I can also see the RT
thread (with correct priority) in "cat /proc/xenomai/sched/threads".
Now I ran the application with gdb (no breakpoints) - works perfectly
fine. Next I ran the application with breakpoints inside "main" & the
RT task - only the "main" breakpoints were hit and gdb freezes without
hitting the RT bereakpoint. I also ran a simple "alchemy" based
application and the breakpoints in the RT task worked perfectly fine.

At the moment the only workaround I use is to switch to the
SCHED_OTHER (non-RT) scheme & then the breakpoints work fine.
Did anyone face this issue? If yes how was this resolved with SCHED_FIFO on?

Thank you,
Virendra
-------------- next part --------------

/*
   Demo of a simple periodic thread using Posix
   under 'standard' Linux
   and under Xenomai versions 2 and 3 using posix skin
   Marc Le Douarain, august 2015
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <errno.h>
#include <pthread.h>
#include <sys/mman.h>
#include <sys/timerfd.h>

#define PERIOD_MICROSECS 10000 //10millisecs
#define START_DELAY_SECS 1 //1sec

pthread_t MyPosixThread;
int TimerFdForThread = -1;
char ThreadRunning = 0;
int ResultIncValue = 0;

int CreatePosixTask( char * TaskName, int Priority, int StackSizeInKo, unsigned 
int PeriodMicroSecs, void * (*pTaskFunction)(void *) )
{
        pthread_attr_t ThreadAttributes;
        int err = pthread_attr_init(&ThreadAttributes);
        if ( err )
        {
                printf("pthread attr_init() failed for thread '%s' with 
err=%d\n", TaskName, err );
                return -10;
        }
#ifdef __COBALT__
        err = pthread_attr_setinheritsched( &ThreadAttributes, 
PTHREAD_EXPLICIT_SCHED );
        if ( err )
        {
                printf("pthread set explicit sched failed for thread '%s' with 
err=%d\n", TaskName, err );
                return -11;
        }
#endif
        err = pthread_attr_setdetachstate(&ThreadAttributes, 
PTHREAD_CREATE_DETACHED /*PTHREAD_CREATE_JOINABLE*/);
        if ( err )
        {
                printf("pthread set detach state failed for thread '%s' with 
err=%d\n", TaskName, err );
                return -12;
        }
#if defined(__XENO__) || defined(__COBALT__)
        err = pthread_attr_setschedpolicy(&ThreadAttributes, SCHED_FIFO);
        if ( err )
        {
                printf("pthread set scheduling policy failed for thread '%s' 
with err=%d\n", TaskName, err );
                return -13;
        }
        struct sched_param paramA = { .sched_priority = Priority };
        err = pthread_attr_setschedparam(&ThreadAttributes, &paramA);
        if ( err )
        {
                printf("pthread set priority failed for thread '%s' with 
err=%d\n", TaskName, err );
                return -14;
        }
#endif
/*      if ( StackSizeInKo>0 )
        {
                err = pthread_attr_setstacksize(&ThreadAttributes, 
StackSizeInKo*1024);
                if ( err )
                {
                        printf("pthread set stack size failed for thread '%s' 
with err=%d\n", TaskName, err );
                        return -15;
                }
        }
*/
        // calc start time of the periodic thread
        struct timespec start_time;
#ifdef __XENO__
        if ( clock_gettime( CLOCK_REALTIME, &start_time ) )
#else
        if ( clock_gettime( CLOCK_MONOTONIC, &start_time ) )
#endif
        {
                printf( "Failed to call clock_gettime\n" );
                return -20;
        }
        /* Start one seconde later from now. */
        start_time.tv_sec += START_DELAY_SECS ;
        
        // if a timerfd is used to make thread periodic (Linux / Xenomai 3),
        // initialize it before launching thread (timer is read in the loop)
#ifndef __XENO__ 
        struct itimerspec period_timer_conf;
        TimerFdForThread = timerfd_create(CLOCK_MONOTONIC, 0);
        if ( TimerFdForThread==-1 )
        {
                printf( "Failed to create timerfd for thread '%s'\n", TaskName);
                return -21;
        }
        period_timer_conf.it_value = start_time;
        period_timer_conf.it_interval.tv_sec = 0;
        period_timer_conf.it_interval.tv_nsec = PeriodMicroSecs*1000;
        if ( timerfd_settime(TimerFdForThread, TFD_TIMER_ABSTIME, 
&period_timer_conf, NULL) )
        {
                printf( "Failed to set periodic tor thread '%s' with 
errno=%d\n", TaskName, errno);
                return -22;
        }
#endif
        
        ThreadRunning = 1;
        err = pthread_create( &MyPosixThread, &ThreadAttributes, (void 
*(*)(void *))pTaskFunction, (void *)NULL );
        if ( err )
        {
                printf( "Failed to create thread '%s' with err=%d !!!!!\n", 
TaskName, err );
                return -1;
        }
        else
        {
                // make thread periodic for Xenomai 2 with 
pthread_make_periodic_np() function.
#ifdef __XENO__ 
                struct timespec period_timespec;
                period_timespec.tv_sec = 0;
                period_timespec.tv_nsec = PeriodMicroSecs*1000;
                if ( pthread_make_periodic_np(MyPosixThread, &start_time, 
&period_timespec)!=0 )
                {
                        printf("Xenomai make_periodic failed for thread '%s' 
with err=%d\n", TaskName, err);
                        return -30;
                }
#endif

                pthread_attr_destroy(&ThreadAttributes);
#ifdef __XENO__ 
                err = pthread_set_name_np( MyPosixThread, TaskName );
#else
                err = pthread_setname_np( MyPosixThread, TaskName );
#endif
                if ( err )
                {
                        printf("pthread set name failed for thread '%s', 
err=%d\n", TaskName, err );
                        return -40;
                }
                printf( "Created thread '%s' period=%dusecs ok.\n", TaskName, 
PeriodMicroSecs );
                return 0;
        }
}

void WaitPeriodicPosixTask( )
{
        int err = 0;
#ifdef __XENO__
        unsigned long overruns;
        err = pthread_wait_np(&overruns);
        if (err || overruns)
        {
                printf( "Xenomai wait_period failed for thread: err=%d, 
overruns=%lu\n", err, overruns );
        }
#else
        uint64_t ticks;
        err = read(TimerFdForThread, &ticks, sizeof(ticks));
        if ( err<0 )
        {
                printf( "TimerFd wait period failed for thread with 
errno=%d\n", errno );
        }
        if ( ticks>1 )
        {
                printf( "TimerFd wait period missed for thread: 
overruns=%lu\n", (long unsigned int)ticks );
        }
#endif
}

// our really simple thread just incrementing a variable in loop !
void * MySimpleTask( void * dummy )
{
        while( ThreadRunning )
        {
                WaitPeriodicPosixTask( );
                ResultIncValue++;
        }
        return 0;
}

int main( int argc, char * argv[] )
{
        int err;
        printf("Simple periodic thread using Posix.\n");
#if defined( __XENO__ ) || defined( __COBALT__ )
        printf("Version compiled for Xenomai 2 or 3.\n");
        mlockall(MCL_CURRENT | MCL_FUTURE);
#endif
        err = CreatePosixTask( "DemoPosix", 1/*Priority*/, 4/*StackSizeInKo*/, 
PERIOD_MICROSECS/*PeriodMicroSecs*/, MySimpleTask );
        if ( err!=0 )
        {
                printf( "Init task error (%d)!\n",err );
        }
        else
        {
                printf( "Wait 10 seconds before ending...\n" );
                sleep( 10 );
                ThreadRunning = 0;
                printf( "Increment value during 10 secs = %d (should be %d)\n", 
ResultIncValue, ((10-START_DELAY_SECS)*1000*1000)/PERIOD_MICROSECS );
        }
        return 0;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: Makefile
Type: application/octet-stream
Size: 371 bytes
Desc: not available
URL: 
<http://xenomai.org/pipermail/xenomai/attachments/20180312/db0614a0/attachment.obj>
-------------- next part --------------
root@rk3399-q72:/home/vk/Posix# ls
Makefile  posix_demo.c
root@rk3399-q72:/home/vk/Posix#
root@rk3399-q72:/home/vk/Posix#
root@rk3399-q72:/home/vk/Posix# make
gcc -o posix_demo posix_demo.c -I/usr/xenomai/include/cobalt 
-I/usr/xenomai/include -D_GNU_SOURCE -D_REENTRANT -D__COBALT__ 
-D__COBALT_WRAP__ -g -O0 -fno-stack-protector -Wl,--no-as-needed 
-Wl,@/usr/xenomai/lib/cobalt.wrappers -Wl,@/usr/xenomai/lib/modechk.wrappers  
/usr/xenomai/lib/xenomai/bootstrap.o -Wl,--wrap=main 
-Wl,--dynamic-list=/usr/xenomai/lib/dynlist.ld -L/usr/xenomai/lib -lcobalt 
-lmodechk -lpthread -lrt
root@rk3399-q72:/home/vk/Posix#
root@rk3399-q72:/home/vk/Posix#
root@rk3399-q72:/home/vk/Posix# ls
Makefile  posix_demo  posix_demo.c
root@rk3399-q72:/home/vk/Posix#
root@rk3399-q72:/home/vk/Posix#
root@rk3399-q72:/home/vk/Posix# ./posix_demo
Simple periodic thread using Posix.
Version compiled for Xenomai 2 or 3.
Created thread 'DemoPosix' period=10000usecs ok.
Wait 10 seconds before ending...
Increment value during 10 secs = 901 (should be 900)
root@rk3399-q72:/home/vk/Posix#
root@rk3399-q72:/home/vk/Posix#
root@rk3399-q72:/home/vk/Posix#
root@rk3399-q72:/home/vk/Posix#
root@rk3399-q72:/home/vk/Posix# gdb posix_demo
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "aarch64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from posix_demo...done.
(gdb) list 175
170     void * MySimpleTask( void * dummy )
171     {
172             while( ThreadRunning )
173             {
174                     WaitPeriodicPosixTask( );
175                     ResultIncValue++;
176             }
177             return 0;
178     }
179
(gdb) b 175
Breakpoint 1 at 0x40168c: file posix_demo.c, line 175.
(gdb)
Note: breakpoint 1 also set at pc 0x40168c.
Breakpoint 2 at 0x40168c: file posix_demo.c, line 175.
(gdb) list 188
183             printf("Simple periodic thread using Posix.\n");
184     #if defined( __XENO__ ) || defined( __COBALT__ )
185             printf("Version compiled for Xenomai 2 or 3.\n");
186             mlockall(MCL_CURRENT | MCL_FUTURE);
187     #endif
188             err = CreatePosixTask( "DemoPosix", 1/*Priority*/, 
4/*StackSizeInKo*/, PERIOD_MICROSECS/*PeriodMicroSecs*/, MySimpleTask );
189             if ( err!=0 )
190             {
191                     printf( "Init task error (%d)!\n",err );
192             }
(gdb) b 188
Breakpoint 3 at 0x4016f8: file posix_demo.c, line 188.
(gdb) run
Starting program: /home/vk/Posix/posix_demo
warning: Unable to determine the number of hardware watchpoints available.
warning: Unable to determine the number of hardware breakpoints available.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/aarch64-linux-gnu/libthread_db.so.1".
[New Thread 0xffffb7d83200 (LWP 2766)]
Simple periodic thread using Posix.
Version compiled for Xenomai 2 or 3.

Thread 1 "posix_demo" hit Breakpoint 3, main (argc=1, argv=0x413650)
    at posix_demo.c:188
188             err = CreatePosixTask( "DemoPosix", 1/*Priority*/, 
4/*StackSizeInKo*/, PERIOD_MICROSECS/*PeriodMicroSecs*/, MySimpleTask );
(gdb) c
Continuing.
[New Thread 0xffffb7583200 (LWP 2767)]
Created thread 'DemoPosix' period=10000usecs ok.
Wait 10 seconds before ending...
^C^C^Z^Z^X^C









_______________________________________________
Xenomai mailing list
Xenomai@xenomai.org
https://xenomai.org/mailman/listinfo/xenomai

Reply via email to