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

Fix refcount when a composite r2r image is loaded from a bundle #61066

Merged
merged 2 commits into from
Nov 3, 2021
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions src/coreclr/vm/nativeimage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,14 +141,17 @@ NativeImage *NativeImage::Open(
LPWSTR searchPathsConfig;
IfFailThrow(CLRConfig::GetConfigValue(CLRConfig::INTERNAL_NativeImageSearchPaths, &searchPathsConfig));

NewHolder<PEImageLayout> peLoadedImage;
PEImageLayoutHolder peLoadedImage;

BundleFileLocation bundleFileLocation = Bundle::ProbeAppBundle(fullPath, /*pathIsBundleRelative */ true);
if (bundleFileLocation.IsValid())
{
PEImageHolder pImage = PEImage::OpenImage(fullPath, MDInternalImport_Default, bundleFileLocation);
peLoadedImage = pImage->GetOrCreateLayout(PEImageLayout::LAYOUT_MAPPED);
peLoadedImage.SuppressRelease();
// No need to use cache for this PE image. It is transient.
// We only need it to obtain the native image, which AppDomain will keep.
PEImageHolder pImage = PEImage::OpenImage(fullPath, MDInternalImport_NoCache, bundleFileLocation);
PEImageLayout* mapped = pImage->GetOrCreateLayout(PEImageLayout::LAYOUT_MAPPED);
mapped->AddRef();
peLoadedImage = mapped;
Copy link
Member

Choose a reason for hiding this comment

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

My reading of the issue is that we were using NewHolder instead of PEImageLayoutHolder/ReleaseHolder, which meant that SuppressRelease wouldn't prevent the delete when the NewHolder went out of scope.

We could have switched to PEImageLayoutHolder and kept what this was doing before (using SuppressRelease). However, with the switch to calling PEImage::OpenImage with MDInternalImport_NoCache, the pImage will not be cached, so it (and therefore the layout created through GetOrCreateLayout) will be released once it goes out of scope - hence we need to do the AddRef instead so that we keep the PEImageLayout around without the PEImage.

Is that correct?

Copy link
Member

Choose a reason for hiding this comment

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

If so, it might be worth having an explicit comment around that. My initial reaction looking at this was that it would make more sense to keep with the SuppressRelease (instead of the explicit AddRef and let the holder release) - before I saw the implications of the switch to MDInternalImport_NoCache.

Copy link
Member Author

@VSadov VSadov Nov 2, 2021

Choose a reason for hiding this comment

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

We could have switched to PEImageLayoutHolder and kept what this was doing before (using SuppressRelease).

Yes, that would work too. SuppressRelease would effectively "leak" the PE image and that would keep the layout alive. We would not have a way to free the layout, but in this case it would be ok.

On the other hand we only need this PE image to get the layout and we will not be doing that again, since AppDomain caches the native image. I figured I'd rather take the ownership of the layout (by doing AddRef) and let PE image instance be freed.

Using cache is not required here since composite r2r PE is not a part of anyone's identity.
Since we will open the image only once anyways, I just thought we should not involve the cache, regardless if we keep/leak PE image or not.

Copy link
Member Author

Choose a reason for hiding this comment

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

I will add a better comment about the whole deal.

Copy link
Member Author

Choose a reason for hiding this comment

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

Added comments.

}

if (peLoadedImage.IsNull())
Expand Down