RT-Smart 应用(apps)开发环境,ubuntu 20.04 + win10 VS Code
最近在调试一个问题,需要使用 FILE
的 fopen、fread 等去读取处理一个大文件,为了尽快复现验证问题,随手搜了一下 fopen 等几个 API的用法,调试时闹出来一个【笑话】,程序运行所到之处,把处理过的本地文件清空了。
当时初步的目标只是使用 stat
去获取一个文件的大小,现象就是 0
如何在 用户态获取文件大小,RT-Smart 的应用开发与 Linux 的用户应用开发基本类似,Linux 平台上的应用,可以轻松的移植到 RT-Smart 上。
fopen 可以在RT-Smart内核态使用,也可以在用户态使用,用户态的使用,一般都是借助 libc 与 系统调用,当前 RT-Smart 使用 musl gcc 工具链
获取文件大小,应该与 fopen、fread 系列无关,代码如下:
unsigned long get_file_size(const char *path)
{
unsigned long filesize = -1;
struct stat statbuff;
if (stat(path, &statbuff) < 0)
{
return filesize;
}
else
{
filesize = statbuff.st_size;
}
return filesize;
}
stat
,头文件 #include
随手摘抄修改了一个测试代码,想获取到 文件大小,然后分批读取,验证这个过程是否正常,哪想到文件大小获取为0,使用 qemu 调试了多遍,怀疑文件系统BUG,依旧未找到正确的思路
原 BUG 测试代码如下:
/* read big file : > 300MB */
#include
#include
#include
#include
#include
#include
#include
#define BUFFER_SIZE (8 * 1024 * 1024)
unsigned long get_file_size(const char *path)
{
unsigned long filesize = -1;
struct stat statbuff;
if (lstat(path, &statbuff) < 0)
{
return filesize;
}
else
{
filesize = statbuff.st_size;
}
return filesize;
}
int main(int argc, char **argv)
{
//int errno;
FILE *fp = NULL;
unsigned long so_far, signed_len;
const char *path = "/lib/libc.so";
char *buffer = NULL;
size_t size;
size_t file_size;
size_t rd_len;
if (argc > 1)
{
path = argv[1];
}
printf("filename path : %s\n", path);
fp = fopen(path, "w+");
if (!fp)
{
printf("fopen failed\n");
return -1;
}
buffer = malloc(BUFFER_SIZE);
if (!buffer)
{
printf("buffer alloc failed\n");
return -1;
}
file_size = get_file_size(path);
printf("file size %ld\n", file_size);
signed_len = file_size;
so_far = 0;
while (so_far < signed_len)
{
size = BUFFER_SIZE;
printf("so far is %lu, signed_len is %lu, size is %lu\n", so_far, signed_len, size);
if (signed_len - so_far < size)
size = signed_len - so_far;
printf("new size is %lu\n", size);
rd_len = fread(buffer, 1, size, fp);
printf("fread rd_len = %ld\n", rd_len);
if ((rd_len != 0) && (rd_len != size))
{
printf("fread failed, rd_len = %ld, size = %ld\n", rd_len, size);
fclose(fp);
free(buffer);
return -2;
}
so_far += size;
printf("fread so_far = %ld\n", so_far);
}
fclose(fp);
free(buffer);
printf("fread big file test end!\n");
return 0;
}
测试结果
文件大小 读取 为 0
sys_stat
后面的调试就不放上来了,说明一个问题:文件获取大小就是 0好吧,我发现了文件系统BUG?读取一下状态,文件大小就变为 0 了?
我多试读取了几个文件,文件大小真的变为了0,包括 /lib/libc.so
这个默认文件
我在板子上试了一下,读取了一下文件系统中的核心文件: rtthread.bin
,哪想到,板子启动不了,看了固件被【真正】清零0
"w+"
,就是这个问题以上记录,其实就是 fopen 参数的使用方法的一个记录,写这么多,就是增加【印象】,得到【教训】,防止编写此类BUG 的事情不再重复犯
获取知识途径很多,有时候有些 BUG的出现,会针对性的让你获取更多,嵌入式开发,除了博闻强记,更重要的,就是有个【烂笔头】记录点点滴滴。