-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Some questions about profiler API #9685
Comments
@noahfalk FYI |
Hi @ww898 , very sorry I hadn't noticed this one earlier.
As an official .NET API, the solutions appear limited. You could determine that the address of the static was itself on the GC heap and then use the GC heap callbacks to detect when the containing object was collected. Although enumerating the GC heap can be fairly heavyweight it sounds like you may already be collecting this information.
Are you asking whether this is true, or requesting us to guarantee it remains true as part of the runtime contract with profilers, something else? I don't know this particular detail though @Maoni0 probably does.
Are you referring to the ICorProfilerCallback::ObjectReferences API or something else?
Have you looked at the layout related APIs such as: These APIs should already let you determine the offsets where individual fields are stored, or the array indices for array elements. If you don't feel these APIs are sufficient to accomplish your goals we should chat a little more about what you are trying to do and why these APIs didn't work for you. Similar to your first question I don't think there is good support specifically for the reference to the LoaderAllocator used in collectible assemblies. By process of elimination you could determine that there is a reference reported from ObjectReferences() that doesn't exist in any of the defined slots in the layout and then infer the meaning of this extra runtime added field, but certainly its not an ideal API design.
We can create a feature request. Two questions that come to mind: To set expectations, creating the feature requests doesn't necessarily mean the runtime will start working on them, we still have to prioritize with many other requests that we get. However even if we don't build them, we can also offer advice for anyone in the community who is interested in working on it. |
this is a very vague statement. if you could explain why you expect this and what kind of guarantee you are looking at it would be helpful. |
Hi @noahfalk, thank you for so full answers
Oh, great. The unofficial solution looks like a bit complicated but it should work. Here is the feature request to make the solution much simpler: https://github.com/dotnet/coreclr/issues/17228
Yes, I expect that you can officially grant that for nearest future. :-) On my opinion, the main problem is a bit common. We only have
Yes, I'm using
So, this is the reason to ask to extend profiling API: add indexes for arrays in |
I think there was (and may still be?) some confusion about what property of the runtime you are asking us to guarantee. I originally misunderstood which lead to me pulling in Maoni. My current understanding is this is property you are hoping for: "the reference reported in the objectRefIds[x] of the ICorProfilerCallback::ObjectReferences call is the reference that is stored in array index X of the managed object." That's probably true when dealing with an array of a reference type, but I'm going to suggest there is a different and more complete invariant you could rely on that is already part of the official documentation of GetArrayObjectInfo: Does that seem like a workable scheme to match up references (or other values) to the array indicies which hold the data without needing to make guarantees about ObjectReferences() behavior? |
@noahfalk @Maoni0 I think we are speaking about a bit different things. I'm speaking about the order in outgoing references in However, It would be great the separate method, like |
I'd suggest if we want to make improvements, lets make improvements that will solve these type loading problems. It sounds like there are potentially two issues that forcing you to use ObjectReferences:
Although I was hoping to find a path that avoids the dependency, I think its safe to rely on at least for the forseeable future. There is a risk that we might add references you didn't expect to the beginning or end of the list (such as the LoaderAllocator for collectible types), but I can't see any reason why we would ever need to change the relative order of references from different array indicies.
My concern going down this route is that it doesn't appear array index would be sufficient to fully satisfy the scenario, and that it would degenerate into wanting ObjectReferences to give you all of the qualifiers necessary to distinguish one reference from another. For example if we had:
If I understand you correctly, you ideally want to know that a particular reference represents arr1[5,6].b.c, but the API wouldn't be able to represent [5,6].b.c with a single number. As a partial solution/workaround for now its probably easier to simply rely on the ordering of ObjectReferences. |
We collect statistics about field resolving. I promise to make the report about that.
Well, could you please add the markers for virtual references in
Yes, you are right. It would be great when I can easily associate reference from array or object with specific field. This way surely creates some additional problems. For example: how can I get parent fields for three nested structures (
I think that the array element index will realy help, because there are a lot large arrays with references in applications, but structures or classes with hundreds or thousands fields with references are very rare (except generators). On my opinion, there is the simple way to convert the element index from array's memory to the logical single or multidimensional indexes surely with
On the other side our profiler doesn't translate element memory indexes to logical indexes - this is the UI work. |
Just continuing to think about this a bit, what if we put the memory offset in the object where we read the reference from into the callback information (or a sentinel value -1 if the reference was implicitly computed and has no backing memory). For example the callback might return:
Using GetArrayObjectInfo, IsArrayClass, and GetClassLayout you should be able to determine the memory ranges where all the top-level array elements reside, even if you are unable to decipher the layout of their inner fields within that range. Together with the offsets you could now quickly bucket all the references that correspond to each array element using a single pass through the results. A few reasons I suggest offsets vs. other ways of describing the references:
|
@noahfalk Cool! That's what I need! |
Closing since it seems the question was answered |
Our profiler excavates static variable values during the GC finished event and everything works perfectly till the GC where the first collectible assembly was silently unloaded. And we get crash after that. Now we disabled static variables for collectible assemblies. How to detect the moment during GC after that I can understand that the module was collected?
Our profiler gathers field names information in every object and assign it to incoming references. It's a bit complicated algorithm which depends on some current CLR undocumented behavior. The most important is: I expect that you process arrays from lower index to high one during GC. I did it because the alghoritm is O(x^2) and it's very very slow for large arrays.
The last one trouble is virtual references in objects from collectible assemblies. CLR add the virtual reference to
System.Reflection.LoadAllocator
object as first element of array of references in profiling API. It works for array types and most object types except following types and its inheritors (because there is the reflection in native for manages fields):System.RuntimeType
seem_keepalive
System.Reflection.RuntimeAssembly
seem_syncRoot
System.Delegate
see_methodBase
Could you please make our live more simple - extend profiler API to get ability to get additional information for references such as:
ModuileID
+mdTypeRef
toModuleID
+mdTypeDef
.The text was updated successfully, but these errors were encountered: