最近经常编译许多不同版本的V8,用来做漏洞复现和研究学习,但是由于python和jinjia版本较高,经常出现同一个报错,这里写个通用解决方式。
报错信息
基本报错如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| ninja: Entering directory `out/x64_9.5.172.21.release' [209/1834] ACTION //src/inspector:protocol_generated_sources(//build/toolchain/linux:clang_x64) FAILED: gen/src/inspector/protocol/Forward.h gen/src/inspector/protocol/Protocol.cpp gen/src/inspector/protocol/Protocol.h gen/src/inspector/protocol/Console.cpp gen/src/inspector/protocol/Console.h gen/src/inspector/protocol/Debugger.cpp gen/src/inspector/protocol/Debugger.h gen/src/inspector/protocol/HeapProfiler.cpp gen/src/inspector/protocol/HeapProfiler.h gen/src/inspector/protocol/Profiler.cpp gen/src/inspector/protocol/Profiler.h gen/src/inspector/protocol/Runtime.cpp gen/src/inspector/protocol/Runtime.h gen/src/inspector/protocol/Schema.cpp gen/src/inspector/protocol/Schema.h gen/include/inspector/Debugger.h gen/include/inspector/Runtime.h gen/include/inspector/Schema.h python3 ../../third_party/inspector_protocol/code_generator.py --jinja_dir ../../third_party/ --output_base gen/src/inspector --config ../../src/inspector/inspector_protocol_config.json --inspector_protocol_dir ///third_party/inspector_protocol Traceback (most recent call last): File "/home/loorain/v8/v8/out/x64_9.5.172.21.release/../../third_party/inspector_protocol/code_generator.py", line 702, in <module> main() File "/home/loorain/v8/v8/out/x64_9.5.172.21.release/../../third_party/inspector_protocol/code_generator.py", line 584, in main jinja_env = initialize_jinja_env(jinja_dir, config.protocol.output, config) File "/home/loorain/v8/v8/out/x64_9.5.172.21.release/../../third_party/inspector_protocol/code_generator.py", line 190, in initialize_jinja_env import jinja2 File "/home/loorain/v8/v8/third_party/jinja2/__init__.py", line 33, in <module> from jinja2.environment import Environment, Template File "/home/loorain/v8/v8/third_party/jinja2/environment.py", line 16, in <module> from jinja2.defaults import BLOCK_START_STRING, \ File "/home/loorain/v8/v8/third_party/jinja2/defaults.py", line 32, in <module> from jinja2.tests import TESTS as DEFAULT_TESTS File "/home/loorain/v8/v8/third_party/jinja2/tests.py", line 13, in <module> from collections import Mapping ImportError: cannot import name 'Mapping' from 'collections' (/usr/lib/python3.10/collections/__init__.py) [226/1834] CXX obj/torque_base/implementation-visitor.o ninja: build stopped: subcommand failed.
|
主要问题就是**ImportError: cannot import name 'Mapping' from 'collections'
**,查询资料可以确定问题主要是py版本导致的问题。
这个问题是由于 jinja2
模块在 Python 3.10 中无法正常导入 Mapping
类导致的。Python 3.10 已将 Mapping
类从 collections
模块移到了 collections.abc
模块,而你的代码可能是基于较早版本的 Python,仍然从 collections
中导入 Mapping
。
解决方法
方法一
问题主要是因为python版本较高导致的,因此编译时选用低于python3.10的python进行编译,就能解决。最好使用3.9或更早的小版本。
方法二
虽然换版本可以解决,不过像我这种懒人很讨厌配多个环境,所以可以手动更改v8代码。
这里我写了两个脚本,一个用于编译前更改代码,一个用于编译后恢复代码
更改 jinja2
的 collections
引用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #!/bin/bash
JINJA2_TESTS_PY="/home/loorain/v8/v8/third_party/jinja2/tests.py"
if [ ! -f "$JINJA2_TESTS_PY" ]; then echo "文件 $JINJA2_TESTS_PY 不存在。请检查路径是否正确。" exit 1 fi
cp "$JINJA2_TESTS_PY" "$JINJA2_TESTS_PY.bak" echo "已备份文件为 $JINJA2_TESTS_PY.bak"
sed -i 's/from collections import Mapping/from collections.abc import Mapping/' "$JINJA2_TESTS_PY" echo "已修改 $JINJA2_TESTS_PY 文件,将 'from collections import Mapping' 替换为 'from collections.abc import Mapping'"
|
恢复 jinja2
的原始 collections
引用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| #!/bin/bash
JINJA2_TESTS_PY="/home/loorain/v8/v8/third_party/jinja2/tests.py" JINJA2_TESTS_PY_BAK="$JINJA2_TESTS_PY.bak"
if [ ! -f "$JINJA2_TESTS_PY_BAK" ]; then echo "备份文件 $JINJA2_TESTS_PY_BAK 不存在。无法恢复。" exit 1 fi
cp "$JINJA2_TESTS_PY_BAK" "$JINJA2_TESTS_PY" echo "已恢复 $JINJA2_TESTS_PY 文件为备份版本"
rm "$JINJA2_TESTS_PY_BAK" echo "已删除备份文件 $JINJA2_TESTS_PY_BAK"
|