常见问题

当出现问题的时候,首先使用下面的方式运行以得到更多的错误信息:

python -d pyarmor.py ...
PYTHONDEBUG=y pyarmor ...

Segment fault

下面的情况都会导致导致程序崩溃

  • 使用调试版本的 Python 来运行加密脚本
  • 使用 Python 2.6 加密脚本,但是却使用 Python 2.7 来运行加密脚本

Could not find _pytransform

通常情况下动态库 _pytransform 和加密脚本在相同的目录下:

  • _pytransform.so in Linux
  • _pytransform.dll in Windows
  • _pytransform.dylib in MacOS

首先检查文件是否存在。如果文件存在:

  • 检查文件权限是否正确。如果没有执行权限,在 Windows 系统会报错:

    [Error 5] Access is denied
    
  • 检查 ctypes 是否可以直接装载 _pytransform:

    from pytransform import _load_library
    m = _load_library(path='/path/to/dist')
    
  • 如果上面的语句执行失败,尝试在 引导代码 中设置运行时刻路径:

    from pytransform import pyarmor_runtime
    pyarmor_runtime('/path/to/dist')
    

如果还是有问题,那么请报告 issue

The license.lic generated doesn't work

通常情况下是因为加密脚本使用的密钥箱和生成许可文件时候使用的密钥箱不一 样,例如在试用版本加密脚本,但是在正式版本下面生成许可文件。

通用的解决方法就是重新把加密脚本生成一下,然后在重新生成许可文件。

NameError: name '__pyarmor__' is not defined

原因是 引导代码 没有被执行。

当使用模块 subprocess 或者 multiprocessing , 调用 Popen 或者 Process 创建新的进程的时候,确保 引导代码 在新进程中也得到执 行。否则新进程是无法使用加密脚本的。

Marshal loads failed when running xxx.py

当出现这个问题,依次进行下面的检查

  1. 检查运行加密脚本的 Python 的版本和加密脚本的 Python 版本是否一致
  2. 尝试移动全局密钥箱 ~/.pyarmor_capsule.zip 到其他任何目录,然后重 新加密脚本
  3. 确保生成许可使用的密钥箱和加密脚本使用的密钥箱是相同的(当运行 PyArmor 的命令时,该命令使用的密钥箱的文件名称会显示在控制台)

_pytransform can not be loaded twice

如果 引导代码 被执行两次,就会报这个错误。通常的情况下,是因为 在加密模块中插入了 引导代码 。 因为引导代码在主脚本已经执行过, 所以导入这样的加密模块就出现了问题。

注解

这个限制是从 PyArmor 5.1 引入的,并且在 PyArmor 5.3.5 中已经移除, 之后的版本都没有这个限制。

Check restrict mode failed

违反了加密脚本的使用约束,默认情况下,加密脚本是不能被进行任何修改的。 更多信息参考 约束模式

如果使用 pack 命令去打包加密后的脚本,也会出现这个错误提示。命令 pack 正确的使用方式是直接打包原始的脚本。

Protection Fault: unexpected xxx

违反了加密脚本的使用约束,默认情况下,下列文件不能进行任何修改:

  • pytransform.py
  • _pytransform.so/.dll/.dylib

更多信息参考 对主脚本的特殊处理

Warning: code object xxxx isn't wrapped

这是因为函数中包含特殊情况的跳转指令而引起的,例如,某一个函数编译成为 byte code 之后如果有类似这样的一条指令 JMP 255

在加密之前,这条指令占用两个字节。而在加密之后,因为在函数头部插入了额 外的指令,这个跳转指令的操作数变成了 267 。在 Python3.6 之后,这条指 令需要 4 个字节:

EXTEND 1
JMP 11

遇到这种情况,目前 PyArmor 就不会加密这个函数, 并显示这个警告信息。当 然,只是这个函数没有被加密,当前模块中的其他函数还是被正常加密的。

如果想要避免这个问题,可以尝试在函数里面增加一些冗余的语句,让跳转长度 不要在临界值即可。

后面的版本会考虑解决这个问题,因为一旦修改原来的指令长度,代码块所有的 相对跳转、绝对跳转指令都需要调整,情况比较复杂,所以遇到这种情况,暂时 忽略了。

Error: Try to run unauthorized function

试图使用没有授权的功能。出现这个问题一般是当前目录下面存在 license.lic`或者 `pytransform.key 而导致的认证问题,解决方案是一是删 除这些不必要文件,或者升级到 PyArmor 5.4.5 以后的版本。

在 Linux 下面无法获取硬盘序列号

获取硬盘序列号需要超级用户权限,首先确认有相关权限。

其次检查一下目录 /dev/disk/by-id ,这里会列出已经挂载的硬盘的接口和 序列号。如果这里没有文件,那么是无法获取硬盘序列号信息的。在 Docker 环 境里面的话,确保运行 docker 的时候挂载硬盘设备。

目前支持的硬盘接口包括 IDE,SCSI 以及 NVME 固态硬盘,对于其他接口的尚 不支持。

运行脚本时候提示 Check license failed: Invalid input package.

检查当前目录下面是否有存在文件 license.lic 或者 pytransform.key , 如果存在的话,确保它们是加密脚本对应的运行时刻文件。

加密脚本会首先在当前目录查看是否存在 license.lic 和运行时刻文件 pytransform.key, 如果存在,那么使用当前目录下面的这些文件。

其次加密脚本会查看运行时刻模块 pytransform.py 所在的目录,看看有没有 license.licpytransform.key

如果当前目录下面存在任何一个文件,但是和加密脚本对应的运行时刻文件不匹 配,就会报这个错误。