Delphi 프로그램 또는 컴파일러 생성 디버그 정보에서 지역 변수 정보 (주소 및 유형)를 어떻게 추출합니까?


105

내 목표는 :

  • Delphi로 컴파일 된 32 비트 또는 64 비트 Windows 프로그램에 일시 중단 된 스레드가 주어지면 스택을 살펴볼 수 있습니다 (실행 가능).
  • 스택 항목이 주어지면 각 메서드와 해당 값의 지역 변수를 열거합니다. 즉, 적어도 주소와 유형 (integer32 / 64 / signed / unsigned, string, float, record, class ...)을 찾아 값을 찾는 데 사용할 수 있습니다.

첫 번째는 괜찮고이 질문에 관한 두 번째 문제입니다. 높은 수준 에서 Delphi의 스택 항목이 주어지면 지역 변수를 어떻게 열거합니까?


낮은 수준에서 이것은 내가 조사한 것입니다.

RTTI : 메서드에 대한 이러한 종류의 정보를 나열하지 않습니다. 이것은 내가 실제로 현실적인 선택이라고 생각한 것이 아니었지만 어쨌든 여기에 나열했습니다.

디버그 정보 : 디버그 빌드를 위해 생성 된 디버그 정보를로드합니다.

  • 지도 파일 : 상세한지도 파일 (텍스트 형식 파일! 하나를 열고 살펴보기)에도 지역 변수 정보가 포함되어 있지 않습니다. 기본적으로 주소 및 소스 파일 행 번호 목록입니다. 파일 및 라인 상관 관계에 대한 주소 (예 : 거터의 파란색 점)에 적합합니다. 더 자세한 정보에 적합하지 않음
  • 원격 디버깅 정보 (RSM 파일)- 내용이나 형식에 대한 알려진 정보가 없습니다 .
  • TD32 / TDS 파일 : 나의 현재 연구 라인. 여기에는 다른 많은 정보 중에서 전역 및 지역 기호가 포함되어 있습니다.

여기에서 발생하는 문제는 다음과 같습니다.

  • TD32 파일 형식에 대한 문서가 없습니다 (찾을 수 있음).
  • 그들에 대한 대부분의 지식은 그들을 사용하는 Jedi JCL 코드 (JclTD32.pas)에서 비롯되었으며 해당 코드를 사용하는 방법 또는 구조가 지역 변수를 표시하기에 충분히 광범위한 지 확실하지 않습니다. 나는 그것이 전역 기호를 처리 할 것이라고 확신하지만 지역에 대해서는 매우 불확실합니다. 정의 된 다양한 상수가 있고 형식에 대한 문서가 없는데, 그 의미를 읽기 위해 추측 할 수 있습니다. 그러나 이러한 상수와 이름은 어딘가에서 왔어 야합니다.
  • TDS 정보를 사용하여 찾을 수있는 소스 는 로컬 기호를로드하거나 처리하지 않습니다.

이것이 올바른 접근 방식이라면이 질문은 'TDS / TD32 파일 형식에 대한 문서가 있고 지역 변수를로드하는 코드 샘플이 있습니까?'가됩니다.

코드 샘플은 필수는 아니지만 매우 작더라도 매우 유용 할 수 있습니다.


2
저는 실제로 Jedi JCL 유닛을 사용하여 TD32 정보에 액세스하지 않았습니다. 저만의 독점 라이브러리가 있지만 필요한 모든 기본 배관이 JclTD32.pas에있는 것처럼 보입니다. 변수 정보에 액세스하기 위해 찾을 수있는 데모 코드는 없지만 거기에있는 샘플 (.. \ jcl \ examples \ windows \ debug \ sourceloc)은 TD32 데이터에서 줄 번호 정보를 얻는 방법을 보여줍니다. 필요한 것을 얻기 위해이를 기반으로 구축 할 수 있어야합니다. 발견 한 내용을 여기로 다시보고하십시오. :)
500-내부 서버 오류

2
@ 500-InternalServerError 감사합니다. 줄 번호 정보는 간단합니다 (지도 파일에도 있음).하지만 특히 지역 기호와 관련된 JCL 코드에 표시되는 정보를 제공 할 수 있습니까? 또한 궁금한 점에서 TD32 독점 라이브러리는 무엇이며 게시 / 공개적으로 사용할 수 있습니까? 아니면 사내에서만 사용할 수 있습니까?
David

3
그 아래에있는 각 절차 / 기능 / 방법 기호에는 로컬 기호 목록이 포함되어 있습니다. 대부분의 정의는 Jedi 단위에있는 것으로 보이지만 일부는 주석 처리되어 있습니다. 내 제안은 작은 테스트 앱을 만들고 기호 열거가 반환하는 내용을 보는 것입니다. 내가 가지고있는 코드는 독점적이며 게시 할 수 없습니다. 어쨌든 지역 변수의 주제는 다루지 않습니다. 그러나 그것이 기반으로하는 정보는 반 공개적이므로 특정 벽에 부딪히면 도움을 드릴 수 있습니다.
500-내부 서버 오류

4
tds2pdb ( code.google.com/p/map2dbg )에는 tds 파일에 대한 파서가있는 것 같습니다. 그래도 C # 코드입니다.
Graymatter

4
예전에는 비공식 문서가 있었지만, Borland (당시)는 내부 형식을 변경하고 문서를 업데이트 할 필요가 없도록 디버그 정보에 액세스하는 대신 dll을 릴리스하기로 결정했습니다. 불행히도 지금은 원본 문서 나 dll을 찾을 수 없습니다. Embarcadero 기술 지원에 문의하여 이에 대해 문의하시기 바랍니다.
500-내부 서버 오류

답변:


2

바이너리가 아닌 디버깅 기호가 있는지 확인하십시오. GDB를 사용하는 것도 가능합니다 (Windows에서는 포트). .dbg 또는 .dSYM 파일을 찾으면 좋을 것입니다. 예를 들어 소스 코드가 포함되어 있습니다.

gdb> list foo
56 void foo()
57 {
58  bar();
59  sighandler_t fnc = signal(SIGHUP, SIG_IGN);
60  raise(SIGHUP);
61  signal(SIGHUP, fnc);
62  baz(fnc);
63 }

디버깅 파일이없는 경우 MinGW 또는 Cygwin을 가져 와서 nm (1) ( man page )를 사용할 수 있습니다. 바이너리에서 기호 이름을 읽습니다. 여기에는 C ++ 유형과 같은 일부 유형이 포함될 수 있습니다.

int abc::def::Ghi::jkl(const std::string, int, const void*)

--demangle옵션 을 추가하는 것을 잊지 마십시오. 그렇지 않으면 다음과 같은 메시지가 표시됩니다.

__ZN11MRasterFont21getRasterForCharacterEh

대신에:

MRasterFont::getRasterForCharacter(unsigned char)

2
Jakub, 답변 주셔서 감사합니다. 불행히도 특정 디버그 형식 인 TDS를 읽어야 할 것입니다. Delphi 앱은 Windows에서 GDB 호환 디버그 정보로 컴파일되지 않습니다. nm가 어떻게 도움이 될지 잘 모르겠습니다. 델파이가 생성하는 것이 아닌 특정 디버그 파일 형식에 의존하기 때문입니다. 아니면 내가 당신의 대답을 오해 했습니까? 예를 들어 GDB가 델파이의 기호를 읽을 수 있습니까?
David

@DavidM, 귀하의 의견은 매우 중요합니다. Windows에서 GNU Binutils 또는 GNU Debugger의 포트를 찾으십시오 (Binutils 포트만 알고 있습니다). GDB 용 BFD 라이브러리가 있습니다. Binutils에서도 사용됩니다. 여러 파일 형식을 읽고 매직 넘버로 인식 할 수 있습니다. 모든 것이 실패하면라는 도구를 사용하십시오 strings. 바이너리 파일에서 문자열을 추출합니다. 맨 페이지를 참조 하십시오 . 이 문자열을 인쇄 할 있지만 도움이 될 필요가 없습니다
최고하기 Sekret

0

http://download.xskernel.org/docs/file%20formats/omf/borland.txt 개방형 아키텍처 핸드북을 살펴보십시오 . 오래되었지만 파일 형식에 대한 관련 정보를 찾을 수 있습니다.


컨텍스트를 추가해 주시겠습니까? 향후 링크가 끊어 질 수 있습니다.
Hintham

링크에는 Borland 컴파일러에서 사용하는 OMF 파일 형식과 Borland에서 사용하는 기타 바이너리 파일 형식에 대한 Borland의 공식 문서가 포함되어 있습니다. 몇 년 전에 TDS 파일 형식을 살펴 보았는데 문서화 된 파일 형식과 일부가 호환되는 것 같았습니다. TDS 파일에서 지역 변수에 대한 정보를 수집하려고 할 때 링크 된 문서를 사용하거나 참조해야합니다. 링크가 끊어지면 내 대답이 쓸모없고 필요한 정보가 손실됩니다. 링크 된 "개방형 아키텍처 핸드북"은 이전 Turbo Pascal 및 C 릴리스의 일부였습니다.
Muetze1
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.