Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Profiler should be more careful when reading other thread's stack #20421

Closed
mraleph opened this issue Aug 8, 2014 · 5 comments
Closed

Profiler should be more careful when reading other thread's stack #20421

mraleph opened this issue Aug 8, 2014 · 5 comments
Assignees
Labels
area-vm Use area-vm for VM related issues, including code coverage, FFI, and the AOT and JIT backends.

Comments

@mraleph
Copy link
Member

mraleph commented Aug 8, 2014

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:

  1. RBP is not really a classical frame pointer and RBP+8 will not contain return address;
  2. 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.

@mraleph
Copy link
Member Author

mraleph commented Aug 8, 2014

I am going to disable this code for Win64 to remove flakes.

After that I am going to reassign to John for the actual fix which is more involved.

@johnmccutchan
Copy link
Contributor

The PC marker offset is negative so we are reading down the stack not up it.

@mraleph
Copy link
Member Author

mraleph commented Aug 8, 2014

Agreed re PC marker offset: I thought we are actually reading return address. Hence reading up, but we are reading PC marker, not return address.

In any case I disabled this code path on Win64 entirely.

Feel free to close this issue if this does not impact Observatory usability.


Set owner to @johnmccutchan.
Added Accepted label.

@johnmccutchan
Copy link
Contributor

https://codereview.chromium.org/455833002 should allow reading of the pc marker on Win64.

@johnmccutchan
Copy link
Contributor

Closing. Only affects native profiling (covered by https://code.google.com/p/dart/issues/detail?id=20423).


Added Fixed label.

@mraleph mraleph added Type-Defect area-vm Use area-vm for VM related issues, including code coverage, FFI, and the AOT and JIT backends. labels Feb 26, 2015
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-vm Use area-vm for VM related issues, including code coverage, FFI, and the AOT and JIT backends.
Projects
None yet
Development

No branches or pull requests

2 participants