2012-03-09 5 views
5

저는 파이썬을 사용하여 'foo'라는 다른 프로그래밍 언어를 구현하고 있습니다. foo의 코드는 모두 python으로 변환 될 것이고 동일한 Python 인터프리터에서 실행되기 때문에 JIT는 python으로 변환 할 것이다.파이썬에서 구현 된 언어에 추적 기능/디버깅 기능을 추가하는 방법은 무엇입니까?

function bar(arg1, arg2) { 
    while (arg1 > arg2) { 
     arg2 += 5; 
    } 
    return arg2 - arg1; 
} 

에 변환합니다 : : 여기

푸의 코드의 작은 조각이다

def _bar(arg1, arg2): 
    while arg1 > arg2: 
     arg2 += 5 
     watchdog.switch() 
    watchdog.switch() 
    return arg2 - arg1 

'감시'는 greenlet는 (생성 된 코드는 또한 greenlet 컨텍스트에서 실행됩니다) 언어가 신뢰할 수없는 코드를 실행하므로 자원 사용을 모니터/제한합니다.

예에서 볼 수 있듯이 파이썬 코드가 생성되기 전에 워치 독 스위치를 추가하고 기능 식별자를 약간 변경하기 위해 구문 분석 트리가 약간 변경됩니다.

모든 요구 사항을 충족하려면 언어에 추적/디버깅 기능을 추가해야합니다. 그래서 파이썬 런타임에서 예외가 발생하면 사용자가 볼 수있는 것은 foo의 코드 추적입니다 (생성 된 파이썬 코드 역 추적).

는 사용자가 다음과 같은 내용으로 'program.foo'라는 이름의 파일을 생성하는 고려 :

1 function bar() { 
2  throw Exception('Some exception message'); 
3 } 
4 
5 function foo() { 
6  output('invoking function bar'); 
7  bar(); 
8 } 
9 
10 foo(); 

번역됩니다에 'program.foo의

def _bar(): 
    watchdog.switch() 
    raise Exception('Some exception message') 

def _foo(): 
    print 'invoking function bar' 
    watchdog.switch() 
    _bar() 

watchdog.switch() 
_foo() 

그런 다음, 출력 '는 다음과 같아야합니다.

invoking function bar 
Traceback (most recent call last): 
    File "program.foo", line 10 
    foo(); 
    File "program.foo", line 7, inside function 'foo' 
    bar(); 
    File "program.foo", line 2, inside function 'bar' 
    throw Exception('Some exception message'); 
Exception: Some exception message 

쉬운 방법이 있습니까? 필자는 파이썬 바이트 코드를 포함하는 솔루션을 선호합니다. 인터프리터 구현에 내부적으로 존재하기 때문에, 다른 것이 없다면 바이트 코드 도구를 사용하면됩니다.

+0

번역본은 파이썬 코드 행과 foo 코드 행 사이에 어떤 종류의 매핑을 저장합니까? 추적을 커스터마이징 할 수 있습니다 : IPython은 꽤 길고 복잡하지만 [ultratb] (https://github.com/ipython/ipython/blob/master/IPython/core/ultratb.py)라는 모듈을 가지고 있습니다. 그리고 약간의 정리로 할 수 있습니다. –

+0

지금까지 번역 만 수행합니다. 그러나 그것이 해결책의 일부라면 필자는 python 행을 foo 행에 확실히 매핑 할 수 있습니다. –

답변

2

컨텍스트 (파일 이름, 함수, 행 번호 등)를 전역 스택에 기록하는 데코레이터로 생성 된 각 파이썬 함수를 꾸밀 수 있습니다. 그런 다음 자신 만의 Exception 클래스를 파생시켜 인터프리터의 최상위 레벨에서 잡을 수 있습니다. 마지막으로 전역 디버그 스택의 정보를 사용하여 원하는 것을 인쇄합니다.

+0

이것은 좋은 리드처럼 보입니다. 이 솔루션을 적용 할 수 있고 각 함수를 꾸미는 대신 파이썬 문의 각 그룹 앞에 현재 foo 라인을 기록하는 함수 호출을 추가 할 것이다. 하지만 왜 사용자 정의 예외 클래스가 필요합니까? 난 그냥 파이썬 예외를 잡아 글로벌 컨텍스트 스택에있는 정보를 인쇄하지 못했습니다? –

+0

물론 가능합니다. 그러나 자신의 예외 클래스를 선언하면 문제에 특정한 예외 정보에 일부 사용자 정의 정보를 기록 할 수 있습니다. –

+0

이것은 지금까지 가장 좋은 솔루션입니다. 감사합니다. –