使用 strtok() 时出现硬故障
Hard Fault when using strtok()
我知道还有很多关于使用 strtok()
导致分段错误的其他线程,但在我的情况下这似乎是一个不同的问题。我在 STM32L4 控制器上使用它,同样的代码在使用在线编译器编译时工作正常
void strtokTest(uint8_t* dest){
char str[] = "1.1.2\nMore Text";
printf("%s", str);
char* token = strtok(str, ".");
uint8_t index = 0;
while(token){
printf("%s", token);
dest[index] = atoi(token);
if(index++ == 2){
break;
}
token = strtok(NULL, ".");
}
}
正确找到了第一个标记,但是在 token = strtok(NULL, ".")
的第一次调用中,代码遇到了硬错误(可能与分段错误相同),我不明白为什么.. .
更新:
我是 运行 FreeRTOS 之前没有提到这个,因为我认为它不相关,但可能不是。似乎如果我在启动调度程序之前调用 strtokTest
函数,它就可以工作,但如果我从我的一个任务中调用它,它就会失败。
我无法使用我的调试器进入,因为这会立即触发硬故障并且堆栈跟踪没有提供太多信息。
因为 strtok
不是线程安全的,在多线程程序中最好使用 strtok_r
如果它可用(它不是由 ISO C 提供,但它是由 POSIX 提供) .您在评论中表示这解决了您的崩溃问题。
如果您真的只从一个线程(包括主线程)调用 strtok
,那么我认为这不会有什么不同。因此,您可能弄错了哪些线程调用了此函数,或者可能在程序的其他地方对 strtok
进行了另一个调用。您可能需要进一步调查。
另一个疯狂的猜测可能是您的程序的链接或加载有问题,以至于 strtok
的内部静态数据没有在可写内存中正确分配。如果它在 ROM 中结束,可以想象内部指针会停留在 NULL 上,而对 strtok
的第二次调用将取消对它的引用。
或者,也许您的库的 strtok
实现尝试使用线程本地存储,以帮助减轻这种风险,并且您的程序中线程本地存储的设置方式可能有问题?
我知道还有很多关于使用 strtok()
导致分段错误的其他线程,但在我的情况下这似乎是一个不同的问题。我在 STM32L4 控制器上使用它,同样的代码在使用在线编译器编译时工作正常
void strtokTest(uint8_t* dest){
char str[] = "1.1.2\nMore Text";
printf("%s", str);
char* token = strtok(str, ".");
uint8_t index = 0;
while(token){
printf("%s", token);
dest[index] = atoi(token);
if(index++ == 2){
break;
}
token = strtok(NULL, ".");
}
}
正确找到了第一个标记,但是在 token = strtok(NULL, ".")
的第一次调用中,代码遇到了硬错误(可能与分段错误相同),我不明白为什么.. .
更新:
我是 运行 FreeRTOS 之前没有提到这个,因为我认为它不相关,但可能不是。似乎如果我在启动调度程序之前调用 strtokTest
函数,它就可以工作,但如果我从我的一个任务中调用它,它就会失败。
我无法使用我的调试器进入,因为这会立即触发硬故障并且堆栈跟踪没有提供太多信息。
因为 strtok
不是线程安全的,在多线程程序中最好使用 strtok_r
如果它可用(它不是由 ISO C 提供,但它是由 POSIX 提供) .您在评论中表示这解决了您的崩溃问题。
如果您真的只从一个线程(包括主线程)调用 strtok
,那么我认为这不会有什么不同。因此,您可能弄错了哪些线程调用了此函数,或者可能在程序的其他地方对 strtok
进行了另一个调用。您可能需要进一步调查。
另一个疯狂的猜测可能是您的程序的链接或加载有问题,以至于 strtok
的内部静态数据没有在可写内存中正确分配。如果它在 ROM 中结束,可以想象内部指针会停留在 NULL 上,而对 strtok
的第二次调用将取消对它的引用。
或者,也许您的库的 strtok
实现尝试使用线程本地存储,以帮助减轻这种风险,并且您的程序中线程本地存储的设置方式可能有问题?