2013-04-22 4 views
1

이 질문에 대한 대답 꽤 동안 검색 한 및 많은 내 생각을 subprocess 모듈 어떻게 작동하는지 익숙하지 함께 할 생각합니다. 누구나 관심이있는 경우 퍼징 프로그램을위한 것입니다. 그냥 잘 작동서브 프로세스, 인코딩 및 로깅 sqlite 함께

# open and run a process and log get return code and stderr information 
process = subprocess.Popen([app, file_name], stdout=subprocess.PIPE, 
              stderr=subprocess.PIPE) 
return_code = process.wait() 
err_msg = process.communicate()[1] 

# insert results into an sqlite database log 
log_cur.execute('''INSERT INTO log (return_code, error_msg) 
        VALUES (?,?)''', [unicode(return_code), unicode(error_msg)]) 
log_db.commit() 

99 (100)의 시간이 초과하지만 가끔 내가 같은 에러가납니다 또한,이 모든 (내가 그 관련 생각) 나는이 같은 일부 코드를 리눅스에서 수행되고 있음을 언급해야한다 로 :

UnicodeDecodeError 잘못된 연속 바이트

편집 : 'UTF8'코덱 위치 43 바이트 0xce를 디코딩 할 수있는 풀 추적

Traceback (most recent call last): 
    File "openscadfuzzer.py", line 72, in <module> 
    VALUES (?,?)''', [crashed, err_msg.decode('utf-8')]) 
    File "/home/username/workspace/GeneralPythonEnv/openscadfuzzer/lib/python2.7/encodings/utf_8.py", line 16, in decode 
    return codecs.utf_8_decode(input, errors, True) 
UnicodeDecodeError: 'utf8' codec can't decode byte 0xdb in position 881: invalid continuation byte 
0,123,516

하위 프로세스, 실행 또는 코드에 사용중인 응용 프로그램에 문제가 있습니까? 모든 포인터는 (특히 서브 프로세스 stdout 및 stderr의 올바른 사용과 관련된 경우) 감사하게 될 것입니다.

+1

해결책이 아님. 단지'wait()'와'communicate()'둘 다 프로세스가 끝날 때까지 기다릴 것이다. 'wait()'호출을 끊고 - (out, err,) = process.communicate() return_code = process.returncode' – RedBaron

+0

과 같은 일을 할 수 있습니다. 어디에서 유니 코드 데코레이터 오류가 발생했는지 보여주는 스택 추적을 할 수 있습니까? – monk

+0

자동 디코딩/인코딩 의미론이 2와 3 사이에서 다르기 때문에 파이썬 버전을 사용하는 것도 가치가 있습니다 (서브 프로세스 라이브러리에서도 마찬가지 일 수 있습니다) – monk

답변

2

내 생각 엔 문제가이 호출 때문이다? 나는 기본적으로 서브 프로세스 API가 자식 프로그램에 의해 출력 된 raw 바이트를 반환 할 것이라고 확신한다. unicode에 대한 호출은 바이트 인코딩을 문자 (코드 포인트)로 변환하려고 시도하는데,이 경우에는 utf8과 같은 인코딩을 가정한다.

내 생각 엔 바이트가 utf8은 유효하지 않지만 latin1은 유효하다는 것입니다. 여기 잘하면 문제 및 해결 방법을 보여주는 한 예입니다

error_msg.decode('latin1') 

: 당신은 바이트와 문자 사이의 변환 코덱을 지정할 수 있습니다

>>> b'h\xcello'.decode('utf8') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/lib/python3.2/encodings/utf_8.py", line 16, in decode 
    return codecs.utf_8_decode(input, errors, True) 
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xce in position 1: invalid continuation byte 

>>> b'h\xcello'.decode('latin1') 
'hÎllo' 

더 나은 솔루션 자녀 프로세스 출력 UTF8을 만들 수 있습니다, 하지만 데이터베이스가 저장할 수있는 데이터에 따라 다릅니다.

+0

과거에 Windows 컴퓨터에서 latin1 인코딩 문제가 발생했습니다. Linux 환경에서 자주 사용됩니까? 이것은 내가 퍼징하고있는 대중적인 오픈 소스 프로그램이며, Windows에서 이식되었을 것이라고 생각하지 않지만 잘못 될 수 있습니다. 나는 너의 제안을 시도 할 것이다. –

+0

쉘에서'echo $ LANG'을 실행하면 어떻게됩니까? – monk

+0

$ LANG : en_US.UTF-8. 나는 내가 그것을 알아 냈다고 꽤 확신한다. 내 모호한 입력이 utf-8로 유효한지 확인하고 있지 않습니다. 사람이 읽을 수있는 텍스트를 수정하고 있습니다. openscad는 잘못된 코드를보고하고 있다고 생각할 때 fuzzing이 오류 스트림에 생성하는 utf-8이 아닌 다른 것을 고수하고 있습니다. 그래서,이 코드에서 버그로 간주됩니다? –

1

당신은 여기 여기 아주 좋은 서브 프로세스 튜토리얼 http://pymotw.com/2/subprocess/ 및 공식 문서를 찾을 수 있습니다 http://docs.python.org/2/library/subprocess.html을, 그러나 당신이 얻고있는 오류를 포맷하는 방법에서, 당신의 코드가 아닙니다 보이지만 오류를 가져옵니다 응용 프로그램 및 당신은 출력을 수집하고 있기 때문에 당신은 그것을보고 있습니다. 코드 외부에서 간단한 bash 루프를 사용하여 앱을 실행하면 오류를 다시 잡아 내고 코드에서 catch 할 수 있는지 확인하고 애플리케이션의 종료 코드를 확인합니다. 오류가 나타나면 다른 코드를 확인해야합니다. 응용 프로그램이 종료 코드를 올바르게 제공하면 0보다 큽니다.

unicode(error_msg) 

ERROR_MSG의 유형은 무엇입니까 :

+0

감사합니다. 오늘 나중에 다시 시도하고 결과를보고하겠습니다. 이것은 내가 의심했던 것입니다. 나는 단지 오류를 잡아 내 자신이 데이터베이스에 넣을 것이라고 생각한다. "오류 : 프로그램이 해독 할 수없는 오류 메시지와 충돌했다"고 하하. 아마 답을 얻을 수 있지만 먼저 확인하고 싶습니다. –