如何在Linux中调试FUSE文件系统崩溃

16

目前我正在使用Linux(2.6内核)中的FUSE文件系统模块以及C语言开发应用程序。由于某些编程错误,在挂载文件系统后,应用程序会崩溃。由于我是一个Linux/C环境的新手开发人员,你能告诉我可能调试此类程序的选项吗?


你说的“using”是什么意思?你是在尝试基于fuse机制实现一个使用空间文件系统,还是其他什么东西? - Sam Liao
6
FUSE 可能会让调试变得有点棘手。 - Tim Post
@arsane,是的,我正在基于FUSE实现一个用户空间文件系统。 - Hrishi
5个回答

16

FUSE有几个功能可能会使其难以调试:它通常在后台运行(这意味着它与stdin/out分离)并且是多线程的(这可能会引入竞争条件并且使用gdb进行调试更加复杂)。幸运的是,这两个功能都可以被禁用:

  1. 使用 -f 开关来保持应用程序在前台运行。这将使得您的 printf 行起作用。
  2. 使用 -s 开关来禁用多线程。禁用多线程将限制性能,但也会隐藏某些错误(竞争条件),简化使用gdb,并确保printf输出可读性 (当多个线程同时调用printf时,它们的输出可能会混淆)。

我还建议阅读Geoff Kuenning的FUSE文档


谢谢你提供的指针。就我所看到的,这是最有帮助的答案。 - class stacker

8

使用-d选项运行您的熔断器客户端。


6

首先,请确保您使用调试符号编译 (-g选项用于gcc)。在运行程序之前,使用shell命令启用核心转储:

ulimit -c unlimited

当应用程序崩溃时,它会在当前工作目录中留下一个core文件(只要它可以写入该文件)。

然后,您可以在gdb调试器中加载核心文件:

gdb <executable file> <core file>

...它会显示程序崩溃的位置,并让您检查变量等内容。


2

您可以使用Valgrind与FUSE一起使用,但是请先阅读此文以了解关于setuid的解决方法。为方便其他需要调试我的文件系统的人,我实际上执行以下操作:

#include <valgrind/valgrind.h>

if (RUNNING_ON_VALGRIND) {
    fprintf(stderr,
        "******** Valgrind has been detected by %s\n"
        "******** If you have difficulties getting %s to work under"
        " Valgrind,\n"
        "******** see the following thread:\n"
        "******** http://www.nabble.com/valgrind-and-fuse-file-systems"
        "-td13112112.html\n"
        "******** Sleeping for 5 seconds so this doesn't fly by ....",
            progname, progname);
    sleep(5);
    fprintf(stderr, "\n");
}

我经常在FUSE上工作...90%的时间我的崩溃是由于泄漏导致OOM killer采取行动,解除引用错误指针,双重释放等。Valgrind是一个很好的工具来捕捉这些问题。GDB也很有帮助,但我发现Valgrind是不可或缺的。


0

UML非常适合调试Linux内核的通用部分,如文件系统、调度等,但不适用于内核的硬件平台或驱动程序特定部分。

http://www.csee.wvu.edu/~katta/uml/x475.html

http://valerieaurora.org/uml_tips.html

仔细观察图表:

Image result for FUSE filesystem

你会看到应用程序“hello”,它实现了所有的 FUSE 回调处理程序。因此,大部分的调试工作都在用户空间程序中进行,因为 FUSE 内核模块(和 libfuse)通常被用于所有的 FUSE 文件系统。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接