编译后的独立Cython可执行文件是否仍包含所有原始源代码?

时间:2018-11-18 08:47:17

标签: python compilation cython

我正在试验Cython和代码混淆的可能性(article)。在该文章中特别指出:

  

编译完成后,无法将已编译的库反向还原为可读的Python源代码!

我使用此question信息在独立的可执行文件中编译我的代码。 根据我的理解,正如文章1所述,Cython通过Python库的相应调用将Python代码转换为C代码(这是正确的吗?)。在其他版本中,我们只有C文件作为输出,并且无法像.pyc文件一样反编译。

我的测试代码非常简单:

def my_crashing_function():
    x = "1"
    y = 2
    test = x + y  # we will crash here

if __name__ == "__main__":
    my_crashing_function()

但是当我运行此可执行文件时(在cython --embed -o test.c main.pygcc -Os -I /usr/include/python3.5m -o test test.c -lpython3.5m -lpthread -lm -lutil -ldl -s之后) 我收到这样的错误:

user@debian:~# ./hello 
Traceback (most recent call last):
  File "main.py", line 7, in init main
   my_crashing_function()
  File "main.py", line 4, in main.my_crashing_function
   test = x + y  # we will crash here
TypeError: Can't convert 'int' object to str implicitly

如您所见,我们具有所有方法名称,正确的变量名称和行的追溯,甚至包含原始源代码注释。如果我们重命名变量或更改注释-在回溯中也将对其进行更改。 我不明白回溯如何显示所有这些信息。仅当完整的源代码也存储在可执行文件中时,它才能以这种方式工作。 请向我解释,我哪里错了?

更新。在我的情况下,追溯是从原始.py文件生成的。该文件与已编译的可执行文件位于同一文件夹中,仅由于这个原因,我在追溯中获得了所有源代码和注释。删除原始.py文件后,回溯将仅包含异常类型和行号,而没有其他信息。

1 个答案:

答案 0 :(得分:3)

否,它不嵌入代码。它依赖于能够找到FileChannel.position()文件-如果您移动该文件,则将获得回溯但没有原始代码。

如果检查生成的C源代码,您会发现错误处理例程经过.pyx,然后经过__Pyx_AddTraceback,这将创建链接到您的__Pyx_CreateCodeObjectForTraceback的{​​{3}}源文件。

在某些情况下(虽然不确定),它会链接到您的.pyx文件。但是,将应用相同的规则-如果找不到源,它将不会显示该行。


即使没有.pyx文件,您仍将获得有用的方法名称回溯-这些名称保留在已编译的可执行文件中。