问题描述
我的初始目标是使用 ctypes
在Cygwin上打开 dll
文件。但我发现了一些问题。我挖出 sys.dl
,它只在IPython上返回未知的权限被拒绝
。
python
一切看起来都不错:
$ ls
my.dll
$ python
Python 2.7.8(默认,2014年7月28日,01:34:03)
[GCC 4.8.3] on cygwin
>>>> import dl
>>> dl.open('my.dll')
< dl.dl object at 0xfffaa0c0>
使用 ipython
/ p>
$ ipython
Python 2.7.8(默认,2014年7月28日,01:34:03)
在[1]:import dl
In [2]:dl.open('my.dll')
-------------------- -------------------------------------------------- -----
错误跟踪(最近最后调用)
< ipython-input-2-c681630fa713> in< module>()
----> 1 dl.open('my.dll')
错误:权限被拒绝
我研究这个使用 strace
。 `IPython的输出日志是巨大的,超过4MB。幸运的是,我发现了一些奇怪的事情:
symlink.check(C:\Users \user\Home\projects \foo\my.dll,0x28AB88)(0x4022)
35 2705178 [main] python2.7 16924 path_conv :: check:this-> path(C:\Users \user\Home\\ \\projects\foo\my.dll),has_acls(1)
37 2705215 [main] python2.7 16924 cwdstuff :: get:posix / cygdrive / c / Users / user / Home / projects / foo
32 2705247 [main] python2.7 16924 cwdstuff :: get:(C:\Users\user\Home\projects\foo)= cwdstuff :: get(0x8006ECF0,32768,0,0) ,errno 11
---进程14376,异常c0000138 at 7726163E
3286 2708533 [main] python2.7 16924 seterrno_from_win_error:/home/corinna/src/cygwin/cygwin-1.7.35/cygwin-1.7 .35-1.i686 / src / src / winsup / cygwin / dlfcn.cc:174 Windows错误182
42 2708575 [main] python2.7 16924 geterrno_from_win_error:未知的windows错误182,将errno设置为13
36 2708611 [main] python2.7 16924 dlopen:ret 0x0
谁是 / home / corinna
?我在我的安装中没有corinna用户,在我的Windows上。 Corinna不是从我的安装。是一些硬编码的东西吗?
现在,这是我从 strace
获得的 python
:
symlink.check(C:\Users \user\Home\projects\foo\ my.dll,0x28B728)(0x4022)
26 10440048 [main] python 12604 path_conv :: check:this-> path(C:\Users \user\Home\projects\foo\ my.dll),has_acls(1)
23 10440071 [main] python 12604 cwdstuff :: get:posix / cygdrive / c / Users / user / Home / projects / foo
25 10440096 [main] python 12604 cwdstuff :: get:(C:\Users\user\Home\projects\foo)= cwdstuff :: get(0x8006ECF0,32768,0,0),errno 0
3405 10443501 [main ] python 12604 dlopen:ret 0x5B9C0000
dlopen
在IPython返回0x0,而它返回0x5B9C0000为python。我注意到 cwdstuff :: get
在调用 dlopen
之前产生错误。
EDIT
我向Cygwin的邮件列表和关于这个问题的Corinna的回答是:
我以前的测试使用 ctypes
最初,当我问我的问题,我只是玩 ctypes
。
我正在使用Cygwin 32位和Windows 7.
当我试图加载一个dll使用<$ c时,我有一个 OSError
$ c> cdll.LoadLibrary 。
更多创意:
-
检查访问DLL的用户是否相同。你这样做:
import getpass
print(getpass.getuser())
-
检查当前进程是什么。我没有使用cygwin,但在linux shell可执行文件
strace
应该显示这个。
用法:获取当前进程的PID:import os; os.getpid()
之后,你可以使用命令strace -p< pid> -e file
。此设置完成后,您可以尝试加载DLL。
-e file
标志应该写得很像。文件
告诉strace报告进程所做的所有文件操作。如果在python / ipython上运行时没有出现差异,你可以尝试删除 -e文件
标志,然后你会看到所有的系统调用, t在这样的窗口上工作,所以这可能不工作,但在linux至少,这应该报告给你进程的一切,你可以看到至少所有的文件,打开,但更有趣的事情如果输出是相同的,那么问题可以在python / ipython中进一步调试,这基本上需要@Doug Blank建议,但我也建议调查每个名字(变量)被触摸。 self
, _dlopen
和模式
名称也听起来像他们可能包含有用的信息。 否则,执行 dir(self)
和 dir _dlopen)
查看您可以找到哪些其他属性可能已经由IPYthon修改。
尝试这些,然后我们可以帮助您进一步挖掘。
My initial goal is to open a dll
file on Cygwin using ctypes
. However I found some issues with it. I dug up to sys.dl
which returns an unknown Permission denied
only on IPython.
With python
everything looks fine:
$ ls
my.dll
$ python
Python 2.7.8 (default, Jul 28 2014, 01:34:03)
[GCC 4.8.3] on cygwin
>>> import dl
>>> dl.open('my.dll')
<dl.dl object at 0xfffaa0c0>
With ipython
I get the error:
$ ipython
Python 2.7.8 (default, Jul 28 2014, 01:34:03)
In [1]: import dl
In [2]: dl.open('my.dll')
---------------------------------------------------------------------------
error Traceback (most recent call last)
<ipython-input-2-c681630fa713> in <module>()
----> 1 dl.open('my.dll')
error: Permission denied
I investigated on this using strace
. The output log for `IPython is huge, more than 4MB. Fortunately, I identified some weird things:
symlink.check(C:\Users\user\Home\projects\foo\my.dll, 0x28AB88) (0x4022)
35 2705178 [main] python2.7 16924 path_conv::check: this->path(C:\Users\user\Home\projects\foo\my.dll), has_acls(1)
37 2705215 [main] python2.7 16924 cwdstuff::get: posix /cygdrive/c/Users/user/Home/projects/foo
32 2705247 [main] python2.7 16924 cwdstuff::get: (C:\Users\user\Home\projects\foo) = cwdstuff::get (0x8006ECF0, 32768, 0, 0), errno 11
--- Process 14376, exception c0000138 at 7726163E
3286 2708533 [main] python2.7 16924 seterrno_from_win_error: /home/corinna/src/cygwin/cygwin-1.7.35/cygwin-1.7.35-1.i686/src/src/winsup/cygwin/dlfcn.cc:174 windows error 182
42 2708575 [main] python2.7 16924 geterrno_from_win_error: unknown windows error 182, setting errno to 13
36 2708611 [main] python2.7 16924 dlopen: ret 0x0
Who is /home/corinna
? I have no corinna user in my installation, neither on my Windows. Corinna does not come from my installation. Is it some hard-coded stuff?
Now, here is what I get from strace
for python
:
symlink.check(C:\Users\user\Home\projects\foo\my.dll, 0x28B728) (0x4022)
26 10440048 [main] python 12604 path_conv::check: this->path(C:\Users\user\Home\projects\foo\my.dll), has_acls(1)
23 10440071 [main] python 12604 cwdstuff::get: posix /cygdrive/c/Users/user/Home/projects/foo
25 10440096 [main] python 12604 cwdstuff::get: (C:\Users\user\Home\projects\foo) = cwdstuff::get (0x8006ECF0, 32768, 0, 0), errno 0
3405 10443501 [main] python 12604 dlopen: ret 0x5B9C0000
dlopen
is returning 0x0 in IPython while it is returning 0x5B9C0000 for python. I notice that cwdstuff::get
is raising an error before dlopen
is called.
EDITI sent a message to Cygwin's mailing list and the answer of Corinna regarding this issue is:
My earlier tests using ctypes
Initially when I asked my question I was just playing with ctypes
.I am working on Cygwin 32-bit and Windows 7.With IPython I got an OSError
when I tried to load a dll using cdll.LoadLibrary
.
More ideas:
Check that the user accessing the DLL is the same. You do that like this:
import getpass
print(getpass.getuser())
Check what's the current process actually doing. I haven't used cygwin but in the linux shell the executable
strace
should show you this.Usage: get the PID of your current process:import os; os.getpid()
After this, you can use (from outside the python/ipython console the commandstrace -p <the pid> -e file
. After this setup, you can try to load your DLL.
Remarks: the -e file
flag should be written exactly like that. The word file
tells strace to report all file operations that the process makes. If no differences occur when running on python/ ipython, you can try dropping the -e file
flag. Then you will see all system calls that the process makes. I haven't worked on windows like that, so this might not work at all there, but on linux at least, this should report to you everything that the process did. You could see there at least all the files that got opened, but more interesting things could be found there as well. If the outputs are identical, then the problem can be debugged further in python/ ipython. This would require basically what @Doug Blank suggested, but I'd also recommend investigating every name (variable) that gets touched. The self
, _dlopen
and mode
names also sound like they might contain useful information.
Otherwise, do a dir(self)
and dir(_dlopen)
to see what other properties you could find there that might have gotten modified by IPYthon.
Try these first, and after that we can help you dig further.
这篇关于在dl.open()与ipython但不与python拒绝的权限的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!