生成CPython时禁用编译器优化

2024-06-16 13:11:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在关注philipguo的excellent series关于CPython的内部结构,并且一直在用GDB浏览解释器的代码。不幸的是,当我单步执行代码时,GDB似乎跳过了很多地方,执行的指令顺序不对(例如,一系列赋值操作,没什么特别的)。你知道吗

据我所知,这是因为编译器优化。实际上,CPython的configure文件似乎默认为-O2。使用./configuremake编译Python 2.7.15时会出现这种情况:

gcc -pthread -c -fno-strict-aliasing -g -O2 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes  -I. -IInclude -I./Include   -DPy_BUILD_CORE -o Modules/python.o ./Modules/python.c
gcc -pthread -c -fno-strict-aliasing -g -O2 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes  -I. -IInclude -I./Include   -DPy_BUILD_CORE -o Parser/acceler.o Parser/acceler.c
gcc -pthread -c -fno-strict-aliasing -g -O2 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes  -I. -IInclude -I./Include   -DPy_BUILD_CORE -o Parser/grammar1.o Parser/grammar1.c
gcc -pthread -c -fno-strict-aliasing -g -O2 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes  -I. -IInclude -I./Include   -DPy_BUILD_CORE -o Parser/listnode.o Parser/listnode.c
...

我尝试通过./configure CFLAGS="-g -O0"在没有优化的情况下进行配置并再次使用make进行编译来解决这个问题,这是可行的(注意每行从-fno-strict-aliasing -g -O2-fno-strict-aliasing -g -O0的变化):

gcc -pthread -c -fno-strict-aliasing -g -O0 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes  -I. -IInclude -I./Include   -DPy_BUILD_CORE -o Modules/python.o ./Modules/python.c
gcc -pthread -c -fno-strict-aliasing -g -O0 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes  -I. -IInclude -I./Include   -DPy_BUILD_CORE -o Parser/acceler.o Parser/acceler.c
gcc -pthread -c -fno-strict-aliasing -g -O0 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes  -I. -IInclude -I./Include   -DPy_BUILD_CORE -o Parser/grammar1.o Parser/grammar1.c
gcc -pthread -c -fno-strict-aliasing -g -O0 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes  -I. -IInclude -I./Include   -DPy_BUILD_CORE -o Parser/listnode.o Parser/listnode.c
...

不幸的是,当我遍历代码时,GDB仍然会跳转。为了完整起见,下面是我用GDB运行的命令:

gdb --args ./python test.py

test.py的内容仅仅是一些基本的算术和打印函数,其实并不相关。你知道吗

我对其中至少一个步骤的理解肯定是不完整的。我是否设置了错误的优化标志?GDB在指令之间跳转是由于其他原因吗?任何建议都将不胜感激。谢谢!你知道吗


Tags: parserincludegccwallstricto3dpyprototypes
1条回答
网友
1楼 · 发布于 2024-06-16 13:11:28
d>:Dr:您想要^ {< CD1>}设置^ {< CD2>}。你知道吗

命令行中有一个-O3-O2之后,因此将-O2更改为-O0没有任何好处;-O3仍然覆盖它。您需要找出-O3来自何处并将其删除。你知道吗

如果您查看生成的Makefile,您应该会看到如下内容:

# Compiler options
OPT=        -DNDEBUG -g -fwrapv -O3 -Wall
# ...
# Avoid assigning CFLAGS, LDFLAGS, etc. so users can use them on the
# command line to append to these values without stomping the pre-set
# values.
PY_CFLAGS=  $(BASECFLAGS) $(OPT) $(CONFIGURE_CFLAGS) $(CFLAGS) $(EXTRA_CFLAGS)

当然,您可以编辑生成的Makefile,将-O3更改为-O0。但是如果您查看configure脚本和Makefile.pre,您可以看到它的来源:它是默认值,仅在本例中被替换:

case $ac_cv_prog_cc_g in
yes)
    if test "$Py_DEBUG" = 'true' ; then
    # Optimization messes up debuggers, so turn it off for
    # debug builds.
            if "$CC" -v  help 2>/dev/null |grep   -Og > /dev/null; then
                OPT="-g -Og -Wall"
            else
                OPT="-g -O0 -Wall"
            fi
    else
    OPT="-g $WRAP -O3 -Wall"
    fi
    ;;

这也为gcc之外的其他编译器设置了正确的标志。你知道吗

然而, with-pydebug的主要作用是启用^{}——如果您是源代码调试CPython的话,您可能需要启用它,但是它与-O0是分开的,而-O0正是您实际需要的。所以,如果你只想-O0,据我所知,你唯一能做的就是编辑Makefile(或者想出一些复杂的env变量和configure参数来欺骗它进行调试构建,然后不启用Py_DEBUG)。你知道吗

相关问题 更多 >