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

Add a fallback for stacktrace printing for older Windows versions. #50526

Merged
merged 6 commits into from
Jun 29, 2018

Conversation

moxian
Copy link
Contributor

@moxian moxian commented May 8, 2018

Some time ago we switched stack inspection functions of dbghelp.dll to their newer alternatives that also capture inlined context.
Unfortunately, said new alternatives are not present in older dbghelp.dll versions.
In particular Windows 7 at the time of writing has dbghelp.dll version 6.1.7601 from 2010, that lacks StackWalkEx and friends.

Tested on my Windows 7 - both msvc and gnu versions produce a readable stacktrace.

Fixes #50138

@rust-highfive
Copy link
Collaborator

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @Kimundi (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

Please see the contribution instructions for more information.

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label May 8, 2018
@Zoxc
Copy link
Contributor

Zoxc commented May 10, 2018

I'd like to see an enum in BacktraceContext which stores the set of functions which are going to be used instead of checking for them in each function. Also you should split the functions into two variants instead of having large matches. The best would be to make these functions generic so you could keep a single one.

@moxian
Copy link
Contributor Author

moxian commented May 11, 2018

Good points. Will do.

}
}

fn set_frames_ex(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should be able to make this generic by passing the STACKFRAME type, the init_frame function and a closure which calls StackWalk and returns the relevant information.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, thank you very much!

This is my first real foray into rust generics, so please let me know if I did anything particularly wrong here.

) == c::TRUE
{
let addr = frame.AddrPC.Offset;
if addr == frame.AddrReturn.Offset || addr == 0 || frame.AddrReturn.Offset == 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic shouldn't be used. set_frames_64 and set_frames_ex should walk the stack in the same way.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the cumbersome logic.

@moxian
Copy link
Contributor Author

moxian commented May 18, 2018

Genericalized.
Sorry that this is taking so long.

@Zoxc
Copy link
Contributor

Zoxc commented May 22, 2018

It's better now. I would prefer a solution without the extra traits though.

So fn set_frames<W: StackWalker>(StackWalk: W, frames: &mut [Frame]) -> io::Result<usize> could become

fn set_frames<
  Frame,
  Walk: FnMut(c::DWORD, c::HANDLE, c::HANDLE, &mut Frame, &mut c::CONTEXT)
  Addr: Fn(&mut Frame) -> *const u8,
>(frames: &mut [Frame], walk: Walk, addr: Addr) -> io::Result<usize>

And something similar could be done to remove the other added traits.

@pietroalbini pietroalbini assigned Zoxc and unassigned Kimundi May 28, 2018
@pietroalbini pietroalbini added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 28, 2018
@shepmaster
Copy link
Member

Ping from triage, @moxian ! Will you have time to revisit this soon?

@moxian
Copy link
Contributor Author

moxian commented Jun 4, 2018

@ triage: Sorry this is taking so long.
I picked up the bug because I wanted it fixed, not because I wanted to fix it myself. I hope me having this PR open does not prevent sufficiently motivated others from fixing it in the meantime (IOW: feel free to steal this from me any time)

@ Zoxc: I removed the extra traits in printing functions, but couldn't figure out how to do the stack walking without the trait.
The proposed closure wrapping StackWalkExFn/StackWalk64Fn cannot be of type FnMut(c::DWORD, c::HANDLE, c::HANDLE, &mut Frame, &mut c::CONTEXT)[1] since the wrapped function accepts concrete c::STACKFRAME64/c::STACKFRAME_EX type which is "erased", if you will, by that time. In other words the above type signature requires closure instance be polymorphic over the type of STACKFRAME which is impossible.
One option would be to pass in the rust's Frame instead of windows' c::STACKFRAME(64|_EX), but that would require moving the logic of populating the Frame from the STACKFRAME to be moved out of set_frame() and into the closure body , which necessarily duplicates said logic across both of the variants, and we are effectively back at commit 1.

[1] I assumed by Frame here you meant an abstraction encompassing both c::STACKFRAME64 and c::STACKFRAME_EX. If not, and you meant the sys_common::backtrace::Frame, then see the second paragraph.

@Zoxc
Copy link
Contributor

Zoxc commented Jun 10, 2018

I've pushed a commit which abstracts over stalk walking using a macro. A macro allows avoiding duplicating the setup of the stack frame structure, so I just used that for the entire thing.

I've yet to test that this code works on Windows 7/10.

That should be done and then we can get @alexcrichton to rubber stamp this.

@moxian
Copy link
Contributor Author

moxian commented Jun 14, 2018

I can confirm that this works on Windows 7 - both msvc and gnu variants.
I also tested it with dbghelp version 10.0.17134.12, and it still works, so should be good for Windows 10 as well (I don't have access to the real Win 10 system, so this is the best approximation I can get).

@pietroalbini pietroalbini added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jun 25, 2018
@pietroalbini
Copy link
Member

r? @alexcrichton

@rust-highfive rust-highfive assigned alexcrichton and unassigned Zoxc Jun 25, 2018
@alexcrichton
Copy link
Member

@bors: r+

Looks great to me!

@bors
Copy link
Contributor

bors commented Jun 28, 2018

📌 Commit cfabe858a681de1227b054df0ab59d73f9c53227 has been approved by alexcrichton

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 28, 2018
@bors
Copy link
Contributor

bors commented Jun 28, 2018

🔒 Merge conflict

This pull request and the master branch diverged in a way that cannot be automatically merged. Please rebase on top of the latest master branch, and let the reviewer approve again.

How do I rebase?

Assuming self is your fork and upstream is this repository, you can resolve the conflict following these steps:

  1. git checkout just-fix (switch to your branch)
  2. git fetch upstream master (retrieve the latest master)
  3. git rebase upstream/master -p (rebase on top of it)
  4. Follow the on-screen instruction to resolve conflicts (check git status if you got lost).
  5. git push self just-fix --force-with-lease (update this PR)

You may also read Git Rebasing to Resolve Conflicts by Drew Blessing for a short tutorial.

Please avoid the "Resolve conflicts" button on GitHub. It uses git merge instead of git rebase which makes the PR commit history more difficult to read.

Sometimes step 4 will complete without asking for resolution. This is usually due to difference between how Cargo.lock conflict is handled during merge and rebase. This is normal, and you should still perform step 5 to update this PR.

Error message
CONFLICT (file/directory): There is a directory with name src/libbacktrace in heads/homu-tmp. Adding src/libbacktrace as src/libbacktrace~HEAD
Automatic merge failed; fix conflicts and then commit the result.

@bors bors removed the S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. label Jun 28, 2018
@moxian
Copy link
Contributor Author

moxian commented Jun 28, 2018

@pietroalbini Will do today (or maybe tomorrow - depending on your timezone).

PR rust-lang#47252 switched stack inspection functions of dbghelp.dll
to their newer alternatives that also capture inlined context.
Unfortunately, said new alternatives are not present in older
dbghelp.dll versions.
In particular Windows 7 at the time of writing has dbghelp.dll
version 6.1.7601 from 2010, that lacks StackWalkEx and friends.

Fixes rust-lang#50138
.. rather than having them be one giant match statement.
.. and pass them around in BacktraceContext.
@moxian
Copy link
Contributor Author

moxian commented Jun 29, 2018

Done.

@alexcrichton
Copy link
Member

@bors: r+

@bors
Copy link
Contributor

bors commented Jun 29, 2018

📌 Commit be7f619 has been approved by alexcrichton

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jun 29, 2018
@bors
Copy link
Contributor

bors commented Jun 29, 2018

⌛ Testing commit be7f619 with merge 090a7110e08eee03f71a6fb95a1c9baa2b61733e...

@bors
Copy link
Contributor

bors commented Jun 29, 2018

💔 Test failed - status-travis

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Jun 29, 2018
@rust-highfive
Copy link
Collaborator

The job dist-x86_64-linux of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
[01:10:30] [TIMING] Analysis { compiler: Compiler { stage: 2, host: "x86_64-unknown-linux-gnu" }, target: "x86_64-unknown-linux-gnu" } -- 3.058
[01:10:30] Dist src
[01:10:43] [TIMING] Src -- 12.640
[01:10:43] Create plain source tarball
[01:12:52] curl: (6) Couldn't resolve host 's3-us-west-1.amazonaws.com'
[01:14:44] curl: (6) Couldn't resolve host 's3-us-west-1.amazonaws.com'
[01:16:37] curl: (6) Couldn't resolve host 's3-us-west-1.amazonaws.com'
[01:16:37] thread 'main' panicked at 'failed to download openssl source: exit code: 6', bootstrap/native.rs:589:17
[01:16:37] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap dist --host x86_64-unknown-linux-gnu --target x86_64-unknown-linux-gnu
[01:16:37] Build completed unsuccessfully in 1:11:00
travis_time:end:0de3483f:start=1530253039615388785,finish=1530257636929458900,duration=4597314070115

---
travis_time:end:08d5687b:start=1530257638293772449,finish=1530257638303225967,duration=9453518
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:1dc8c752
$ head -30 ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
global:
global:
  _ZdaPv;
  _ZdaPvRKSt9nothrow_t;
  _ZdaPvSt11align_val_t;
  _ZdaPvSt11align_val_tRKSt9nothrow_t;
  _ZdaPvj;
  _ZdaPvjSt11align_val_t;
  _ZdlPv;
  _ZdlPvRKSt9nothrow_t;
  _ZdlPvSt11align_val_t;
  _ZdlPvSt11align_val_tRKSt9nothrow_t;
  _ZdlPvj;
  _ZdlPvjSt11align_val_t;
  _Znaj;
  _ZnajRKSt9nothrow_t;
  _ZnajSt11align_val_t;
  _ZnajSt11align_val_tRKSt9nothrow_t;
  _Znwj;
  _ZnwjRKSt9nothrow_t;
  _ZnwjSt11align_val_t;
  _ZnwjSt11align_val_tRKSt9nothrow_t;
  __asan_*;
  __cxa_atexit;
  __cxa_throw;
  __fprintf_chk;
  __getdelim;
  __interceptor___cxa_atexit;
  __interceptor___cxa_throw;
  __interceptor___fprintf_chk;
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:0060de60
$ dmesg | grep -i kill

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

1 similar comment
@rust-highfive
Copy link
Collaborator

The job dist-x86_64-linux of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
[01:10:30] [TIMING] Analysis { compiler: Compiler { stage: 2, host: "x86_64-unknown-linux-gnu" }, target: "x86_64-unknown-linux-gnu" } -- 3.058
[01:10:30] Dist src
[01:10:43] [TIMING] Src -- 12.640
[01:10:43] Create plain source tarball
[01:12:52] curl: (6) Couldn't resolve host 's3-us-west-1.amazonaws.com'
[01:14:44] curl: (6) Couldn't resolve host 's3-us-west-1.amazonaws.com'
[01:16:37] curl: (6) Couldn't resolve host 's3-us-west-1.amazonaws.com'
[01:16:37] thread 'main' panicked at 'failed to download openssl source: exit code: 6', bootstrap/native.rs:589:17
[01:16:37] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap dist --host x86_64-unknown-linux-gnu --target x86_64-unknown-linux-gnu
[01:16:37] Build completed unsuccessfully in 1:11:00
travis_time:end:0de3483f:start=1530253039615388785,finish=1530257636929458900,duration=4597314070115

---
travis_time:end:08d5687b:start=1530257638293772449,finish=1530257638303225967,duration=9453518
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:1dc8c752
$ head -30 ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
global:
global:
  _ZdaPv;
  _ZdaPvRKSt9nothrow_t;
  _ZdaPvSt11align_val_t;
  _ZdaPvSt11align_val_tRKSt9nothrow_t;
  _ZdaPvj;
  _ZdaPvjSt11align_val_t;
  _ZdlPv;
  _ZdlPvRKSt9nothrow_t;
  _ZdlPvSt11align_val_t;
  _ZdlPvSt11align_val_tRKSt9nothrow_t;
  _ZdlPvj;
  _ZdlPvjSt11align_val_t;
  _Znaj;
  _ZnajRKSt9nothrow_t;
  _ZnajSt11align_val_t;
  _ZnajSt11align_val_tRKSt9nothrow_t;
  _Znwj;
  _ZnwjRKSt9nothrow_t;
  _ZnwjSt11align_val_t;
  _ZnwjSt11align_val_tRKSt9nothrow_t;
  __asan_*;
  __cxa_atexit;
  __cxa_throw;
  __fprintf_chk;
  __getdelim;
  __interceptor___cxa_atexit;
  __interceptor___cxa_throw;
  __interceptor___fprintf_chk;
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:0060de60
$ dmesg | grep -i kill

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@kennytm
Copy link
Member

kennytm commented Jun 29, 2018

@bors retry travis-ci/travis-ci#9696

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 29, 2018
@bors
Copy link
Contributor

bors commented Jun 29, 2018

⌛ Testing commit be7f619 with merge 6e5e63a...

bors added a commit that referenced this pull request Jun 29, 2018
Add a fallback for stacktrace printing for older Windows versions.

Some time ago we switched stack inspection functions of dbghelp.dll to their newer alternatives that also capture inlined context.
Unfortunately, said new alternatives are not present in older dbghelp.dll versions.
In particular Windows 7 at the time of writing has dbghelp.dll version 6.1.7601 from 2010, that lacks StackWalkEx and friends.

Tested on my Windows 7 - both msvc and gnu versions produce a readable stacktrace.

Fixes #50138
@bors
Copy link
Contributor

bors commented Jun 29, 2018

☀️ Test successful - status-appveyor, status-travis
Approved by: alexcrichton
Pushing 6e5e63a to master...

@bors bors merged commit be7f619 into rust-lang:master Jun 29, 2018
Mark-Simulacrum added a commit to Mark-Simulacrum/rust that referenced this pull request Jan 3, 2019
Fix backtraces for inlined functions on Windows

Fixes an regression introduced in rust-lang#50526

r? @alexcrichton
kennytm added a commit to kennytm/rust that referenced this pull request Jan 5, 2019
Fix backtraces for inlined functions on Windows

Fixes an regression introduced in rust-lang#50526

r? @alexcrichton
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants