You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Right now we are randomly crashing on Win64 due to profiler trying to read from another thread's stack and hitting the guard page.
Code assumes that if FP does not fall on the start of the page then this page must have been already touched by the thread and thus is not a guard page.
if defined(TARGET_OS_WINDOWS)
// If the fp is at the beginning of a page, it may be unsafe to access
// the pc marker, because we are reading it from a different thread on
// Windows. The next page may be a guard page.
const intptr_t kPageMask = VirtualMemory::PageSize() - 1;
if ((sample->fp() & kPageMask) == 0) {
return;
}
endif
Actual reasoning behind this check is unclear because stack grows downwards so it's always previous page that is guard page (in terms of linear addresses) not next page.
Furthermore this assumption is completely incorrect for the code that MS C++ compiler generates. Here is an example of function prologue:
mov qword ptr [rsp+20h],rbx
push rbp
push rsi
push rdi
push r12
push r13
push r14
push r15 ;; last touched stack address is here
lea rbp,[rsp-0DA0h]
sub rsp,0EA0h
Notice the following:
RBP is not really a classical frame pointer and RBP+8 will not contain return address;
RBP > RSP, but at the same time both RBP and RSP are far below the last touched stack address and potentially point into the next page which is still marked as GUARD (as it was not touched yet).
If we suspend thread precisely at the function prologue we are risking hitting the guard page and we do actually hit it randomly.
Given observations 1 & 2, we should never attempt to read the stack while it is outside of Dart code which we fully control.
The text was updated successfully, but these errors were encountered:
Right now we are randomly crashing on Win64 due to profiler trying to read from another thread's stack and hitting the guard page.
Code assumes that if FP does not fall on the start of the page then this page must have been already touched by the thread and thus is not a guard page.
if defined(TARGET_OS_WINDOWS)
// If the fp is at the beginning of a page, it may be unsafe to access
// the pc marker, because we are reading it from a different thread on
// Windows. The next page may be a guard page.
const intptr_t kPageMask = VirtualMemory::PageSize() - 1;
if ((sample->fp() & kPageMask) == 0) {
return;
}
endif
Actual reasoning behind this check is unclear because stack grows downwards so it's always previous page that is guard page (in terms of linear addresses) not next page.
Furthermore this assumption is completely incorrect for the code that MS C++ compiler generates. Here is an example of function prologue:
mov qword ptr [rsp+20h],rbx
push rbp
push rsi
push rdi
push r12
push r13
push r14
push r15 ;; last touched stack address is here
lea rbp,[rsp-0DA0h]
sub rsp,0EA0h
Notice the following:
If we suspend thread precisely at the function prologue we are risking hitting the guard page and we do actually hit it randomly.
Given observations 1 & 2, we should never attempt to read the stack while it is outside of Dart code which we fully control.
The text was updated successfully, but these errors were encountered: