Подтвердить что ты не робот

Разрешение отклонено на dl.open() с помощью ipython, но не с python

Моя первоначальная цель - открыть файл dll на Cygwin с помощью ctypes. Однако я нашел некоторые проблемы с этим. Я выкопал до sys.dl, который возвращает неизвестный Permission denied только на IPython.

С python все выглядит нормально:

$ 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>

С ipython я получаю ошибку:

$ 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

Я исследовал это с использованием strace. Выходной журнал для `IPython огромен, более 4 МБ. К счастью, я обнаружил некоторые странные вещи:

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

Кто /home/corinna? У меня нет пользователя corinna в моей установке, ни на моей Windows. Коринна не приходит из моей установки. Это какие-то жестко закодированные вещи?

Теперь вот что я получаю от 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 возвращает 0x0 в IPython, пока он возвращает 0x5B9C0000 для python. Я заметил, что cwdstuff::get вызывает ошибку до вызова dlopen.

ИЗМЕНИТЬ Я отправил сообщение в список рассылки Cygwin, а ответ Коринны в отношении этой проблемы:

Это не ошибка Cygwin, AFAICS. Cygwin никогда не загружает функции по порядковое. Это также немного на стороне берега, поскольку информация обеспокоен. Например, невозможно увидеть, как процесс вызывает dlopen, например. Коринна Как решить эту проблему?

Мои предыдущие тесты с использованием ctypes

Сначала, когда я задал свой вопрос, я просто играл с ctypes. Я работаю над Cygwin 32-bit и Windows 7. С IPython я получил OSError, когда пытался загрузить DLL с помощью cdll.LoadLibrary.

4b9b3361

Ответ 1

Больше идей:

  • Убедитесь, что пользователь, обращающийся к DLL, является тем же. Вы делаете это так:

    import getpass

    print(getpass.getuser())

  • Проверьте, что делает текущий процесс. Я не использовал cygwin, но в оболочке linux исполняемый файл strace должен показать вам это. Использование: получить PID текущего процесса: import os; os.getpid() После этого вы можете использовать (извне консоль python/ipython команду strace -p <the pid> -e file). После этой настройки вы можете попробовать загрузить свою DLL.

Примечания: флаг -e file должен быть написан точно так же. Слово file сообщает strace сообщать обо всех действиях файла, которые выполняется процессом. Если при запуске на python/ipython не возникает различий, вы можете попробовать сбросить флаг -e file. Затем вы увидите все системные вызовы, которые делает процесс. Я не работал над такими окнами, так что это может вообще не работать, но, по крайней мере, по Linux, это должно сообщать вам все, что сделал этот процесс. Вы могли видеть там, по крайней мере, все файлы, которые были открыты, но здесь можно было найти более интересные вещи. Если выходы идентичны, тогда проблема может быть отлажена далее в python/ipython. Это потребует в основном того, что предложил @Doug Blank, но я также рекомендую исследовать каждое имя (переменную), которое будет затронуто. Названия self, _dlopen и mode также звучат так, как будто они могут содержать полезную информацию.

В противном случае сделайте dir(self) и dir(_dlopen), чтобы узнать, какие другие свойства вы могли бы найти там, которые могли быть изменены IPYthon.

Попробуйте сначала, и после этого мы сможем помочь вам копать дальше.

Ответ 2

Две идеи:

1) в следующей ячейке введите% pdb, а затем интерактивно "напечатайте self._name", чтобы узнать, что это такое.

2) Используйте полный путь к cdll.LoadLibrary( "foo.dll" ), чтобы узнать, работает ли это.

Как только вы узнаете, в чем проблема, тогда вы можете решить, чья ошибка это, и сообщить об этом (может быть проблемой ctypes, но, вероятно, ipython)

Ответ 3

  • Возможно, исполняемый файл Python и IPython используют разные файлы манифеста, которые определяют политику загрузки?

  • Попробуйте добавить DLL-путь к sys.path в обоих случаях.

  • Проверьте права администратора (UAC) в обоих случаях.

  • Используйте хост зависимостей для определения зависимостей этой DLL. Может быть, проблема исходит из зависимостей?

  • Возможно, ваша машина имеет несколько копий этой DLL?

  • Наконец, вы можете использовать Process Explorer, чтобы просмотреть список DLL, загруженных в обоих случаях, и увидеть любые различия.

Я работаю над очень похожим вопросом:

ipython notebook и script разница - загрузка DLL