2016-03-07 2 views
3

У меня есть сценарий python 3.5, работающий под Windows, который вызывает определенную проблему (tblastn из BLAST + suite, если быть точным) в нескольких файлах. В большинстве этих файлов он работает нормально, но на некоторых он не работает с кодом возврата 0xC0000005. Если я возьму тот же самый вызов командной строки и запустил его из консоли в том же текущем рабочем каталоге, он выполняет отлично.Внешняя команда не работает с кодом возврата 0xC0000005 при вызове с Python, но работает в консоли

Я в настоящее время работает команда с subprocess.Popen, как это:

childProcess = subprocess.Popen(blast_cmd, stdin=subprocess.PIPE, 
            stdout=subprocess.PIPE, stderr=subprocess.PIPE, 
            universal_newlines=True,shell=True) 

и затем вызвать subprocess.poll(), пока она не завершится. Я использую многопоточность, запуская четыре процесса одновременно, но это все равно, если я заставляю его запускать по одному. То же самое происходит с os.system, subprocess.run(), subprocess.call() и subprocess.check_call(), и случается, установил ли я shell на True или False.

Какой файл (ы) он терпит неудачу, является каждый раз, когда я запускаю код, но тот же файл будет работать, если он будет помещен в другой список файлов для обработки. Изменение метода вызова иногда приводит к сбою файлов, поэтому использование os.system может привести к сбою разных файлов по сравнению с subprocess.Popen. Таким образом, это не похоже на то, к какому файлу я вызываю tblastn.

Кто-нибудь знает, что может вызвать такое поведение?

Или, если кто-то знает, что может быть отличным между запуском в созданном процессе (в документации говорится, что он использует CreateProcess()) по сравнению с запуском из командной строки, то, по крайней мере, мне нужно было где-то начать?

+0

У меня есть идея о том, как его отладить, но я не знаком с tblastn; вы скомпилируете его из источника или имеете возможность? –

+0

Я получил его как .exe; Я мог достать источник и перекомпилировать его, но я бы предпочел не делать этого. –

+0

Хорошо - я так понимаю, ты на окнах?Не знаю о Windows, но в Linux вы можете добавить «valgrind» в список «blast_cmd» и предоставить ему файл журнала для вывода (его valgrind arg). Это приведет к записи stacktrace о том, где не удалось (хотя это поможет, если скомпилировано в debugmode, если это segfault). Это не значит, что вы можете отлаживать программу, но чтобы увидеть, есть ли какой-то конкретный аргумент, который он терпит неудачу или не может загрузить. Возможно, какой-то ресурс передается не так, как на оболочке (один автоматически завершает полное имя пути, например) –

ответ

2

код ошибки, скорее всего, «Доступ запрещен» (хотя есть 4 код создает в заголовочных файлах окна, Access Denied является наиболее вероятным:

# for hex 0xc0000005/decimal -1073741819 
    FILE_LOG_INFORMATION_FAILED         iasmsg.h 
# Information for the %1 log could not be logged to the text 
# file %2 in the path %3. Error code: %0 
    STATUS_ACCESS_VIOLATION          ntstatus.h 
# The instruction at 0x%08lx referenced memory at 0x%08lx. 
# The memory could not be %s. 
    USBD_STATUS_DEV_NOT_RESPONDING         usb.h 
# as an HRESULT: Severity: FAILURE (1), FACILITY_NULL (0x0), Code 0x5 
# for hex 0x5/decimal 5 
    ERROR_ACCESS_DENIED           winerror.h 
# Access is denied. 

Я хотел бы начать, глядя на пользовательские привилегии/учетные данные, которые используются для запуска исходного (запускающего/родительского) сценария, который дочерний процесс/подпроцесс наследует свои учетные данные из ... затем сравнивает это с учетными данными, которые используются, когда вы «запускаете это в командной строке», поскольку вы описал.

HTH, Edwin.

1
  1. Sub proc, которые запускаются программно, часто получают другие настройки памяти (размер кучи и т. Д.), Чем интерактивно запущенные procs. Поэтому попробуйте поместить некоторую оболочку для проверки кучи/памяти вокруг tblastn.exe. Ваше описание «сбоя в одном файле, но обработка в другом списке файлов» показывает, что ошибка не связана с самим отказоустойчивым вызовом, а с каким-то условием, вызванным предыдущими действиями.
  2. вывод буферизирован в память. Если tblastn имеет много выходных данных, используйте для связи(), чтобы аннулировать (или использовать) выходные данные субпроцессов.
  3. shell = True не требуется для вызова исполняемых файлов, он предназначен для выполнения строковых оболочек оболочки. Используя это, вы обмениваете tblastn бессмысленным cmd.exe.
Смежные вопросы