선인장 스택을 사용하여 병렬 프로그램을 구현하는 MS Windows에서 언어 PARLANSE을 구현했습니다. 스택 청크는 함수 당 단위로 할당되며 은 단지이고 로컬 변수를 처리하는 데 적합한 크기이고 표현식 푸시/팝 및 라이브러리 호출 (라이브러리 루틴이 적용되는 스택 공간은 )을 포함합니다. 이러한 스택 프레임은 실제로 32 바이트로 작을 수 있으며 종종 그렇습니다. 코드가 멍청한 짓 수행하고 하드웨어 트랩 ... 윈도우는 "스택에"전체 86 기계 컨텍스트를 밀어 주장 에 나타나는 지점에서 발생하지 않는 한Windows : 스택에 전체 x86 컨텍스트를 밀어 넣지 마십시오.
이 모두 잘 작동합니다. FP/MMX/etc를 포함하면 500 바이트가 넘습니다. 레지스터, . 당연히 32 바이트 스택의 500 바이트 푸시 은 그렇지 않아야합니다. (하드웨어가 트랩에 이라는 단어를 푸시하지만 전체 컨텍스트는 푸시하지 않음).
[편집 2012년 11월 27일 : 참조 this for measured details on the rediculous amount of stack Windows actually pushes]
나는 윈도우 (예를 들어, 스레드에 특정 위치에) 다른 예외 상황에 맞는 블록 곳을 저장할받을 수 있습니까? 그런 다음 소프트웨어에서 예외 을 스레드에서 처리하고 작은 작은 스택 프레임을 오버플로하지 않고 처리 할 수 있습니다.
나는 이것이 가능하다고 생각하지 않지만, 훨씬 더 큰 청중에게 물어볼 것이라고 생각했습니다. 이 문제가 발생할 수있는 OS 표준 호출/인터페이스 이 있습니까?
내 프로세스가 선택적으로 기본적으로 현재 기존 동작을 가능하게 초기화 컨텍스트 저장 위치 "contextp"를 정의시키기에 MS를 사기 수 있다면 운영 체제에서 할 사소한 것입니다. 그런 다음 interrrupt/트랩 벡터 codee 교체 : 등, ... somereg을 저장하는 데 필요한 명백한 변화
hardwareint: mov <somereg> contextp
test <somereg>
jnz $2
push context
mov contextp, esp
jmp $1
$2: store context @ somereg
$1: equ *
로 ...
hardwareint: push context
mov contextp, esp
을
[I는 어떤 기능을 수행 지금은 : 각 함수에 대해 생성 된 코드를 확인하십시오. 트랩 (예 : 0으로 나누기)을 생성 할 가능성이 있거나 디버깅 할 가능성이있는 경우 (잘못된 포인터 deref 등) 가능한 경우 을 FP 컨텍스트의 스택 프레임에 추가하십시오. 스택 프레임 은 이제 ~~ 500-1000 바이트의 크기로 끝나기 때문에 프로그램은 까지 회귀 할 수 없습니다. 이는 우리가 작성한 응용 프로그램의 실제 문제 일 때가 있습니다. 그래서 우리는 가능한 솔루션 을 가지고 있지만 그것은 디버깅]
편집 8월 25일 복잡 : 내가 알아 마이크로 소프트 내부 엔지니어 Apparantly 히 권한이 에이 이야기를 얻기 위해 관리 한 사람 MS의 수도 실제로 주의 . 해결책에 희미한 희망이있을 수 있습니다.
9 월 14 일 수정 : MS Kernal Group Architect는이 이야기를 듣고 공감 스럽습니다. 그는 MS가 (제안 된 것과 같은) 솔루션을 고려할 것이지만 서비스 팩에있을 가능성은 낮다고 말했다.다음 버전의 Windows를 기다려야 할 수도 있습니다. (한숨 ... 나이 먹을 수도 있습니다 ...)
편집 : 2010 년 9 월 13 일 (1 년 후). Microsoft 측에서 아무런 조치도 취하지 않았습니다. 내 최근의 악몽 : Windows X64에서 32 비트 프로세스를 실행하는 트랩을 수행하고 인터럽트 처리기가 32 비트 컨텍스트를 푸시하기 전에 스택에서 전체 X64 컨텍스트를 푸시합니까? 그것은 훨씬 더 클 것입니다 (두 배의 정수 레지스터를 두 배, SSE 레지스터의 두 배를 (?))?
편집 : 2012 년 2 월 25 일 : (1.5 년 간 ...) Microsoft 측에서 아무런 반응이 없습니다. 나는 그들이 내 종류의 병렬 처리에 신경 쓰지 않는다고 생각한다. 나는 이것이 지역 사회에 불만이라고 생각한다. 정상적인 상황에서 MS가 사용하는 "큰 스택 모델"은 막대한 양의 VM을 먹음으로써 어느 순간에도 살아갈 수있는 병렬 계산의 양을 제한합니다. PARLANSE 모델은 다양한 주행/대기 상태에서 백만 개의 "곡물"이있는 응용 프로그램을 갖게합니다. 이것은 실제로 1 억 개의 노드 그래프가 "병렬로"처리되는 일부 응용 프로그램에서 발생합니다. PARLANSE 체계는 약 1Gb의 RAM으로이를 수행 할 수 있습니다. MS 1Mb "큰 스택"을 사용하려고 시도한다면 스택 공간을 위해 단지 10^12 바이트의 VM이 필요하며 Windows는 100 만 개의 스레드를 관리 할 수 없다고 확신합니다.
편집 : 2014 년 4 월 29 일 : (4 년 후). 나는 MS가 단지 그렇게 읽지 않는다고 생각한다. 필자는 PARLANSE에 충분한 엔지니어링 작업을 수행 했으므로 디버깅 중에 FP 작업이 진행될 때만 대형 스택 프레임 가격을 지불하므로이 작업을 수행하는 데있어 매우 실용적인 방법을 찾을 수있었습니다. MS는 계속 실망했다. 여러 버전의 Windows에서 스택에 푸시 된 항목의 양은 하드웨어 컨텍스트 만 필요로하는 것보다 훨씬 심각하게 달라질 수 있습니다. 이러한 변동성 중 일부는 예외 처리 체인에 코를 찔러 넣은 비 MS 제품 (예 : 바이러스 백신)이 붙어서 발생합니다. 왜 그들은 내 주소 공간 밖에서 그렇게 할 수 없습니까? 우리는 FP/디버그 트랩을위한 큰 슬롭 팩터를 추가하고 그 양을 초과하는 피할 수없는 MS 시스템을 현장에서 기다리는 것으로 모든 것을 처리합니다.
ntdll.dll을 메모리에 패치하면 변경 내용은 현재 프로세스에만 표시됩니다 (copy-on-write). 나는 IAT가 아니라 직접 주소가 사용된다고 가정 하겠지만 JMP를 사용하여 처리기의 처음 몇 바이트를 자신의 코드로 덮어서 링 3으로 되돌릴 수 있습니다. Windows는 이러한 종류의 하지만 그럴 가치가있어. – zildjohn01
이제 그건 생각입니다. IDT의 대상이 ntdll.dll에 있고 그걸 밟을 수 있다고 제안하고 있습니까? IDT가 어디서 가리키고 있는지 또는 ntdll.dll에 게시 된 엔트리 포인트인지 어떻게 알 수 있습니까? ntdll.dll의 구조에 대한 자세한 내용은 어디에서 확인할 수 있습니까? 방금 들었던 문구를 에코하려면 "이것은 잠시 바쁘게 할 것입니다."감사합니다! –
죄송합니다.나는 IDT를 사용했는데 요즘은 x86 아키텍처에서 호출하는 인터럽트 벡터 나 인터럽트를 의미합니다. (저는 x86 매뉴얼을 가지고 있습니다. 이것은 수사학적인 문장입니다 :-) –