How to inspect WeakReference values with WinDBG/SOS and ClrMD? - windbg

I'm investigating a memory leak issue from production and retrieved a memory dump. I'm trying to dump the values of the accumulated object, the I met WeakReference. Here's what I got in WinDBG:
0:000> !do 000000011a306510
Name: System.WeakReference
MethodTable: 000007feeb3f9230
EEClass: 000007feeadda218
Size: 24(0x18) bytes
File: C:\Windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
Fields:
MT Field Offset Type VT Attr Value Name
000007feeb3f4a00 400068d 8 System.IntPtr 1 instance 343620e0 m_handle
0:000> !do 343620e0
<Note: this object has an invalid CLASS field>
Invalid object
We can find out that we cannot use the m_handle value as the object address. I've check the code of WeakReference and it's fully extern codes.
My question is, how can we inspect the value of it using WinDBG/SOS? Also, I'm writing ad-hoc analyzer for the problem with ClrMD, so how should I check the object references by the WeakReference object with it?

m_handle is an IntPtr which is a value type, so get the method table for IntPtrusing !name2ee *!System.IntPtr, then do
!dumpvc <method table of IntPtr> <value of m_handle>
This will give you the value the IntPtr points to. Since it points to an object, just dump that
!do <value of IntPtr>

Thanks Thomas for the answer.
Here's the code for getting the object address reference by an WeakReference object in ClrMD:
private static readonly ClrType WeakRefType = Heap.GetTypeByName("System.WeakReference");
private static readonly ClrInstanceField WeakRefHandleField = WeakRefType.GetFieldByName("m_handle");
private static readonly ClrType IntPtrType = Heap.GetTypeByName("System.IntPtr");
private static readonly ClrInstanceField IntPtrValueField = IntPtrType.GetFieldByName("m_value");
private static ulong GetWeakRefValue(ulong weakRefAddr)
{
var handleAddr = (long)WeakRefHandleField.GetValue(weakRefAddr);
var value = (ulong)IntPtrValueField.GetValue((ulong)handleAddr, true);
return value;
}
Hope it helps.

Related

Is there a way to associate a 'struct file' structure with 'struct platform_device'?

I'm writing a kernel module that has private attributes for each probed instance. When performing different file operations, is it possible to access that private data?
The private data I'm referring to is stored using:
void platform_set_drvdata(struct platform_device *, void *);
and would like to be able to access that data from, say, a read file operation:
static ssize_t read(struct file *, char __user *, size_t , loff_t *);
I feel as though I've asked this before, but can't find the question: Is there a way to map a struct file object to a struct platform_device object (preferably without resorting to global variables)?
EDIT
I looked through the drivers/platform directory of the kernel for an example of code that had struct file_operations object that had members using per-probed instance data. The code I found seemed rather circular.
As of writing this, my platform instance data object now contains a struct file_operations fops member, which, when the open() is called I use the container_of() macro to get my instance data.
In the probe() function, I do:
static int am_probe(struct platform_device *pdev) {
struct am_instance * instance = devm_kzalloc(dev, sizeof(struct am_instance), GFP_KERNEL);
...
/* am_fops is in .rodata (and not a pointer) */
instance->fops = am_fops;
rv = register_chrdev(0, instance->device_name, &instance->fops);
...
platform_set_drvdata(pdev, instance);
...
Then, in the open() method I do this:
static int am_open(struct inode *inode, struct file *file) {
file->private_data = container_of(file->f_op, struct am_instance, fops);
return 0;
}
The above works, in that from the read() function, I can access the instance data by examining the file->private_data field with an appropriate cast.

Object of type 'MyClass' cannot be converted to type 'System.Object[]' C#

I've been looking into this for a couple of hours but so far haven't gotten any luck.
Here's my C# code:
myClassInstance = new MyClass("MyParam", 1);
object[] args = new object[1] { myClassInstance };
MethodInfo methodInfo = GetType().GetMethod(myMethod, BindingFlags.NonPublic | BindingFlags.Instance);
string method = (string)methodInfo.Invoke(this, args);
I have MethodInfo and System.Reflection imported. The Unity error is this:
ArgumentException: Object of type 'SystemController' cannot be converted to type 'System.Object[]'
It doesn't point to a specific line in the code, but from what I can tell it seems to be an issue with converting the myClassInstance variable to an object, which doesn't make sense to me, as I believed everything in C# inherited from System.Object.
Here is MyClass:
public class MyClass
{
public string var1;
public int var2;
public MyClass(string param1, int param2)
{
var1 = param1;
var2 = param2;
}
}
Clearly, I'm not showing the entire class, but the only difference is that there are more variables and parameters to store. Those shouldn't change anything, so I won't bore you with them. It's just a class with a constructor, not inheriting from anything.
Any help I could get with this would be greatly appreciated. Let me know if you need more info.
The error here was me trying to pass the entire object[] array into my method as a parameter when I should have only passed the contents of the array. See here:
I was doing this:
void MyMethod(object[] args) {
MyClass instance = (MyClass)args[0];
...
}
But should've done this:
void MyMethod(MyClass myClassInstance) {
...
}
After reading some more documentation and reviewing the comments above I discovered that the .Invoke() method passes what's inside the args array instead of the entire array. At least, that's my current understanding, and it's what made my code work.
Thanks for the help.

Systemverilog const ref arg position when constructing an object

I am creating a class that needs a reference to the test bench's configuration object. Since the configuration must be intact throughout the simulation, I pass it as a const ref object. Here is a sudo code that I want to run:
class tb_config;
int unsigned rate;
int unsigned chnls[];
const int unsigned nb_chnls;
function new (int unsigned rate, int unsigned nb_chnls);
this.rate = rate;
this.nb_chnls = nb_chnls;
chnls = new[nb_chnls];
endfunction
endclass
class tx_phy;
static int phy_id;
tb_config cfg;
function new (int unsigned phy_id, const ref tb_config cfg);
this.phy_id = phy_id;
this.cfg = cfg;
endfunction
endclass
module test;
tb_config cfg = new(100, 4);
tx_phy phy = new( 1234, cfg);
endmodule
The code above works perfectly fine and it meets my expectation. But if I change the arguments in tx_phy::new to function new (const ref tb_config cfg, int unsigned phy_id); and pass the values to the constructor accordingly I get the following error in Cadence Incisive:
invalid ref argument usage because actual argument is not a variable.
Also same thing happens when I test it with Aldec in edaplayground: https://www.edaplayground.com/x/5PWV
I assume this is a language limitation, but is there any other reason for that??
The reason for this is because the argument kind is implicit if not specified. You specified const ref for the first argument, but nothing for the second argument, so it is also implicitly const ref. Adding input to the second argument declaration fixes this.
function new (const ref tb_config cfg, input int unsigned phy_id);
I also want to add const ref tb_config cfg is equivalent to writing
function new (tb_config cfg, int unsigned phy_id);
Both of these arguments are implicitly input arguments, which means they are copied upon entry.
A class variable is already a reference. Passing a class variable by ref means that you can update the handle the class variable has from within the function. Making the argument a const ref means you will not be able to update the class variable, but you can still update members of the class the variable references. There is no mechanism to prevent updating members of class object if you have a handle to it other than by declaring them protected or local.
The only place it makes sense to pass function arguments by ref in SystemVerilog is as an optimization when the arguments are large data structures like an array, and you only need to access a few of the elements of the array. You can use task ref arguments when the arguments need to be updated during the lifetime of the task (i.e. passing a clock as an argument).

MFC Classes CMAP

What I do not understand is the : “UINT&”. What does it mean in the context of the template
static CMap<CString, LPCSTR, UINT, UINT&> cXMLfields::fields_by_name;
static CMap<CString, LPCSTR, UINT, UINT&> cXMLfields::oopf_fields_by_name;
static CString friendly_name[XML_FIELDNUM];
static CString fields_by_id[XML_FIELDNUM];
static CString oopf_fields_by_id[OOPF_XML_FIELDNUM];
static void Build_map();
static void MoveItem(CListBox& src, CListBox& dst, int index);
CMap<CString,LPCTSTR, struct_sample,struct_sample> myMap;
struct_sample aTest;
aTest.a = 1;
aTest.b = 2;
aTest.c = 3;
myMap.SetAt("test",aTest);
struct_sample aLookupTest;
BOOL bExists = myMap.Lookup("test",aLookupTest); //Retrieves the
//struct_sample corresponding to "test".
I understand the theory, but my key is a String e.g “RFIDTAG1”.And my value is an unsigned integer. Example.UNIT is the Value to the Specific KEY ...for example {Age : 27} Where Age is the Key and 27 is the Value.I struggle when the value is an integer, I can understand if the value was a structure.So Can you use {Age: 27 } as the example and show me the code like below when using a structure
The & means pass by reference.
See this link.
Also here on MSDN.
ARG_VALUE
Data type used for VALUE arguments; usually a reference to VALUE.

Constant inside class

I've tried to create a vb scripts class with a constant and got 800A03EA error. It's it a VBS bug? Isn't it an OOP fundamental rule?
Class customer
' comment it const and its works
const MAX_LEN=70
Private Name
Private Sub Class_Initialize
Name = ""
End Sub
' name property.
Public Property Get getName
getName = Name
End Property
Public Property Let letName(p_name)
Name = p_name
End Property
end class
The documentation lists all statements that are allowed in the context of classes. Const isn't among them, so it's not supported. You can work around the issue by using private member variables that you initialize during instantiation (i.e. in Class_Initialize):
Class customer
Private MAX_LEN
Private Name
Private Sub Class_Initialize
MAX_LEN = 70
Name = ""
End Sub
...
End Class
If instances of the class should expose this value, you could implement it as a read-only property:
Class customer
Private MAX_LEN
Private Sub Class_Initialize
MAX_LEN = 70
End Sub
'read-only property, so no "Property Let/Set"
Public Property Get MaxLength
MaxLength = MAX_LEN
End Property
...
End Class
However, as Ekkehard.Horner pointed out correctly, the value could still be changed by object-internal code. If immutability is the primary requirment for this value you should implement it as a global constant.
I agree with Ansgar Wiechers's answer, but would like to propose another option.
If immutability is more important than performance, you could put the value directly in the Get and use the property to refer to the value instead of a class-level variable.
Class customer
'read-only property, so no "Property Let/Set"
Public Property Get MaxLength
MaxLength = 70
End Property
...
End Class
A Private variable (perhaps with a getter) gives you a value that is read-only from the outside of the class, but class internal code can still change that value.
So using a global Const (perhaps with a 'namespace' name part) may be a better workaround in cases where the constness is most important.