简体   繁体   English

构建CPython时禁用编译器优化

[英]Disabling Compiler Optimizations when Building CPython

I've been following along with Philip Guo's excellent series about CPython's internals and have been walking through the interpreter's code with GDB. 我一直在跟着Philip Guo关于CPython内部的出色系列 ,并一直在GDB中浏览解释器的代码。 Unfortunately, GDB seems to skip around quite a bit when I step through the code, executing instructions out of order (a series of assignment operations for example, nothing fancy). 不幸的是,当我单步执行代码,不按顺序执行指令(例如一系列赋值操作,没什么花哨的东西)时,GDB似乎跳了很多。

From what I understand, this is because of compiler optimizations. 据我了解,这是由于编译器的优化。 Indeed, CPython's configure file seems to default to -O2 . 实际上,CPython的configure文件似乎默认为-O2 This is shown to be the case when compiling Python 2.7.15 with ./configure and make : 使用./configuremake编译Python 2.7.15时,情况就是这样./configure

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
...

I tried fixing this by configuring without optimizations via ./configure CFLAGS="-g -O0" and compiling with make again, which works (note the change from -fno-strict-aliasing -g -O2 to -fno-strict-aliasing -g -O0 on each line): 我尝试通过不通过./configure CFLAGS="-g -O0"进行优化而进行./configure CFLAGS="-g -O0"make再次使用make编译, 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
...

Unfortunately, GDB still jumps around when I step through the code. 不幸的是,当我单步执行代码时,GDB仍然跳来跳去。 For completeness, here's the command I'm running with GDB: 为了完整起见,这是我与GDB一起运行的命令:

gdb --args ./python test.py

The contents of test.py are just some basic arithmetic and print functions, which isn't really relevant. test.py的内容只是一些基本的算术和打印功能,实际上并不相关。

My understanding of at least one of these steps must be incomplete. 我对这些步骤中至少一个的理解必须是不完整的。 Am I setting the optimization flag incorrectly? 我是否将优化标志设置不正确? Is GDB jumping between instructions due to some other reason? GDB是否由于其他原因在指令之间跳转? Any advice would be greatly appreciated. 任何建议将不胜感激。 Thanks! 谢谢!

tl;dr: You want the configure setting --with-pydebug . tl; dr:您需要configure设置--with-pydebug

You've got an -O3 on the command line that comes after the -O2 , so changing the -O2 to -O0 doesn't do any good; -O2之后的命令行上有-O3 ,因此将-O2更改为-O0并没有任何好处。 the -O3 still overrides it. -O3仍然会覆盖它。 You need to figure out where the -O3 is coming from and remove it. 您需要找出-O3的来源并将其删除。

If you look at the generated Makefile , you should see something like this: 如果查看生成的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)

You can, of course, just edit the generated Makefile to change the -O3 to -O0 . 当然,您可以编辑生成的Makefile来将-O3更改为-O0 But if you look inside the configure script and Makefile.pre , you can see where this comes from: it's the default value, only replaced in this case: 但是,如果您查看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
    ;;

This also sets the right flags for other compilers besides gcc . 这也为gcc以外的其他编译器设置了正确的标志。

However, the main effect of --with-pydebug is to enable Py_DEBUG —which you probably want if you're source-debugging CPython, but it is a separate thing from -O0 , which is what you were actually asking about. 但是,-- --with-pydebug的主要作用是启用Py_DEBUG -如果要对CPython进行源代码调试,则可能Py_DEBUG ,但这与-O0是分开的,而这实际上是您要问的。 So, if you want only -O0 , as far as I know, the only thing you can do is edit the Makefile (or come up with some complicated set of env variables and configure arguments that tricks it into doing a debug build but then not enabling Py_DEBUG ). 因此,据我所知,如果只想使用 -O0 ,那么您唯一可以做的就是编辑Makefile (或提供一些复杂的env变量并configure引诱它进行调试构建的参数,但是不这样做启用Py_DEBUG )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM