애플리케이션의 공유 객체에서 "addr2line"을 포크하여 스택 추적을 구축합니다. 얼마나 안전합니까?

애플리케이션의 공유 객체에서 "addr2line"을 포크하여 스택 추적을 구축합니다. 얼마나 안전합니까?

저는 프로세스나 스레드가 터미널 신호(예: SIGSEGV, SIGABRT)를 수신할 때 추적을 내보내도록 Linux에서 실행되는 애플리케이션을 향상시키고 있습니다.

backtrace(3)코드는 backtrace_symbols(3), 를 사용하여 잘 작동하며 역추적 dladdr(3)abi::__cxa_demangle유용한 정보를 생성합니다 .

addr2line그 외에도 소스 파일 이름과 줄 번호를 생성하려고 할 때 제공된 주소를 사용하여 실행 파일을 보내면 잘 작동하는 것을 발견했지만 최근에는 기호가 공유 객체에 있는 한 backtrace(3)생성하기 쉽습니다 ??:0. backtrace친구가 신고한 주소가 ASLR의 영향을 받은 것 같습니다 . 이 문제는 내 스택 추적의 대부분(전부는 아니지만)에 영향을 미치며 현재 forking 의 가치를 감소시키고 있습니다 addr2line.

문제를 해결하고 파일 및 줄 번호를 얻는 방법에 대한 인터넷 결과가 드물어지기 시작했습니다. 그러나 나는 최근에 다음 문제를 해결하기 위해 메모리 매핑이 어떻게 작동하는지 충분히 배웠습니다.

  • backtrace_symbols(3)공유 개체에 이 주소와 오프셋을 추가하고 이를 보낼 때 제공된 기호를 찾기 위해 이 공유 개체와 함께 사용할 수 있는 공유 개체에 대한 경로가 포함된 문자열을 제공합니다 dladdr(3). 파일과 줄 번호가 올바르게 생성되었습니다.dli_fnamenmbacktrace_symbolsaddr2line -e <sharedobjectpath>
  • /proc/<pid>/maps공유 개체 경로에서 매핑된 주소를 조회 r-xp하고 보고된 주소에서 해당 값을 빼면 backtrace(3)위의 공유 개체와 정확히 동일한 주소를 얻을 수 있습니다.
  • 공유 객체 맵 주소를 직접 가져오면(아직 테스트하지는 않았지만 직감적으로) dladdr1(3)액세스를 건너뛸 수 있을 수도 있습니다 /proc/<pid>/maps.

addr2line어쨌든 여기서는 파일과 줄 번호를 가져오기 위해 분기해야 하는 것 같습니다. 이는 약간 고통스럽고(수백 밀리초가 소요됨) libbfd내 응용 프로그램에 종속성으로 도입하지 않고 필요한 것 같습니다.

고쳐 쓰다:자세히 살펴보지 않았는데 에서 찾은 주소가 /proc/<pid>/maps의 값과 동일하다는 것을 알게 되었습니다. 그게 다야. 전혀 위를 쳐다볼 필요가 없습니다.dli_fbasedladdr(3)/proc/<pid>/maps

이를 수행하는 더 깨끗하고 직접적인 방법이 있습니까? 세 번째 글머리 기호로 인해 addr2line. (편집하다: 주소를 알려주실 수 있나요? 제 언급은 무시하세요 /proc/<pid>/maps. ) 두 번째 글머리 기호는 이미 필요한 포크를 얻기 위해 읽을 수 있음을 보여/proc/<pid>/mapsaddr2line 주며 , 다소 큰 메모리 매핑 출력을 스캔하는 것은 많은 작업이지만 후속 호출보다 확실히 빠릅니다 . 세 번째 글머리 기호는 실행 불가능한 것으로 판명됨) 내 프로그램에서 액세스하는 것과 관련된 보안/액세스/보안 문제가 있습니까 /proc/<pid>/maps? 달리기 는 어때요addr2line ?

답변1

알아요, 이것은 매우 늦은 답변이지만 어쨌든 도움이 될 것입니다. 최근에 addr2line같은 문제를 해결하고 있는데 사용을 피하고 싶다면라이브러리 파일. 또한 일부프로젝트당신을 위해 이 작업을 수행합니다(아직 직접 테스트해 볼 기회가 없었습니다).

관련 정보