/proc/를 사용하여 하위 작업(스레드)의 스택을 찾는 방법/지도?

/proc/를 사용하여 하위 작업(스레드)의 스택을 찾는 방법/지도?

목적:

Linux 환경에서 포인터 스캐너를 만드는 방법에 대해 이론화 중입니다.

부인 성명:

내 결과는 Debian Bookworm(현재 안정 버전)과 사용자 정의 커널이 있는 Gentoo 시스템에서 테스트되었습니다. 차이는 관찰되지 않았습니다.

질문:

대상 프로세스에 디버거를 연결하지 않고도 각 스레드/하위 작업 스택에 대한 VMA를 식별할 수 있기를 바랍니다. 이것은 다음을 사용하여 가능해야합니다프로세스의사 파일 시스템

논의하다:

Linux 4.5 이전에는 경로명 필드에 상위 작업의 스택 영역이 표시되었고 /proc/[parent_tid]/maps, 각 하위 작업의 스택 영역은 으로 표시되었습니다.[STACK][STACK:child_tid]

Linux 4.5 이후에는 상위 작업의 스택 영역만 해당 [STACK]레이블을 유지합니다. 이제 하위 작업 스택 영역에 레이블이 없습니다. 이 변경에 대한 커밋 메시지(링크 1 참조)에서 Johannes Weiner는 VMA의 순서도를 관찰하여 하위 작업 스택을 볼 수 있다고 언급했습니다 /proc/[parent_tid]/task/[child_tid]/maps.

이것은 나에게 효과적이지 않은 것으로 판명되었습니다. 상위 작업과 하위 작업 간의 메모리 영역 매핑은 동일합니다. /proc/[parent_tid]/maps== /proc/[parent_tid]/task/[child_tid*]/maps. 이는 궁극적으로 [STACK]라벨이 동일한 영역에 배치된다는 것을 의미합니다.

/proc/[tid]/stat특정 작업에 대한 스택 하단에서 VMA를 찾는 데 사용할 수 있습니다. 이는 28번째 값입니다(man 5 proc 참조). 다시, /proc/[parent_tid]/stat. /proc/[parent_tid]/task/[child_tid*]/stat분명히 하위 작업은 프로세스의 다른 모든 작업과 스택의 시작 부분을 공유하지 않습니다.

clone(2), 스택 포인터를 매개변수로 사용하여 새 하위 작업을 생성하는 데 사용되는 시스템 호출입니다. 스택 메모리를 얻는 가장 확실한 방법은 익명성을 이용하는 것입니다 mmap(2). NET의 익명 메모리 매핑 /proc/[tid]/maps일부 단일 스레드 및 다중 스레드 프로세스를 관찰하면 익명 메모리 매핑 수와 프로그램의 스레드 수 사이에 직접적인 상관 관계가 있습니다. 이러한 유형의 매핑은 스레드 스택에만 적용되는 것은 아니지만 스레드 스택이 이런 방식으로 할당되었으면 좋겠습니다. 각 메모리 맵에는 /proc/[tid]/maps. 이들 중 어느 것이 하위 작업 스택으로 작동하는지 확인할 수 있는 방법이 있습니까?

내가 여기서 무슨 실수를 했나요?


관련된 링크들:

  1. [STACK:tid]다음에서 태그를 제거하기로 약속합니다 /proc/[tid]/maps.
    https://lists.ubuntu.com/archives/kernel-team/2016-March/074681.html

답변1

Field 28은 Linux 6.1.0에서 작동합니다. 작업은 필요하지 않는 한 자체 스택을 갖지 않습니다.

다음은 다양한 하단 스택 값을 반환해야 하는 간단한 실행 스크립트입니다.일부일. Firefox를 다운로드/설치해야 할 수도 있습니다.

#!/bin/bash

# create a temporary profile
test -d /tmp/temporary_profile || mkdir /tmp/temporary_profile

# run Firefox on that profile
firefox --profile /tmp/temporary_profile &

# Give it some time to create the tasks
sleep 10

# Get the PID
FFPID=$!

# Print field 28 of the stat files
awk '{print FILENAME" "$28}' /proc/$FFPID/stat /proc/$FFPID/task/*/stat

Firefox를 실행하는 경우 다음 줄을 실행하고 현재 프로세스 ID를 입력할 수 있습니다.

read a;awk '{print FILENAME" "$28}' /proc/$a/stat /proc/$a/task/*/stat

다른 다중 스레드 프로그램과도 작동하지만 Firefox는 거의 즉시 자체 스택으로 일부 작업을 생성하므로 코드가 제대로 작동하는지 확인하는 데 도움이 될 수 있습니다.

관련 정보