通过Ruby/DL调用OpenProcessToken时出现SEGFULT
请参阅下面的更新 我一直在尝试修复Ruby库跨UAC上下文与另一个程序通信的能力,并且需要创建一个与当前用户具有相同安全属性的共享文件映射。我正在使用Ruby/dl,并试图在Ruby 1.9.3上实现这一点,这就是导致我的问题的原因 调用advapi31中的函数会导致分段错误。您将在下面找到一个导致我的机器出现分段故障的最小示例。我收到的错误文本是,下面是错误文本打印到命令行后出现的错误框的屏幕截图:通过Ruby/DL调用OpenProcessToken时出现SEGFULT,ruby,windows,rubydl,Ruby,Windows,Rubydl,请参阅下面的更新 我一直在尝试修复Ruby库跨UAC上下文与另一个程序通信的能力,并且需要创建一个与当前用户具有相同安全属性的共享文件映射。我正在使用Ruby/dl,并试图在Ruby 1.9.3上实现这一点,这就是导致我的问题的原因 调用advapi31中的函数会导致分段错误。您将在下面找到一个导致我的机器出现分段故障的最小示例。我收到的错误文本是,下面是错误文本打印到命令行后出现的错误框的屏幕截图: require 'dl' require 'dl/import' require 'dl/ty
require 'dl'
require 'dl/import'
require 'dl/types'
module Win
extend DL::Importer
dlload 'kernel32', 'advapi32'
include DL::Win32Types
# args: none
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms683179(v=vs.85).aspx
extern 'HANDLE GetCurrentProcess()'
# args: hProcessHandle, dwDesiredAccess, (out) phNewTokenHandle
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa379295(v=vs.85).aspx
extern 'BOOL OpenProcessToken(HANDLE, DWORD, PHANDLE)'
# args: hObject
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms724211(v=vs.85).aspx
extern 'BOOL CloseHandle(HANDLE)'
# args: none
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms679360(v=vs.85).aspx
extern 'DWORD GetLastError()'
def self.open_process_token
token_handle = DL::CPtr.malloc(DL::SIZEOF_VOIDP, DL::RUBY_FREE)
raise_error_if_zero(OpenProcessToken(Win.GetCurrentProcess, 0x8, token_handle.ref))
raise_error_if_zero(CloseHandle(token_handle))
end
def self.raise_error_if_zero(result)
if result == 0
raise "Windows error: #{Win.GetLastError}"
end
end
end
Win.open_process_token
使现代化
使用RubyInstaller将Ruby更新为1.9.3p545使我能够运行上面提供的示例,但仍然存在问题。我已经创建了一个包含这些文件的要点,当使用1.9.3p545运行时,这些文件会产生一个分段错误,尽管这一次没有解释器变得无响应,也不会产生如上所述的对话框。我已经在我的机器上尝试了这个和下面的,还有一个安装了相同版本Ruby的机器,结果也一样。因为我之前没有提到过,所以我运行的是64位Windows 7 Pro,我测试的另一台计算机也是如此
我注意到一些事情可能暗示了一个更深层次的问题,不一定与OpenProcessToken相关。以下任何一项都可能单独防止SEG故障:
将第3行从runner.rb复制到mwe.rb的底部,并直接运行mwe.rb。
注释掉mwe.rb的第5行或注释掉一些较大的错误子集.rb,例如注释掉第37行到第99行,不会导致任何故障。
注释runner.rb的第3行,实际上只需要其他文件并退出。
从Pageant::Win中注释出以下组合不会导致segfault:
呼叫外部人员
对struct的调用
常数
类方法
在最后一种情况下,没有必要注释掉特定类别的所有项目。例如,如果我注释掉TOKEN_USER和SECURITY_属性,就可以避免segfault。我还可以通过注释掉TOKEN_USER和与IsValidSecurityDescriptor关联的extern语句来防止segfault。我尝试过其他几种组合,它们会产生相同的行为
任何帮助都将不胜感激。此错误不是由ruby造成的,而是由您的代码造成的 在open_process_token方法中,对DL::CPtr类型的变量使用了不适当的方法ref 方法打开\u进程\u令牌
def self.open_process_token
token_handle = DL::CPtr.malloc(DL::SIZEOF_VOIDP, DL::RUBY_FREE)
OpenProcessToken(Win.GetCurrentProcess, 0x8, token_handle.ref)
end
应该是
def self.open_process_token
ptoken_handle = DL::CPtr.malloc(DL::SIZEOF_VOIDP, DL::RUBY_FREE)
OpenProcessToken(Win.GetCurrentProcess, 0x8, ptoken_handle)
token_handle = ptoken_handle.ptr.to_i
end
感谢您的支持,这不是问题