根据SylixOS使用手册,记录一个使用Crash Trap 调试,但crashtrap捕获不到程序崩溃的异常问题。
我的环境是SylixOS version 2.3.6,CPU zynq7020,IDE 6.1.0。
一、使用官方例程
#include <SylixOS.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
void func()
{
int a = 3, b = 3, int i;
for(i = 0; i < 120; i++)
{
/*
* 当count等于3时,触发算数异常
*/
printf("%d\n", a / (b - i));
sleep(1);
}
}
int main (int argc, char **argv)
{
printf("Hello SylixOS!\n");
/*
* 程序开始延时10s,等待执行crashtrap命令
*/
sleep(10);
func();
return (0);
}
执行效果:
程序执行到i等于3时直接结束,并没有被crashtrap捕获。
二、在程序中执行crashtrap
修改代码,在程序一开始通过代码方式启用crashtrap
#include <SylixOS.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
void func()
{
int a = 3, b = 3, int i;
for(i = 0; i < 120; i++)
{
/*
* 当count等于3时,触发算数异常
*/
printf("%d\n", a / (b - i));
sleep(1);
}
}
int main (int argc, char **argv)
{
char cmd[64];
printf("Hello SylixOS!\n");
snprintf(cmd, sizeof(cmd), "crashtrap %d 1", getpid());
system(cmd);
func();
return (0);
}
效果:
和在命令行启用crashtrap同样不能被捕获,程序直接结束。
三、修改代码中崩溃的位置
主动增加一个空指针操作,触发程序异常
#include <SylixOS.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int main (int argc, char **argv)
{
char cmd[64];
printf("Hello SylixOS!\n");
snprintf(cmd, sizeof(cmd), "crashtrap %d 1", getpid());
system(cmd);
char *buf = NULL;
char *data = "hello world";
//空指针内存拷贝
memcpy(buf, data, strlen(data));
return (0);
}
效果:
程序崩溃,并且系统直接挂掉,从IDE中登录可以看到crash_test线程是STOP状态
通过Attach Remote App可以看到程序崩溃位置:
四、尝试其他崩溃
1、修改只读内存(结果:SylixOS允许修改字符串常量 Oh Shit!)
#include <SylixOS.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int main (int argc, char **argv)
{
char cmd[64];
printf("Hello SylixOS!\n");
snprintf(cmd, sizeof(cmd), "crashtrap %d 1", getpid());
system(cmd);
char *str = "Hello, World!";
//修改只读内存
str[0] = 'h';
printf("%s\n", str);
return (0);
}
2、越界访问数组(结果:SylixOS不检查数组越界 Oh Shit!)
#include <SylixOS.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int main (int argc, char **argv)
{
char cmd[64];
printf("Hello SylixOS!\n");
snprintf(cmd, sizeof(cmd), "crashtrap %d 1", getpid());
system(cmd);
int array[5] = {1, 2, 3, 4, 5};
//越界访问数组
printf("%d\n", array[10]);
return (0);
}
3、栈溢出(结果:SylixOS栈溢出直接重启 Oh Shit!)
#include <SylixOS.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
void recursive_function(int n) {
char large_array[1000]; // 在栈上分配一个大数组
printf("Level %d, address of array: %p\n", n, &large_array);
recursive_function(n + 1); // 递归调用自己
}
int main (int argc, char **argv)
{
char cmd[64];
printf("Hello SylixOS!\n");
snprintf(cmd, sizeof(cmd), "crashtrap %d 1", getpid());
system(cmd);
recursive_function(1);
return (0);
}
结果:系统直接重启
五、Attach方法
六、总结
1、除法分母为负值产生的崩溃不能被crashtrap捕获。
2、指针操作导致的崩溃可以被crashtrap捕获,但会导致系统崩溃;不使用crashtrap捕获则不会导致系统崩溃。
3、尝试了几个可能导致段错误的情况,大部分会导致系统直接重启,我要你有何用!Oh Shit!