本程序可以查看实时程序中是否调用了非实时接口,如果是的话会发送sigdebug信号提示或结束,开发者写实时程序的时候可以加上以防止写了非实时代码。 测试发现调用open,close write等常用inux系统调用都会进入非实时模式。打开CONFIG_XENO_OPT_DEBUG_TRACE_RELAX可以跟踪非实时调用的位置。
//-----------------------sigdebug.c-----------------------------------------------------
/*
* Copyright (C) 2004-2015 Philippe Gerum <rpm@xenomai.org>
* Copyright (C) 2014 Gilles Chanteperdrix <gch@xenomai.org>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <error.h>
#include <signal.h>
#include <sched.h>
#include <unistd.h>
#include <pthread.h>
#include <xeno_config.h>
#include <rtdm/testing.h>
#define HIPRIO 99
#define LOPRIO 0
int priority = HIPRIO;
static void *pthread_func(void *cookie)
{
pthread_setmode_np(0, PTHREAD_WARNSW, NULL);
open("abc",O_CREAT,0777);
return NULL;
}
#ifdef CONFIG_XENO_COBALT
//#include <cobalt/uapi/syscall.h>
static const char *reason_str[] = {
[SIGDEBUG_UNDEFINED] = "received SIGDEBUG for unknown reason",
[SIGDEBUG_MIGRATE_SIGNAL] = "received signal",
[SIGDEBUG_MIGRATE_SYSCALL] = "invoked syscall",
[SIGDEBUG_MIGRATE_FAULT] = "triggered fault",
[SIGDEBUG_MIGRATE_PRIOINV] = "affected by priority inversion",
[SIGDEBUG_NOMLOCK] = "process memory not locked",
[SIGDEBUG_WATCHDOG] = "watchdog triggered (period too short?)",
[SIGDEBUG_LOCK_BREAK] = "scheduler lock break",
};
static void sigdebug(int sig, siginfo_t *si, void *context)
{
printf("sigdebug\n\n");
const char fmt[] = "%s, aborting.\n"
"(enabling CONFIG_XENO_OPT_DEBUG_TRACE_RELAX may help)\n";
unsigned int reason = sigdebug_reason(si);
int n __attribute__ ((unused));
static char buffer[256];
if (reason > SIGDEBUG_WATCHDOG)
reason = SIGDEBUG_UNDEFINED;
switch(reason) {
case SIGDEBUG_UNDEFINED:
case SIGDEBUG_NOMLOCK:
case SIGDEBUG_WATCHDOG:
n = snprintf(buffer, sizeof(buffer), "pthread_func: %s\n",
reason_str[reason]);
n = write(STDERR_FILENO, buffer, n);
exit(EXIT_FAILURE);
}
n = snprintf(buffer, sizeof(buffer), fmt, reason_str[reason]);
n = write(STDERR_FILENO, buffer, n);
signal(sig, SIG_DFL);
kill(getpid(), sig);
}
#endif /* CONFIG_XENO_COBALT */
static void setup_sched_parameters(pthread_attr_t *attr, int prio)
{
struct sched_param p;
int ret;
ret = pthread_attr_init(attr);
if (ret)
error(1, ret, "pthread_attr_init()");
ret = pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED);
if (ret)
error(1, ret, "pthread_attr_setinheritsched()");
ret = pthread_attr_setschedpolicy(attr, prio ? SCHED_FIFO : SCHED_OTHER);
if (ret)
error(1, ret, "pthread_attr_setschedpolicy()");
p.sched_priority = prio;
ret = pthread_attr_setschedparam(attr, &p);
if (ret)
error(1, ret, "pthread_attr_setschedparam()");
}
int main(int argc, char *const *argv) {
pthread_t latency_task;
struct sigaction sa;
pthread_attr_t tattr;
#ifdef CONFIG_XENO_COBALT
sigemptyset(&sa.sa_mask);
sa.sa_sigaction = sigdebug;
sa.sa_flags = SA_SIGINFO;
sigaction(SIGDEBUG, &sa, NULL);
#endif
setup_sched_parameters(&tattr, priority);
pthread_create(&latency_task, &tattr, pthread_func, NULL);
// pthread_attr_destroy(&tattr);
pthread_join(latency_task,NULL);
return 0;
}