GNU/Linux上有哪些WONTFIX的错误,以及如何解决它们?

21

Linux和GNU用户空间(glibc)似乎存在一些“WONTFIX”错误,即尽管明显违反ISO C和/或POSIX的要求,负责方宣布不愿意修复这些错误。但我不知道有哪些资源为程序员列出这些错误和解决建议。

以下是我能想到的几个:

  • Linux UDP select 错误:在未确认校验和的情况下,select(以及相关接口)会标记UDP套接字文件描述符已准备好读取,只要收到数据包就会立即发生。在后续的recv/read/等调用中,如果校验和无效,则调用将阻塞。解决此问题需要始终将UDP套接字设置为非阻塞模式,并处理EWOULDBLOCK条件。如果我没记错,MaraDNS是最早受到此bug影响并且第一个抱怨(未成功)要求修复它的知名项目。注意:正如Martin v. Löwis指出的那样,显然这个bug已经被修复了。只有当您需要支持真正过时的Linux版本时才需要工作区。
  • GNU C库中的printf系列错误:当指定了字段精度(如%.3s)时,printf系列在处理%s参数时错误地将其视为多字节字符字符串而不是字节字符串,可能会导致截断的输出。我不知道除了替换整个printf子系统之外是否有解决方法(或者只是不使用带有非多字节字符字节字符串的printf函数族,但如果要在UTF-8语言环境中处理遗留代码页字符串,这可能会有问题)。
  • 某些系统调用的错误errno结果代码不正确(我记不清是哪些了)。如果您只阅读GNU / Linux man页面并将其与标准进行比较,通常很容易检查这些内容。(我找不到此内容的参考资料,也许我是错的。我能找到的最接近的问题是ENOTSUPEOPNOTSUP具有相同的值; 请参见PDTR 24715。)
  • 还有哪些错误和解决方法可以添加到这个列表中? 我提问的目的是:

    1. 构建更完整的此类错误列表,以便新手和经验丰富的程序员都能快速了解在GNU / Linux上运行预期可移植程序时可能出现的潜在问题。
    2. 利用SO集体智慧,想出尽可能多此类错误的 clever 和无障碍标准解决方法,而不是每个人在被刺伤后都必须发明自己的解决方法,并可能以次优,丑陋或hackish的方式实现 - 更糟糕的是,以破坏对更符合规范的系统的支持的方式实现。

    7
    请投票关闭的人解释一下。我不明白这怎么可能是离题的,因为我问的是明显与编程有关的解决方法。我承认这可能有点争议性,这可能是提出关闭建议的另一个原因,但如果重点是积极寻找处理这些问题的无障碍方式而不仅仅是责备他人,我认为这是一个值得探讨的问题。 - R.. GitHub STOP HELPING ICE
    3
    什么是“bugs”?如果Linux不符合标准,显然是标准有问题。 - Franci Penov
    5
    SO需要为评论提供独立的+1有趣和+1信息丰富的投票... :-) - R.. GitHub STOP HELPING ICE
    2
    这似乎是社区维基的一个好候选者。 - Ape-inago
    10
    我不确定这个问题是否适合在SO系统中提问。它相当广泛、有些主观,而且没有办法说哪个答案比其他答案更好或更差。SO并不适合收集“X列表”。关于第一个点,关于开发漏洞列表,Wiki或者Bug跟踪器比SO更适合。至于利用“SO的智慧”来找到解决方法,最好每个漏洞都有一个单独的问题,这样解决方法就可以被投票和接受了,而不是试图把漏洞及其解决方法塞进答案和/或评论中。 - Brian Campbell
    显示剩余7条评论
    2个回答

    5

    我无法重现你所声称的printf问题。运行程序

    #include <stdio.h>
    #include <locale.h>
    
    int main()
    {
            setlocale(LC_ALL, "");
            printf("%.4s\n", "Löwis");
            return 0;
    }
    

    在de_DE.UTF-8语言环境下,打印“Löw”看起来正确:我请求4个字节,并得到了4个字节(ö是2个字节)。如果库计算多字节字符,则输出应为“Löwi”。这是使用glibc 2.11.2实现的。
    编辑:将字符串更改为“%.2s\n”将只打印“L”,即仅一个字节。但是,这符合规范the specification,其中说:
    如果指定了精度,则不应写入超过该数量的字节。
    (强调是我的),然后
    不得写入部分字符。
    因此,由于打印两个字节(即L和ö的前导字节)将导致写入部分字符,因此打印不完整的UTF-8将是不符合规范的。

    3
    把它改成"xxxö",你会发现只得到了3个字节。这是一个愚蠢的例子,但一个真实的例子是,如果你想要处理多种不同编码的字符串,而这些编码与本地设置的编码不匹配。ISO C允许这样做(因为%s纯粹是按字节指定的),但glibc禁止这样做。总之,我不想争论这些问题是否是错误。它们已经被熟练的人员充分记录。我正在寻求建立问题和解决方法列表。 - R.. GitHub STOP HELPING ICE
    1
    或者将格式字符串更改为"%.2s"以查看错误。 - R.. GitHub STOP HELPING ICE
    1
    @R..:如果你对构建错误列表和解决方案感兴趣,那么你应该相应地从列表中删除那些事实上不是错误的东西。声称某些事情是错误的,而实际上并非如此,这是主观的并且容易引发争议。 - Martin v. Löwis
    1
    @Martin:关于你的编辑,你正在阅读关于%ls格式说明符的文本。 "绝不应该编写部分字符"是指将wchar_t字符串转换为多字节字符串时会发生什么。关于纯 %s: "将从数组中写入字节,直到(但不包括)任何终止空字节"。请注意 应该写入。没有根据语义解释排除某些字符的选项。 - R.. GitHub STOP HELPING ICE
    在 http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf 的解释副本中,我找不到任何关于 %s 的讨论。 - Martin v. Löwis
    显示剩余6条评论

    4

    我不相信UDP问题确实存在。在当前的Linux内核中,udp_poll会读取

    /**
     *      udp_poll - wait for a UDP event.
     *      @file - file struct
     *      @sock - socket
     *      @wait - poll table
     *
     *      This is same as datagram poll, except for the special case of
     *      blocking sockets. If application is using a blocking fd
     *      and a packet with checksum error is in the queue;
     *      then it could get return from select indicating data available
     *      but then block when reading it. Add special case code
     *      to work around these arguably broken applications.
     */
    unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait)
    {
            unsigned int mask = datagram_poll(file, sock, wait);
            struct sock *sk = sock->sk;
    
            /* Check for false positives due to checksum errors */
            if ((mask & POLLRDNORM) && !(file->f_flags & O_NONBLOCK) &&
                !(sk->sk_shutdown & RCV_SHUTDOWN) && !first_packet_length(sk))
                    mask &= ~(POLLIN | POLLRDNORM);
    
            return mask;
    
    }
    

    据我所知,它似乎隐藏了具有错误校验和的UDP数据包,以防止其通过select/poll报告。自从2009年的版本85584672开始使用这个代码版本。但即使在此之前(至少从2005年开始),该代码显然已经在select/poll中删除了错误的数据包。


    不错的发现!但你关注的是他的例子,而不是他实际的问题:如何解决这些错误。逐个追踪每个例子来证明它们不是错误只会导致他提出更多的例子。 - Konerak
    3
    但这篇文章的宣称目标就是发现具体问题并发布具体解决方法。所以对于前两个问题,事实证明不需要任何解决方法(至少在当前版本中是如此)。因此,任何认为这些是实际问题的人都会得到帮助,因为他们知道这些并不是问题。如果有真正的漏洞被提出,我们可以开始讨论解决方法。 - Martin v. Löwis
    你说得对。我将它列为"WONTFIX",因为它最初就是这样的。显然有足够多的人抱怨(或者内核内部发生了足够多的变化,以至于修复变得容易),实际上已经被修复了。感谢你的发现。至于另一个问题,你误读了标准。 - R.. GitHub STOP HELPING ICE

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