dotnet / dotnet/diagnostics

[Linux] How to view static fields of generics in SOS?

Open
#50 0 comments 0 reactions 1 assignee Claimed by @mikem8361 View on GitHub
Dominant language
C++
Stars
1.3k
Forks
404
Avg merge
2d 5h
Merged PRs (30d)
35

Description

@ayuckhulk commented on [Mon May 29 2017](https://github.com/dotnet/coreclr/issues/11960)

Consider the following code:
```
class Program
{
public static void Main()
{
S1 s1 = new S1();
s1.bar = 2;
}

public class S1
{
public static int fooInt = 99;
public T bar;
}
}

```

I'd like to view the value of `s1.fooInt`. However, SOS plugin for lldb does not show its value or native address:
```
(lldb) sos ClrStack -i s1

Dumping managed stack and managed variables using ICorDebug.
=============================================================================
Child SP IP Call Site
00007FFFFFFFC340 00007fff7d7408dd [DEFAULT] Void Program.Main() (/home/i.kulaychuk/work/overlay/Program.dll)

PARAMETERS: (none)

LOCALS:
+ Program+S1`1<int> s1 @ 0x7fff580337d0
|- < unknown type > fooInt
|- int bar = 0

00007FFFFFFFC360 00007ffff62a1f87 [NativeStackFrame]
Stack walk complete.
=============================================================================
```

```
(lldb) sos DumpObj 0x00007fff580337d0
Name: Program+S1`1[[System.Int32, System.Private.CoreLib]]
MethodTable: 00007fff7c196b00
EEClass: 00007fff7d792808
Size: 24(0x18) bytes
File: /home/i.kulaychuk/work/overlay/Program.dll
Fields:
MT Field Offset Type VT Attr Value Name
00007fff7d471740 4000002 8 System.Int32 1 instance 0 bar
00007fff7d471740 4000001 10 System.Int32 1 static dynamic statics NYI fooInt
(lldb)
```

The command `sos ClrStack -i s1` uses ICorDebug API `ICorDebugType::GetStaticFieldValue` to show static fields (see https://github.com/dotnet/coreclr/blob/master/src/ToolBox/SOS/Strike/strike.cpp#L11734). But for some reason it does not work for dynamic statics.
Is it a bug? Is there any other way to get dynamic static fields?

CC @jkotas, @janvorli, @mikem8361, @Dmitri-Botcharnikov

---

@jkotas commented on [Mon May 29 2017](https://github.com/dotnet/coreclr/issues/11960#issuecomment-304685856)

I do not think that there is anything fundamental why this cannot work. It is just unimplemented.

---

@ayuckhulk commented on [Mon May 29 2017](https://github.com/dotnet/coreclr/issues/11960#issuecomment-304697350)

@jkotas The API `ICorDebugType::GetStaticFieldValue` actually returns `CORDBG_E_STATIC_VAR_NOT_AVAILABLE`. However, C# debugger (`clrdbg`) is always able to show static variable value. Does it force the runtime to initialize the dynamic static field of the class? Is it by design that `ICorDebugType::GetStaticFieldValue` does not initialize the static field of the class? Is there another API to force the initialization?

Sorry, I got confused with `ICorDebur*`, `IDacDbiInterface*` etc. APIs :smile:

---

@0xd4d commented on [Mon May 29 2017](https://github.com/dotnet/coreclr/issues/11960#issuecomment-304702050)

You'll need to create an instance of the generic class, see this comment in rsclass.cpp:
```C#
// The debugger may chose to func-eval the creation of an instance of this type and try again.
```

---

@ayuckhulk commented on [Mon May 29 2017](https://github.com/dotnet/coreclr/issues/11960#issuecomment-304702649)

@0xd4d The instance of the class is already created (when I put a breakpoint on line `s1.bar = 2;`) but `ICorDebugType::GetStaticFieldValue` still returns `CORDBG_E_STATIC_VAR_NOT_AVAILABLE`. What API should I use to `func-eval the creation of an instance of this type`?

---

@ayuckhulk commented on [Tue May 30 2017](https://github.com/dotnet/coreclr/issues/11960#issuecomment-304855235)

@jkotas Is this https://blogs.msdn.microsoft.com/davidnotario/2005/02/08/jit-compiler-and-type-constructors-cctors/ the reason why static fields are not available? Then I guess I need to call the `.cctor` method using `ICorDebugEval` API.

---

@jkotas commented on [Tue May 30 2017](https://github.com/dotnet/coreclr/issues/11960#issuecomment-304887170)

The short answer is that many things in the runtime are done lazily, including allocation of storage for static fields.

> Then I guess I need to call the .cctor method using ICorDebugEval API.

If you want to mimic the Visual Studio experience, then yes - you would need to run the .cctor. It is not just to allocate the storage for the fields, it is also to actually run the .cctor if it has not run already.

---

@ayuckhulk commented on [Tue May 30 2017](https://github.com/dotnet/coreclr/issues/11960#issuecomment-304891602)

@jkotas I tried to use `ICorDebugEval` for `.cctor` from SOS but it failed with `E_NOTIMPL`. I guess that's because SOS uses V4 debug API and in order for `ICorDebugEval` to work the API should be V2.
Is there any working API to actually run `.cctor` and other methods (like getters for properties)? Or am I missing something? :smile:

---

@jkotas commented on [Tue May 30 2017](https://github.com/dotnet/coreclr/issues/11960#issuecomment-304898689)

It is because of funceval requires infrastructure that was never implemented for the low-level SOS debugger. I do not think it has anything to do with V2 vs. V4 debug APIs.

---

@ayuckhulk commented on [Tue May 30 2017](https://github.com/dotnet/coreclr/issues/11960#issuecomment-304902371)

@jkotas Could you please point me to the things that should be implemented to get funceval working in SOS?

---

@jkotas commented on [Tue May 30 2017](https://github.com/dotnet/coreclr/issues/11960#issuecomment-304908711)

The funceval is pretty complex. You can an idea about what is involved from https://blogs.msdn.microsoft.com/jmstall/tag/funceval/ .

---

@ayuckhulk commented on [Tue May 30 2017](https://github.com/dotnet/coreclr/issues/11960#issuecomment-304943975)

Thank you!

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.