【发布时间】:2014-10-03 04:32:11
【问题描述】:
我的应用在系统 A 上运行良好,但在系统 B 上出现段错误。
系统 A(Hyper-V 虚拟机)
- Linux System_A 2.6.32-5-686 #1 SMP 2014 年 5 月 13 日星期二 16:33:32 UTC i686 GNU/Linux
- gcc 版本 4.4.5 (Debian 4.4.5-8)
- 文件系统:ext3
系统 B(树莓派)
- Linux System_B 3.12.28+ #712 PREEMPT Tue Sep 16 15:49:13 BST 2014 armv6l GNU/Linux
- gcc 版本 4.6.3 (Debian 4.6.3-14+rpi1)
- 文件系统:尝试使用 ext3 和 ext4
该应用程序的目的是跟踪使用inotify 在目录中所做的更改。它将元数据保存到(如果不存在则创建)日志文件。但是,在系统 B 上,它甚至没有那么远。
当我运行程序来监视对目录的更改时,它会在尝试确定正在修改的文件时崩溃。
我已经进行了一些挖掘,似乎没有正确设置文件名指针(我在确定文件是否感兴趣时用作临时文件名持有者)。
变量最初是使用
设置的char *filename;
在我用正在修改的文件名填充它之前,我不会以任何其他方式使用该变量。
当我将事件文件名(正在修改的文件)复制到一个临时变量时,它会出现段错误:
strcpy(filename,event->name);
现在,当我添加一些
printf("ignoring %s \n", event->name);
printf("filename = %s \n", filename);
..在 strcpy 之前,所以我可以看到发生了什么:
在系统 A 上
ignoring .testfile.swp
filename = Hd¤¿Xè|·ðc¤¿ÿÿÿÿô¿~·®
在系统 B 上
ignoring .testfile.swp
filename = (null)
Segmentation fault
在这个阶段我能看到的唯一区别是变量“文件名”可能没有正确初始化。但也许这无关紧要,也许我正在寻找错误的方向。
问题:
我是否需要在使用
strcpy之前“准备”指针,还是应该这样做?两个
gcc版本之间是否存在导致此问题的限制?我只是用gcc worklog.c -o worklog编译是否有办法在发生段错误时获得更多信息性调试输出?
【问题讨论】:
-
你需要用
malloc()分配内存并设置filename指向它。否则,strcpy()应该复制到哪里? -
char *filename;不分配任何存储空间;strcpy(filename, …)通过随机指针复制数据,如果幸运的话,也可以是空指针。未定义的行为——不好,不惜一切代价避免。 -
谢谢,我会试试这个。知道为什么它不会在 System_A 上中断吗?也许不正确,但我多年来一直像这样使用它没有问题..
-
通过 Valgrind 运行你的程序。它可以帮助发现内存错误。
-
你真是太幸运了。未定义的行为意味着任何事情都可能发生。