Содержит ли скомпилированный автономный исполняемый файл Cython весь исходный код?
Я экспериментирую с Cython и возможностями обфускации кода ( статья). В этой статье особо отмечено:
Когда компиляция завершена, нет возможности вернуть обратно скомпилированные библиотеки обратно в читаемый исходный код Python!
Я использую эту информацию о вопросе, чтобы скомпилировать мой код в автономный исполняемый файл. В моем понимании и, как упоминалось в статье 1, Cython переводит код Python в код C с соответствующими вызовами библиотеки Python (это правильно?). В других случаях у нас есть только 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.py
а также gcc -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
Как видите, у нас есть трассировка со всеми именами методов, правильными именами переменных и строками, даже с оригинальными комментариями исходного кода. Если мы переименуем переменную или изменим комментарий - он также будет изменен при трассировке. Я не понимаю, как traceback может отображать всю эту информацию. Это может работать таким образом, только если полный исходный код также хранится в исполняемом файле. Пожалуйста, объясните мне, где я не прав?
Обновить. Traceback в моей ситуации был сгенерирован из оригинального.py файла. Этот файл находился в той же папке, что и скомпилированный исполняемый файл, и только благодаря этому я получил весь исходный код и комментарии в traceback. После удаления оригинального.py файла traceback будет содержать только тип исключения и номера строк, без другой информации.
1 ответ
Нет, он не встраивает код. Это зависит от возможности найти .pyx
файл - если вы переместите этот файл, вы получите трассировку, но без исходного кода.
Если вы изучите сгенерированный источник C, то обнаружите, что процедура обработки ошибок проходит __Pyx_AddTraceback
, затем __Pyx_CreateCodeObjectForTraceback
, который создает PyCodeObject
связано с вашим .pyx
исходный файл.
При некоторых обстоятельствах (я не уверен, что, хотя) он ссылается на ваш .c
файл вместо. Однако будут применяться те же правила - если он не может найти источник, он не покажет эту строку.
Даже без файла.pyx вы все равно получите трассировку с полезными именами методов - они сохраняются в скомпилированном исполняемом файле.