[Xenomai] Crash with longer dlopen/dlcose sequence

Edouard Tisserant edouard.tisserant at gmail.com
Wed May 9 10:57:53 CEST 2018

> [Xenomai] bad syscall <0xf0002>

It appears that 0xf0002 is a private ARM SWI, as declared in linux'
/arch/arm/include/uapi/asm/unistd.h :

 * The following SWIs are ARM private.
#define __ARM_NR_BASE           (__NR_SYSCALL_BASE+0x0f0000)
#define __ARM_NR_breakpoint     (__ARM_NR_BASE+1)
#define __ARM_NR_cacheflush     (__ARM_NR_BASE+2)

Code in Xenomai's /kernel/cobalt/posix/syscall.c must be wrong :

    code = __xn_get_syscall_nr(regs);
    if (code >= NR_syscalls)
        goto bad_syscall;

NR_syscalls is defined in kernel as 400, so private ARM SWIs are always

What should we do ? Can we safely ignore that cacheflush syscall is not
being executed ?

Otherwise, what should be the logic to determine good or bad syscalls ?

On 09/05/2018 09:45, Edouard Tisserant wrote:
> I detected this in my dmesg :
> [Xenomai] bad syscall <0xf0002>
> The message isn't associated to any crash. It doesn't seem to break
> anything, but it doesn't smell good... does it ?
> It happens each time I dlopen a cobalt-wrapped shared object (also
> happens if just using alchemy, without any other special linker
> instuctions).
> I was looking at kernel/cobalt/posix/syscall*,  but still I couldn't
> figure out what is emitting that wrong syscall when dlopening. In case
> it matters, OABI compatibility is not enabled in my build, and target is
> an imx28.
> I'm a bit lost. Where should I search ?
> On 27/04/2018 17:43, Philippe Gerum wrote:
>> On 04/27/2018 04:43 PM, Edouard Tisserant wrote:
>>>> Now let see if dlopen/dlclose some code using alchemy segfaults or not...
>>> Well, it didn't work as-is, but I finally got it working !
>>> If I was dlopening anything relying on copperplate after that python
>>> code, then it was making an assert :  __register_setup_call: Assertion
>>> `!main_init_done' failed.
>>> The reason is that all xenomai libraries we plan to use have to be
>>> loaded _before_ call to xenomai_init, so that their setup call is
>>> registered.
>>> Hereafter is updated (and simplified) python code :
>>> from ctypes import *
>>> for name in ["cobalt", "modechk", "copperplate", "alchemy"]:
>>>     globals()[name] = CDLL("lib"+name+".so", mode=RTLD_GLOBAL)
>>> cobalt.xenomai_init(pointer(c_int(0)),
>>> pointer((POINTER(c_char)*2)(create_string_buffer("python"), None)))
>>> Note : Order of dlopen matters. Argument passed to
>>> xenomai_init(&argc,&argv) are here only to prevent de-referencing NULL.
>>> After this being executed, you can load and unload many shared object
>>> that use alchemy and posix (they should not be linked to boostrap_pic.o)
>> Looks good. The key point is that xenomai_init() is the call from the
>> API which controls the whole Xenomai init process, after which Xenomai
>> libs are fully functional. This explains why any library which wants to
>> be part of that process needs its setup descriptor to be known and
>> registered prior to issuing this call.
>> The bootstrap module is just a helper that calls xenomai_init()
>> automatically before the main() routine is entered (bootstrap.o) when
>> glued to a final executable, or right after a DSO is loaded
>> (bootstrap-pic.o) when glued to a shared library. If the application
>> wants a fine-grained control over the init sequence instead, it just
>> needs not to include the bootstrap module in the executable/DSO, calling
>> xenomai_init() manually when it sees fit.

More information about the Xenomai mailing list