question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

RemoteExecutor Swallows Errors and Throws Invalid Exceptions

See original GitHub issue
  • This issue is blocking
  • This issue is causing unreasonable pain

I could be holding it wrong but it does not seem to be working as expected.

Microsoft.DotNet.RemoteExecutor Version 6.0.0-beta.20508.3 (Are there non beta version available?)

Installed via https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json

The following method runs without any assertation exceptions. I would expect it to fail.

            RemoteExecutor.Invoke(() =>
            {
                 Assert.True(false);
            }).Dispose();

The following code throws an exception. I would expect none.

            RemoteExecutor.Invoke(() =>
            {
                 return RemoteExecutor.SuccessExitCode;
            }).Dispose();

Message: Exit code was -2147450749 but it should have been 42 Expected: True Actual: False Stack Trace: RemoteInvokeHandle.Dispose(Boolean disposing) line 237 RemoteInvokeHandle.Dispose() line 58

Issue Analytics

  • State:open
  • Created 3 years ago
  • Comments:43 (29 by maintainers)

github_iconTop GitHub Comments

3reactions
ViktorHofercommented, Oct 10, 2020

Thanks for reporting @JimBobSquarePants and @vitek-karas for the analysis. Vitek is right that RemoteExecutor doesn’t set HostRunner (the path to the host to invoke) to the right value in cases where VSTest’s apphost is used. This didn’t show up for us in dotnet/runtime as we don’t use VSTest’s apphost feature as we supply our custom host.

As a simple fallback mechanism we could check if processFileName ends with (dotnet[.exe]) and if not, use the dotnet in the %PATH%.

For a more complete implementation, we should follow what Vitek proposes:

It should be using dotnet.exe - but this will be tricky because it will need to pick the right one. The best way would probably be to use location of the runtime running the test (this will be tricky to get completely right with single-file, but it’s possible).

An implementation of that could look like this:

  1. Retrieve the location of the shared framework assemblies currently being used by the process.
  2. Climb up the directory tree until a dotnet host is found.
  3. If none is found, use the one in the PATH.

@vitek-karas do you think we should stop at some point climbing up the directory tree? For self-contained application we need to fallback to %PATH% as a self-contained application doesn’t have a dotnet host. Right?

3reactions
vitek-karascommented, Oct 10, 2020

Thanks - I was able to repro it locally.

The command line it executes doesn’t seem to make sense to me:

F:\AppModel\repro\RemoteExecutorTests\ExecutorTest\bin\Debug\netcoreapp3.1\testhost.exe 
exec 
--runtimeconfig "F:\AppModel\repro\RemoteExecutorTests\ExecutorTest\bin\Debug\netcoreapp3.1\ExecutorTest.runtimeconfig.json" 
--depsfile "F:\AppModel\repro\RemoteExecutorTests\ExecutorTest\bin\Debug\netcoreapp3.1\ExecutorTest.deps.json" 
"F:\AppModel\repro\RemoteExecutorTests\ExecutorTest\bin\Debug\netcoreapp3.1\Microsoft.DotNet.RemoteExecutor.dll"
<args to the remote executor - not interesting>

This would work if it were running “dotnet.exe exec …”, but I doubt testhost recognizes “exec” (I could be wrong though).

In any case the command line won’t work because the special host parameters must be first on the command line: --runtimeconfig and so on. Since testhost.exe is an apphost it doesn’t inherently recognize exec on the host level, and so it runs itself as if there were no special parameters on the command line. And thus it tries to read the file testhost.runtimeconfig.json which doesn’t exist (the valid=[1] is misleading, internally the host treats missing runtime config as valid) - so it ends up with empty runtime config which means no framework references and thus tries to run as self-contained - which it’s not and so on.

I tried running the same command line via dotnet.exe exec and that works (well at least it runs the code).

I don’t know how this passes tests (if they run) in Arcade repo and/or how it’s used in a case where it would actually work. But as is, this seems completely broken.

Also - I which we could update the testhost.exe to some “recent” version, it’s 2.1 (I know we probably need it to be able to run 2.1 tests, unfortunately). In this case it means that the tracing from the testhost.exe is not visible in the trace file since it doesn’t recognize COREHOST_TRACEFILE which was added in 3.0.

I think somebody from Arcade should comment on what is the intended command line. I can definitely help with figuring out what it should be in reality to get all the desired behaviors.

Couple of notes about what I think it SHOULD be doing:

  • Using testhost.exe won’t work because that is the VS test host runner, it does not support running the executor dll as a command line app
  • It should be using dotnet.exe - but this will be tricky because it will need to pick the right one. The best way would probably be to use location of the runtime running the test (this will be tricky to get completely right with single-file, but it’s possible).

The break was probably introduced by changes to the VSTest platform - some time ago it switched from running the test via “dotnet.exe” to using the “testhost.exe”. But that’s been quite a while now if I remember correctly.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Why are Java Errors swallowed on threads spawned by an ...
It's not swallowed, it's there: public static void main(String[] args) { ExecutorService executor = Executors.
Read more >
Error hiding
In computer programming, error hiding (or error swallowing) is the practice of catching an error or exception, and then continuing without logging, ...
Read more >
Do Not Swallow The Exceptions | Justin James
Here are a couple of examples of what I am talking about when I say swallowing the exception. Example 1: Totally Throwing Away...
Read more >
To throw an exception or not to throw an exception : r/dotnet
Use validation for user input and return status code 400 if user made mistake with user friendly message to help user to fix...
Read more >
All Classes (Atlassian Confluence 8.2.0-m27 API)
A simple return type representing the state where a user (logged in our anonymous) does not have access to Confluence or a given...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found