13

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.

EDIT I sent a message to Cygwin's mailing list and the answer of Corinna regarding this issue is:

This is not Cygwin's fault, AFAICS. Cygwin never loads functions by ordinal. This is also a bit on the lean side as far as information is concerned. One can't see how the process calls dlopen, for instance. Corinna How to solve this issue?

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.

nowox
  • 25,978
  • 39
  • 143
  • 293
  • 3
    where is the library located? – loopbackbee Mar 17 '15 at 11:10
  • library in the current directory in both cases? (you can check your current directory from python like so: `import os; os.getcwd()`; same from ipython, but there you can also use the `!pwd` command) – vlad-ardelean Mar 17 '15 at 11:12
  • also... try this in both python and ipython: `import sys; print sys.executable`. That will show you where the python interpreter that you're running is installed... perhaps the library is in the same directory as the interpreter, and ipython uses the global interpreter...because you're in a virtual environment and have forgotten to install ipython??... i'm just throwing ideas here. – vlad-ardelean Mar 17 '15 at 11:14
  • @vlad-ardelean Yes in both cases I get the same `getcwd()` value. Also the same for the `sys.executable` (almost the same actually, python point to `/usr/bin/python` while ipython is linked to `/usr/bin/python2.7.exe`. python is a symbolic link to python2.7.exe) – nowox Mar 17 '15 at 11:34
  • ok. in both environments you have this list `import sys; print sys.path`. Where's the library you're trying to load? Do the output of the previous commands, from python and ipython differ? If so does is the library missing from a path that the ipython interpreter has access to? – vlad-ardelean Mar 17 '15 at 11:50
  • @vlad-ardelean No everything looks the same unfortunately. – nowox Sep 09 '15 at 06:23
  • I'm guessing this is fundamentally a duplicate of [IPython `sys.path` different from python `sys.path`](http://stackoverflow.com/questions/23209192/ipython-sys-path-different-from-python-sys-path) – tripleee Sep 09 '15 at 06:39
  • It would follow naturally if the DLL cannot be found on the search path. – tripleee Sep 09 '15 at 06:55
  • I have a very similar problem, but vice-verse: http://stackoverflow.com/questions/32465864/ipython-notebook-script-difference-loading-dlls – denfromufa Sep 10 '15 at 04:22
  • I tried your example before the edit and could not reproduce. The dll loaded fine in IPython. I wonder if your IPython installation is running a different python to the default. Note in `strace` output that the lines start `python` in the working version and `python2.7` in the failing version. Is Ipython referring to the Windows python install instead of the Cygwin's own version? Maybe this could explain permissions errors. – J Richard Snape Sep 11 '15 at 16:05
  • `python` is just a symlink to `python2.7` – nowox Sep 11 '15 at 16:06

3 Answers3

6

Two ideas:

1) in the next cell, type %pdb, and then interactively "print self._name" to see what it is.

2) Use a full path to cdll.LoadLibrary("foo.dll") to see if that works.

Once you know what the issue is, then you can decide whose bug it is, and report it (could be a ctypes issue, but probably ipython)

Doug Blank
  • 2,031
  • 18
  • 36
  • That sounds like a ctypes issue, or integration problem... is there an ENV variable that is different? – Doug Blank Mar 17 '15 at 18:33
  • thank for this advise. I checked it and did not find any thing from `%pdb`. Also I the `ENV` variables are the same for both `python` and `ipython`. Using `strace` I found that the problem is not specific to `ctypes`. My best guess is now `dl.open` – nowox Sep 16 '15 at 06:25
4
  • Perhaps Python executable and IPython kernel use different manifest files which define loading policy?

  • Try appending the DLL path to sys.path in both cases.

  • Check admin rights (UAC) in both cases.

  • Use dependency walker to figure out dependencies of this DLL. Maybe the problem comes from dependencies?

  • Possibly your machine has multiple copies of this DLL?

  • Finally you can use Process Explorer to see the list of DLLs loaded in both cases and see any differences.

I'm working on a very similar issue:

ipython notebook & script difference - loading DLLs

Community
  • 1
  • 1
denfromufa
  • 5,610
  • 13
  • 81
  • 138
4

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 command strace -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.

vlad-ardelean
  • 7,480
  • 15
  • 80
  • 124
  • 1
    Yes, you found it. The problem comes from `_dlopen`. I was able to reproduce the problem just with using `import dl` and `dl.open('my.dll')`. I edited my question to show what I have found. – nowox Sep 11 '15 at 09:10
  • cool. nice to see you're on a good track. when i have some more time, i'll try to investigate further. In the meantime, could you perhaps clone the ipython repository https://github.com/ipython/ipython and run this command `git log --graph --format='%h %Cred%ad%Creset %C(yellow)%aN%Creset %s' -S corina`... This will display their commits containing the word `corina`. Perhaps there's also a repository for cygwin, and you can run that there too... – vlad-ardelean Sep 11 '15 at 10:12
  • Corinna is working for Cygwin not for IPython I guess. – nowox Sep 11 '15 at 10:44