【问题标题】:Why a not-threaded Perl is not using off64_t type compared to a threads-enabled one?为什么与启用线程的 Perl 相比,非线程 Perl 不使用 off64_t 类型?
【发布时间】:2024-01-21 14:09:01
【问题描述】:

我最初的任务是安装 mod_perl 2.0.6 + Apache 2.2.22。
编译 mod_perl 时,该进程因出现与 off64_t 相关的大量错误而停止。于是,我开始深入挖掘。首先,我安装了两个新的 Perl 5.8.9 实例(因为我必须使用这个版本):一个线程版本和一个非线程版本(它们是相同的,只有 usethreads 不同)。尝试使用线程化 Perl 重现相同的内容并成功完成,并且完全没有 off64_t 错误。
结论很明显:线程化的 Perl 提供了必要的off64_t,而非线程化的则没有。
进一步搜索,我比较了两个 Perl 的 config.h(来自 core/<arch>/CORE),在第 3671 行我可以看到这个(在非线程 Perl 中):

    /* HAS_OFF64_T:
     *      This symbol will be defined if the C compiler supports off64_t.
     */
    /*#define       HAS_OFF64_T             / **/

在启用线程的 Perl 中:

    #define HAS_OFF64_T            /**/

perl -V 对于两个 Perl 实例都将 ccflags ='... -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 ...' 报告为使用的编译器标志。

据我了解,off64_t 用于大文件,与线程无关。我找到了关于off_toff64_t 的信息:

如果源代码使用_FILE_OFFSET_BITS = 64 编译,则此类型(即off_t)透明地替换为off64_t

简短地说:有 2 个相同的 Perl 构建,只有一个区别:usethreads 配置参数。线程化的 Perl 启用 off64_t,非线程化的则不启用。

我的问题是:为什么会发生这种情况以及线程如何连接到应该用于大文件而不是线程的 off64_t 数据类型

信息:Arch Linux OS 32 位(内核 2.6.33)、gcc 4.5.0、libc 2.11.1、标准 Perl 5.8.9

注意:off64_t 在第 15526 行的Configure 中处理,生成一个简单的try.c 并尝试编译。问题是为什么非线程 Perl 不能编译它而线程 Perl 可以。

【问题讨论】:

  • 请说明发行版和架构
  • 尝试使用 5.14.2 编译,该错误可能已经修复,因为 Linux 上的构建错误很容易被发现。 5.8.9 不再是 not supported。我看到你有相当现代的 GCC、httpd 和 mod_perl 版本,坚持使用 Perl 是没有意义的,因为没有人可能会产生解决方法或错误修复。
  • @daxim,我知道 5.8.9 不再受支持,应该使用 5.14,但我必须使用非线程 5.8.9,这就是为什么这个特殊问题影响我的原因。我只是想找出那里发生了什么以及为什么会发生这种情况。但为了完整起见,我也会尝试 5.14 并比较两个版本。
  • @daxim 为了完整起见,我还安装了一个新的非线程 (-Uusethreads) Perl v5.14.2,它具有与 off64_t 完全相同的行为和相同的错误与 Apache 结合使用时变为 apr_off_t 错误。 config.h 包含相同的 #define HAS_OFF64_T 行注释(以及很多其他行,与线程版本相比)

标签: multithreading perl compilation large-files


【解决方案1】:

我不确定回答我自己的问题是否是一种可接受的行为,但当我在寻找解决方案而不是等待其他人完成我的作业时,我认为它会是对阅读本文的其他人有用。

简而言之,我的问题的答案是 -D_GNU_SOURCE gcc 编译器标志,似乎线程与 off64_t 类型没有任何共同之处。

看来-Dusethreads用于Configure时,使用hints/linux.sh并执行如下代码:

case "$usethreads" in
$define|true|[yY]*)
    ccflags="-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS $ccflags"

然后代码使用定义的_GNU_SOURCE 编译,这允许使用很多东西(就像在这些线程中回答的那样:What does “#define _GNU_SOURCE” imply?)。

当 Perl 在不支持线程的情况下构建时,这些标志将被跳过,并且头文件中的许多位仍然被注释。
似乎 Perl 本身不受此影响。甚至旧版本的 Apache 也没有,但 Apache 2.2+ 开始使用由_GNU_SOURCE 启用的代码,并且构建mod_perl 并不像以前那么简单。

我不知道谁应该注意到这件事。也许核心 Perl 维护者自己,也许 Apache 维护者,也许没有人,这只是我的特殊情况或编译器问题。

结论:在构建非线程 Perl 时,_GNU_SOURCE 未被使用,因此 Perl .h 文件有很多注释 #defines 并且针对 Apache 2.2+ 源构建 mod_perl 失败。构建 Perl 时应添加额外的 -Accflags='-D_GNU_SOURCE'

也欢迎其他答案。也许我错了,或者我只是看到了冰山一角

【讨论】:

    最近更新 更多