.NET - WinDBG - Содержимое строки - PullRequest
2 голосов
/ 25 марта 2012

Я пытаюсь отладить утечку памяти в большом приложении.Мой первый шаг - познакомиться с WinDBG.У меня есть следующая программа в .NET:

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Try
        Dim HelloWorld As String = "HelloWorld"
        Dim testInt As Integer
        Me.Show()
        For testInt = 0 To 1000000
            TextBox1.Text = testInt 'There is a textbox on the form
            Application.DoEvents() 'So textbox updates on the fly
        Next

    Catch ex As Exception

    End Try
End Sub

Я пытаюсь просмотреть содержимое переменной HelloWorld в WinDbg, которая должна быть «HelloWorld».Я следовал этим инструкциям:

1) Подключил WinDBG к исполняемому файлу и запустите отладчик.

2) Немедленно прервите (до завершения цикла)

3) loadby sos clr

4) ~ 0s

5)! Clrstack

6)! Dumpheap-type WinDBG (проект называется WinDBGApplication)

Вывод такой:

Statistics:
      MT    Count    TotalSize Class Name
00186f88        1           12     WinDBGTest.My.MyProject+ThreadSafeObjectProvider`1[[WinDBGTest.My.MyProject+MyWebServices, WinDBGTest]]
00186e80        1           12 WinDBGTest.My.MyProject+ThreadSafeObjectProvider`1[[WinDBGTest.My.MyProject+MyForms, WinDBGTest]]
00186e2c        1           12 WinDBGTest.My.MyProject+MyForms
00186d3c        1           12 WinDBGTest.My.MyProject+ThreadSafeObjectProvider`1[[Microsoft.VisualBasic.ApplicationServices.User, Microsoft.VisualBasic]]
00186cec        1           12 WinDBGTest.My.MyProject+ThreadSafeObjectProvider`1[[WinDBGTest.My.MyComputer, WinDBGTest]]
00186be8        1           12 WinDBGTest.My.MyProject+ThreadSafeObjectProvider`1[[WinDBGTest.My.MyApplication, WinDBGTest]]
00184bf4        1          104 WinDBGTest.My.MyApplication
00187308        1          328 WinDBGTest.Form1
Total 8 objects

Нет никаких доказательств того, что строка называется HelloWorld и должна основываться на моем ограниченном понимании отладки низкого уровня.Что я делаю не так?

Я попробовал то, что было предложено Rockstart, и получил такой вывод:

OS Thread Id: 0x7a0 (0)
ESP/REG  Object   Name
0039E5EC 0234db94 System.Windows.Forms.Control+ControlNativeWindow
0039E63C 0234dadc System.Windows.Forms.TextBox
0039E658 0234dadc System.Windows.Forms.TextBox
0039E668 0234dadc System.Windows.Forms.TextBox
0039E680 0234db94 System.Windows.Forms.Control+ControlNativeWindow
0039E698 0234db94 System.Windows.Forms.Control+ControlNativeWindow
0039E6A8 0234db94 System.Windows.Forms.Control+ControlNativeWindow
0039E7FC 0234dadc System.Windows.Forms.TextBox
0039E864 02604b10 System.Windows.Forms.Control+MultithreadSafeCallScope
0039E868 02604b68 System.String    26309
0039E878 026049a8 System.String    26310
0039E87C 0234dadc System.Windows.Forms.TextBox
0039E880 026049a8 System.String    26310
0039E884 0234db94 System.Windows.Forms.Control+ControlNativeWindow
0039E890 0234db94 System.Windows.Forms.Control+ControlNativeWindow
0039E8A0 026049a8 System.String    26310
0039E8AC 0234dadc System.Windows.Forms.TextBox
0039E8B4 0234db84 System.Windows.Forms.PropertyStore
0039E8C8 0234dadc System.Windows.Forms.TextBox
0039E8CC 026049a8 System.String    26310
0039E8DC 026049a8 System.String    26310
0039E8E0 0234dadc System.Windows.Forms.TextBox
0039E8EC 0234dadc System.Windows.Forms.TextBox
0039E8F0 0234dadc System.Windows.Forms.TextBox
0039E904 0234d4e4 WinDBGTest.Form1
0039E940 0234d4e4 WinDBGTest.Form1
0039E944 0234e4c0 System.EventHandler
0039E970 0234a1c4 System.EventArgs
0039E978 0234d4e4 WinDBGTest.Form1
0039E9DC 0234d4e4 WinDBGTest.Form1
0039EA00 0234d4e4 WinDBGTest.Form1
0039EAE0 0234d984 System.Windows.Forms.Control+ControlNativeWindow
0039ED28 0234d4e4 WinDBGTest.Form1
0039ED34 0234d4e4 WinDBGTest.Form1
0039ED3C 0234d4e4 WinDBGTest.Form1
0039ED44 0234d4e4 WinDBGTest.Form1
0039ED4C 0234d4e4 WinDBGTest.Form1
0039EDCC 0234d4e4 WinDBGTest.Form1
0039EE18 023491c8 System.Windows.Forms.Application+ThreadContext
0039EE58 023490c8 Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase+WinFormsAppContext
0039EE8C 02348f54 WinDBGTest.My.MyApplication
0039EEA8 02348f54 WinDBGTest.My.MyApplication
0039EEB8 02348f54 WinDBGTest.My.MyApplication
0039F1D8 02348640 System.Object[]    (System.String[])

Ответы [ 3 ]

0 голосов
/ 26 марта 2012

!dumpheap -type WinDBG - неправильный подход, если вы ищете строку.Если вы хотите использовать !dumpheap для этого, вам нужно искать String, так как это имя типа.Тот факт, что на строку ссылаются из метода в пространстве имен WinDBGApplication, здесь не имеет значения.Однако выгрузка всех строк даст вам много ссылок даже для небольшого приложения, такого как это, поскольку среда выполнения выделяет кучу строк, так что это тоже не очень полезно.

На рассматриваемый экземпляр строки ссылается локальная переменная, поэтому лучший способ найти его - это сделать !dso, как предложено Rockstart.Это перечислит все ссылки в текущем стеке, и так как строка ссылается на этот стек, вы найдете адрес здесь.Чтобы вывести саму строку, используйте !do с адресом строки, как показано в выводе из !dso.

Также, пожалуйста, посмотрите на этот вопрос .

0 голосов
/ 26 марта 2012

"2) Немедленно прервать (до завершения цикла)"

Как вы обеспечиваете разрыв до завершения цикла? Вы держите какие-либо точки останова через windbg? Если это прерывание не сделано в нужном месте, то вы не можете получить строку в стеке.

Я попробовал аналогичную программу на рабочем столе и увидел строку. Вот мой пример программы.

class Program
{
    static void Main(string[] args)
    {
        var testclass = new testClass();
        testclass.Load();
    }


}

public class testClass
{
    public void Load()
    {
        var HelloWorld = "Hello World!!";
        string temp = string.Empty;
        for (int i = 0; i < 1000; i++)
        {
            temp = i.ToString();

            if (i == 400)
            {
                Console.ReadKey();
            }
        }
    }
}

}

Когда элемент управления достиг Console.ReadKey (), я подключил отладчик и запустил! Dso. Вот результат.

enter image description here

Еще один подход, вы можете удалить «Me.Show ()» и попробовать то же самое снова. Боюсь, Me.Show появится в основном потоке и перенесет вашу логику в рабочий поток, и, следовательно, вы не сможете увидеть строку в стеке.

0 голосов
/ 25 марта 2012

Переменная Helloworld была бы сохранена в стеке. Следовательно, используйте! Dso для вывода объектов стека. Вы должны увидеть строку Helloworld

...