Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Ensure Environment.ExitCode works correctly after app domain unloaded.#10842

Merged
jkotas merged 5 commits intodotnet:masterfrom
mazong1123:fix-6206
Apr 13, 2017
Merged

Ensure Environment.ExitCode works correctly after app domain unloaded.#10842
jkotas merged 5 commits intodotnet:masterfrom
mazong1123:fix-6206

Conversation

@mazong1123
Copy link

This PR addresses 2 problems of Environment.ExitCode:

  1. Can't get correct exit code of main function.
  2. Can't set %errorlevel%.

Details can be found on #6206

Fix #6206

This PR addresses 2 problems of Environment.ExitCode:

1. Can't get correct exit code of main function.
2. Can't set %errorlevel%.

Details can be found on #6206

Fix #6206
@mazong1123 mazong1123 changed the title Ensure Enironment.ExitCode works correctly after app domain unloaded. [WIP]Ensure Enironment.ExitCode works correctly after app domain unloaded. Apr 10, 2017
@mazong1123 mazong1123 changed the title [WIP]Ensure Enironment.ExitCode works correctly after app domain unloaded. Ensure Enironment.ExitCode works correctly after app domain unloaded. Apr 10, 2017
@mazong1123
Copy link
Author

@jkotas Could you please review this PR? Thanks.

@mazong1123
Copy link
Author

@dotnet-bot test Tizen armel Cross Release Build please

@mazong1123
Copy link
Author

@dotnet-bot test OSX10.12 x64 Checked Build and Test please

CORECLR_HOSTING_API(coreclr_shutdown,
void* hostHandle,
unsigned int domainId);
unsigned int domainId,
Copy link
Member

Choose a reason for hiding this comment

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

I don't think we can change the signature of the existing hosting API. There are other Microsoft projects like dotnet cli and possibly also community projects using the current APIs and this would break them. It seems that we need to create a new version of coreclr_shutdown with the added latchedExitCode and keep the old one unchanged. Named e.g. coreclr_shutdown_2.

Copy link
Author

@mazong1123 mazong1123 Apr 10, 2017

Choose a reason for hiding this comment

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

@janvorli Should I do the same change on ICLRRuntimeHost::UnloadAppDomain (keep the old one, add a new ICLRRuntimeHost::UnloadAppDomain2)? I found somewhere out of unixinterface.cpp calling this method as well so I have to add a default value to pLatchedExitCode. If this interface is used by other projects we probably have to keep the old signature.

Copy link
Member

Choose a reason for hiding this comment

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

Right, you cannot modify the ICLRRuntimeHost methods either. This is a COM interface and by COM rules, you need to add a new version of the whole interface, called ICLRRuntimeHost4 (there already is ICLRRuntimeHost3) and put the new method on it.

Copy link
Author

@mazong1123 mazong1123 Apr 11, 2017

Choose a reason for hiding this comment

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

@janvorli I went through the code from coreclr initialization to shutdown. It seems like we need more efforts to address this issue. Therefore I just write down the design here before diving to the code. Please correct me if anything is incorrect.

Current process of executing a managed assembly:

  1. In ExecuteManagedAssembly, coreclr_initialize is called to initialize the hostHandle.
  2. in coreclr_initialize , a CorHost2 object created, who implemented interface ICLRRuntimeHost2, and a pointer to ICLRRuntimeHost2 is assigned to hostHandle.
  3. In ExecuteManagedAssembly, coreclr_execute_assembly is called with hostHandle passed in.
  4. In coreclr_execute_assembly, hostHandle is cast to ICLRRuntimeHost2.
  5. In ExecuteManagedAssembly, coreclr_shutdown is called with hostHandle passed in.
  6. In coreclr_shutdown, hostHandle is cast to ICLRRuntimeHost2.

To fix the Environment.ExitCode issue while keeping ICLRRuntimeHost2 not being changed, I'm going to:

  1. Create a new COM interface ICLRRuntimeHost4 which introduces a new UnloadAppDomain method with latchedExitCode as its last parameter.
  2. Create a CorHost4 class which implements ICLRRuntimeHost4.
  3. Create coreclr_initialize_2, coreclr_execute_assembly_2 and coreclr_shutdown_2 functions. They have same logic as coreclr_initialize, coreclr_execute_assembly and coreclr_shutdown but use CorHost4 and ICLRRuntimeHost4 instead.

Copy link
Member

Choose a reason for hiding this comment

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

You should not need to create CorHost4 . The new interface can be implemented by CorHost2 just fine. Also, you should not need to create coreclr_initialize_2 or coreclr_execute_assembly_2. coreclr_shutdown_2 is the only one needed.

@jkotas jkotas changed the title Ensure Enironment.ExitCode works correctly after app domain unloaded. Ensure Environment.ExitCode works correctly after app domain unloaded. Apr 10, 2017
unsigned int domainId,
int* latchedExitCode)
{
ICLRRuntimeHost4* hostHandleV4 = nullptr;
Copy link
Member

Choose a reason for hiding this comment

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

Instead of this query interface here, could you please change all references in this file from ICLRRuntimeHost2 to ICLRRuntimeHost4?

Copy link
Author

@mazong1123 mazong1123 Apr 12, 2017

Choose a reason for hiding this comment

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

Sure, I've changed them.

@mazong1123
Copy link
Author

@dotnet-bot test Tizen armel Cross Debug Build please
@dotnet-bot test Tizen armel Cross Release Build please

END_ENTRYPOINT_THROWS;

// Sync the latched exit code with the return value of main function.
SetLatchedExitCode(iRetVal);
Copy link
Member

Choose a reason for hiding this comment

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

Is this really needed?

It will incorrectly overwrite latched exit code for non-void returning functions.

https://github.com/mazong1123/coreclr/blob/0c46640307dab1d8359f4e3b856a4390d9a6389d/src/vm/assembly.cpp#L1854 should take care of it for non-void returning main.

Copy link
Author

@mazong1123 mazong1123 Apr 13, 2017

Choose a reason for hiding this comment

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

The condition in following line will be false so that L1854 won't be executed at least for this example :
https://github.com/mazong1123/coreclr/blob/0c46640307dab1d8359f4e3b856a4390d9a6389d/src/vm/assembly.cpp#L1852

I don't know why we're checking the stringArgs here so I have to sync the latched exit code outside. Seems like we should remove the check. Do you have any idea about this line of code?

Copy link
Member

Choose a reason for hiding this comment

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

Seems like we should remove the check

Agree.

Could you please also verify that the following program will have exit code 123?

using System;

class My {
    static void Main() {
        Environment.ExitCode = 123;
    }
}

Copy link
Author

Choose a reason for hiding this comment

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

I just ran the sample program and echo $? gave me 123. Note I've removed the check and my sync code before testing. So it works.

@jkotas
Copy link
Member

jkotas commented Apr 12, 2017

BTW: Once this goes through, we will also need to update the nuget aware dotnet host (https://github.com/dotnet/core-setup/blob/master/src/corehost/cli/coreclr.cpp) to use the new method when it is available.

@mazong1123
Copy link
Author

mazong1123 commented Apr 13, 2017

@jkotas Do we need a shutdown2 method instead of updating the method shutdown? I guess we need a coreclr_shutdown_2_fn as well?

@jkotas
Copy link
Member

jkotas commented Apr 13, 2017

Do we need a shutdown2 method instead of updating the method shutdown?

Updating shutdown should do the trick.

I guess we need a coreclr_shutdown_2_fn as well?

Agree.

@mazong1123
Copy link
Author

@jkotas I've fired a new issue here: https://github.com/dotnet/core-setup/issues/2050

I'll work on that once this PR merged.

Copy link
Member

@jkotas jkotas left a comment

Choose a reason for hiding this comment

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

LGTM. Thanks!

@jkotas jkotas merged commit 5e138a6 into dotnet:master Apr 13, 2017
@jkotas
Copy link
Member

jkotas commented Apr 13, 2017

I have just noticed that we have not unified the Windows and Unix corerun yet, and the Windows one still goes through the interface. Could you please also update these to use ICLRRuntimeHost4 ?

https://github.com/dotnet/coreclr/blob/master/src/coreclr/hosts/corerun/corerun.cpp
https://github.com/dotnet/coreclr/blob/master/src/coreclr/hosts/coreconsole/coreconsole.cpp

@mazong1123
Copy link
Author

@jkotas I created a new issue #10960 to track this change. I'll submit a new PR accordingly. Sorry for missing the Windows change.

@mazong1123 mazong1123 deleted the fix-6206 branch April 19, 2017 13:29
jkotas pushed a commit that referenced this pull request Apr 19, 2017
)

* Change ICLRRuntimeHost2 to ICLRRuntimeHost4 for Windows corerun.

Since we've introduced ICLRRuntimeHost4 in PR #10842 for Unix, we apply it for Windows corerun as well.

Fix #10960
@karelz karelz modified the milestone: 2.0.0 Aug 28, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants