Skip to content
This repository has been archived by the owner on Nov 1, 2020. It is now read-only.

Implement break opcode as llvm.debugtrap #5344

Merged
merged 4 commits into from
Feb 7, 2018
Merged

Conversation

Blealtan
Copy link
Contributor

@Blealtan Blealtan commented Feb 3, 2018

Implemented break opcode as llvm.debugtrap. Not adding any test cases since it seems that no C# codes generates break opcode directly.

In Emscripten, `llvm.debugtrap` is implemented as a round-trip call to
`debugger;` statement JavaScript which will invoke debugger in browsers;
and in LLVM it's implemented as `unreachable` instruction of WASM. This
should be a better match than `llvm.trap` on `break` opcode semantics.

Fix dotnet#4511
@Blealtan Blealtan changed the title Implement break opcode as llvm.debugtrap. Implement break opcode as llvm.debugtrap Feb 3, 2018
@hippiehunter
Copy link
Contributor

There is an IL section (cpobj) of the hellowasm test that you can bolt on a test for this.

I'm more than a little curious what the experience is like when running this instruction in WASM.

@morganbr
Copy link
Contributor

morganbr commented Feb 4, 2018

A good way to both test this and make it useful could be to make Debugger.Break() work. It calls into Debugger.DebugBreak, which is an intrinsic that gets a generated break opcode.

The logic currently checks IsDebuggerPresent, which is hardcoded to false in the Unix PAL

extern "C" UInt32_BOOL IsDebuggerPresent()
{
// UNIXTODO: Implement this function
return UInt32_FALSE;

If that were changed to true for WASM, I think there wouldn't be any other problems. To include a test for this in HelloWasm, we'd have to be sure it wouldn't break if a debugger isn't attached so we don't lock up the test.

@Blealtan
Copy link
Contributor Author

Blealtan commented Feb 4, 2018

@hippiehunter As I've mentioned in #4511 , in Emscripten it's implemented as a round-trip call to statement debugger; in JS, and in LLVM it's simply implemented as WASM instruction unreachable. For now we're using Emscripten, and browser will pause at the debugger; statement if devtools window is opened (I've tested in Firefox and Chrome, my Edge DevTools is broken unexpectedly).

@morganbr Testing if a debugger is present by our self seems to be unnecessary: both Firefox and Chrome only pauses at debugger; statement when devtools window is opened. We can always assume that there is a debugger attached, since if not, it'll neither lock up the test. I'll try on that.

@Blealtan
Copy link
Contributor Author

Blealtan commented Feb 4, 2018

@morganbr It works, Debugger.Break() compiles and only pauses the execution with developer windows opened once changed the line you mentioned. However, this is also used by the Unix port which has not implementated debugger, right? Maybe we'd add a conditional compilation for WASM?

@Blealtan
Copy link
Contributor Author

Blealtan commented Feb 4, 2018

Another problem is, how will we deal with Debugger._isDebuggerAttached? It's said that the debugger is responsible to set it true, but WASM debugger is obviously not implemented with CoreRT in mind, and we have no way to know whether a debugger is attached (that is, devtools window opened). Maybe always set it to true since debugger; in JS itself doesn't function without debugger attached?

@morganbr
Copy link
Contributor

morganbr commented Feb 6, 2018

Good question. on further thought, maybe Debugger.Break should just conditionally not call IsDebuggerPresent. I think you should be able to use #if WASM. We might be able to come back to Debugger._isDebuggerAttached by writing some Javascript for it, but from a quick search, I get the impression it varies by browser and might be a bit fragile.

@Blealtan
Copy link
Contributor Author

Blealtan commented Feb 6, 2018

It seems that Debugger.Break assumes Debugger._isDebuggerAttached is always true in case of IsDebuggerPresent returns true according to the comments there. Anyway I'll test the #if WASM and if okay, commit it here.

@Blealtan
Copy link
Contributor Author

Blealtan commented Feb 6, 2018

#if WASM doesn't work, neither does #ifdef WASM. Is this the correct macro name? Or similar macro by now doesn't exist?

@jkotas
Copy link
Member

jkotas commented Feb 6, 2018

It is #ifdef _WASM_

Set IsDebuggerPresent to TRUE in case of WASM. Although
`Debugger._isDebuggerAttached` is not set, this modify itself will allow
`Debugger.Break` to work.
Copy link
Contributor

@morganbr morganbr left a comment

Choose a reason for hiding this comment

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

Looks good. I've tested it in Edge, Firefox and Chrome and it stops under their debuggers and not without them.

@morganbr morganbr merged commit eba7180 into dotnet:master Feb 7, 2018
@morganbr
Copy link
Contributor

morganbr commented Feb 7, 2018

Thanks, @Blealtan! I can already tell this will be incredibly useful for debugging until we have more complete debugger support. In particular, this makes the Chrome debugger really useful since it has the best WASM function output, but no search. Using this, we can put Debugger.Break() in interesting places without having to figure out what number every function ended up with.

Can I interest you in picking up another issue next?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants