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

Support WhereRefBind log entries #24

Closed
KirillOsenkov opened this issue Mar 25, 2021 · 10 comments · Fixed by #25
Closed

Support WhereRefBind log entries #24

KirillOsenkov opened this issue Mar 25, 2021 · 10 comments · Fixed by #25

Comments

@KirillOsenkov
Copy link

I've been using Fusion++ today, it's a great tool!

I noticed that it looks like it may not support all entries. Specifically if I run fuslogvw.exe and specify log all binds to disk, I may get files with this format: WhereRefBind!Host=(LocalMachine)!FileName=(Microsoft.Build.NuGetSdkResolver.dll).htm

These don't seem available in Fusion++.

To get a repro:

  1. git clone https://github.com/dotnet/msbuild (assuming you cloned into C:\MSBuild), checkout main as of 2021-03-24 (e.g. dotnet/msbuild@bf0b0c5)
  2. build -bl /p:CreateBootstrap=true
  3. C:\msbuild\artifacts\bin\bootstrap\net472\MSBuild\Current\Bin\MSBuild.exe /r C:\temp\net472\net472.csproj where net472.csproj is any dotnet C# project. Note /r is important as the codepaths involve NuGet

Run step 3 under fuslogvw and Fusion++ and compare the results.

dotnet/msbuild#6289 is the issue we're investigating. Looks like we first load an assembly using Assembly.LoadFrom(), which loads it into the LoadFrom context, then we load the same .dll into the default load context, so we have two copies of the assembly loaded from two different codepaths, then we get the exception.

@awaescher
Copy link
Owner

Whoa, great spot. I will have a look at this soon.
Thanks for the feedback.

@awaescher
Copy link
Owner

Fusion++ checks if it was able to parse log entries by looking if the corresponding entry has a DisplayName.

This is okay for "ordinary" logs like this:

=== Zustandsinformationen vor Bindung ===
LOG: DisplayName = System.Xml.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
 (Fully-specified)
LOG: Appbase = file:///D:/Develop/GitHub/msbuild/artifacts/bin/bootstrap/net472/MSBuild/Current/Bin/
LOG: Ursprünglicher PrivatePath = NULL
LOG: DynamicBase = NULL
LOG: CacheBase = NULL
LOG: AppName = MSBuild.exe
Aufruf von Assembly : Microsoft.Build.Tasks.Core, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a.
===

See DisplayName = System.Xml.Linq ...

For Where-Ref binds, there's no DisplayName. That's why Fusion++ sorts them out.


=== Zustandsinformationen vor Bindung ===
LOG: Where-ref-Bindung. Speicherort = D:\Develop\GitHub\msbuild\artifacts\bin\bootstrap\net472\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\tools\net472\Microsoft.NET.Build.Extensions.Tasks.dll
LOG: Appbase = file:///D:/Develop/GitHub/msbuild/artifacts/bin/bootstrap/net472/MSBuild/Current/Bin/
LOG: Ursprünglicher PrivatePath = NULL
LOG: DynamicBase = NULL
LOG: CacheBase = NULL
LOG: AppName = MSBuild.exe
Aufruf von Assembly : (Unknown).
===

What would you say could be the DisplayName for Where-Ref bindings?

image

@awaescher
Copy link
Owner

awaescher commented Apr 11, 2021

What do you think about this?

image

for

image

awaescher added a commit that referenced this issue Apr 11, 2021
@KirillOsenkov
Copy link
Author

This is perfect! Thanks so much!

@awaescher
Copy link
Owner

Version 1.4 was just released 🎉

Thank you for the feedback, Kirill.

@Eruvisu
Copy link

Eruvisu commented Jun 28, 2021

Can someone tell me what "Where-ref bindings" are? Or where can I find some information about it?
I searched a bit on the internet but I wasn't able to find anything.
I have an issue with one dll where it searches for it in the probing paths and it doesn't find it but then it finds it using 'where-ref'.
And then for the same dll in another application it doesn't use where-ref. It just searches for it in the probing paths and it doesn't find it and that's it.
I used Fusion++ v1.4.

@KirillOsenkov
Copy link
Author

Maybe @davkean knows?

@davkean
Copy link

davkean commented Jun 29, 2021

WhereRef binds are situations where the assembly name hasn't been set; think Assembly.LoadFrom("foo.dll").

@Eruvisu
Copy link

Eruvisu commented Jul 1, 2021

Thanks @davkean for the explanation.

@abelbraaksma
Copy link

WhereRef binds are situations where the assembly name hasn't been set; think Assembly.LoadFrom("foo.dll").

Indeed. There are four load contexts (load, load-from, reflection-only, no context). But both LoadFrom and Load(Byte[]) do not provide a name and, unless they were already loaded from a known location previously, they will end up in the load-from context (for found filenames) or no context (for byte arrays). The latter is also true for on-the-fly user-generated assemblies.

Some more info is hidden under the Remarks section here: https://docs.microsoft.com/en-us/dotnet/api/system.reflection.assembly.loadfrom?view=net-6.0#system-reflection-assembly-loadfrom(system-string).

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

Successfully merging a pull request may close this issue.

5 participants