加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

Windows上的奇怪Python错误,在调试器下工作

发布时间:2020-12-14 01:35:18 所属栏目:Windows 来源:网络整理
导读:下面的代码意外地引发了一个异常:pywintypes.error:(6,’GetFileInformationByHandle’,’句柄无效.’),即GetFileInformationByHandle不起作用. 奇怪的是,在Python调试器下一切正常.更奇怪的是,当我删除some_parameter或GetFileInformationByHandle时,错误
下面的代码意外地引发了一个异常:pywintypes.error:(6,’GetFileInformationByHandle’,’句柄无效.’),即GetFileInformationByHandle不起作用.

奇怪的是,在Python调试器下一切正常.更奇怪的是,当我删除some_parameter或GetFileInformationByHandle时,错误消失了.这告诉我,也许是一些内存错误,但我真的不知所措.

有些代码可能看起来没必要,但我不能在不引起异常的情况下缩小代码.

我已经在Windows 7上的Python 3.4.1 x64,pywin32 218.5和219上测试了这个.

import os
import win32file
import pywintypes
from ctypes import *
from ctypes.wintypes import *


class BY_HANDLE_FILE_INFORMATION(Structure):
    _fields_ = [
        ('dwFileAttributes',DWORD),('ftCreationTime',FILETIME),('ftLastAccessTime',('ftLastWriteTime',('dwVolumeSerialNumber',('nFileSizeHigh',('nFileSizeLow',('nNumberOfLinks',('nFileIndexHigh',('nFileIndexLow',]


def GetFileInformationByHandle2(handle):
    GetFileInformationByHandle(handle)


def GetFileInformationByHandle(handle):
    bhfi = BY_HANDLE_FILE_INFORMATION()
    res = windll.kernelbase.GetFileInformationByHandle(handle.handle,byref(bhfi))
    if res == 0:
        errno = GetLastError()
        raise pywintypes.error(errno,'GetFileInformationByHandle',FormatError(errno))


def open_file(path,param_1=False):
    return win32file.CreateFile(path,win32file.GENERIC_READ,None,win32file.OPEN_EXISTING,None)


def main():
    path = 'test.bin'
    open(path,'wb').close()
    h_file = open_file(path)
    GetFileInformationByHandle(h_file)
    win32file.CloseHandle(h_file)
    h_file = open_file(path)
    GetFileInformationByHandle2(h_file)
    win32file.CloseHandle(h_file)
    os.remove(path)


if __name__ == '__main__':
    main()

解决方法

这让我在windbg下付出了很多努力来找出原因.

问题是windll.kernelbase.GetFileInformationByHandle的第一个句柄参数是作为DWORD而不是QWORD传递的.奇怪的错误可能是由修改rcx的前4个字节的附加代码引起的,这是x64调用约定中的第一个参数.

我在这里留下这个答案供我自己参考,以防其他人发现这个有用.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读