none
Como encontrar a thread de uma task pelo WinDbg RRS feed

  • Pergunta

  • Olá

    Tenho uma aplicação que faz o disparo de várias tasks que ficam em um array (System.Threading.Tasks.Task) e no final ele espera o término das tasks, utilizando o código abaixo:

        Dim tasks As New List(Of Task)         
        For Each fator As String In Fatores
                    tasks.Add( _
                        Task.Run(Sub()
                                     Calcular(New Object() {fator,})
                                 End Sub))
         Next
         Task.WaitAll(tasks.ToArray())

    Durante a execução solicitei um dump da aplicação. Na consulta das threads obtive a lista abaixo (removi as finalizadas)

          ID OSID ThreadOBJ           State GC Mode     GC Alloc Context                  Domain           Count Apt Exception
       0    1 60d8 000000000045e540    26020 Preemptive  000000014DE5FE38:000000014DE5FFD0 00000000004492e0 0     STA
       2    2 3c90 00000000004896d0    2b220 Preemptive  0000000000000000:0000000000000000 00000000004492e0 0     MTA (Finalizer)
       5    3 309c 000000001d6ba3f0  102a220 Preemptive  0000000000000000:0000000000000000 00000000004492e0 0     MTA (Threadpool Worker)
       7    4 743c 000000001d6eb920  202b220 Preemptive  0000000000000000:0000000000000000 00000000004492e0 0     MTA
       8    5 7528 000000001d794080  202b220 Preemptive  000000014DE596F8:000000014DE59FD0 00000000004492e0 0     MTA
       9    6 53f4 000000001d7bd720    21220 Preemptive  0000000000000000:0000000000000000 00000000004492e0 0     Ukn
      10   17 239c 000000001fa04160  202b020 Preemptive  0000000000000000:0000000000000000 00000000004492e0 0     MTA
      12 1134 20ec 0000000000474380  8029220 Preemptive  0000000000000000:0000000000000000 00000000004492e0 0     MTA (Threadpool Completion Port)
      15  649 2e2c 00000000247fdd00  1029220 Preemptive  0000000000000000:0000000000000000 00000000004492e0 0     MTA (Threadpool Worker)
      17  650 28ac 0000000000478bb0  1029220 Preemptive  0000000000000000:0000000000000000 00000000004492e0 0     MTA (Threadpool Worker)
      16  651 47c8 000000006069d5a0  1029220 Preemptive  0000000000000000:0000000000000000 00000000004492e0 0     MTA (Threadpool Worker)

    XXXX  706    0 000000001fb2f9f0  1039820 Preemptive  0000000000000000:0000000000000000 00000000004492e0 0     Ukn (Threadpool Worker)
      22  705 5dd0 000000001fb301c0  1029220 Preemptive  000000014DE5C098:000000014DE5DFD0 00000000004492e0 0     MTA (Threadpool Worker)

    Utilizando o comando ~*e!clrstack consegui localizar a lista das tasks na linha

    000000002083ead0 000007fee6c3bf95 System.Threading.Tasks.Task.WaitAllBlockingCore(System.Collections.Generic.List`1, Int32, System.Threading.CancellationToken) [f:\dd\ndp\clr\src\BCL\system\threading\Tasks\Task.cs @ 5193]
    000000002083eb70 000007fee6c3bbd0 System.Threading.Tasks.Task.WaitAll(System.Threading.Tasks.Task[], Int32, System.Threading.CancellationToken) [f:\dd\ndp\clr\src\BCL\system\threading\Tasks\Task.cs @ 5109]

    E peguei a lista nos parâmetros abaixo

    000000002083eb70 000007fee6c3bbd0 System.Threading.Tasks.Task.WaitAll(System.Threading.Tasks.Task[], Int32, System.Threading.CancellationToken) [f:\dd\ndp\clr\src\BCL\system\threading\Tasks\Task.cs @ 5109]
        PARAMETERS:
            tasks (0x000000002083ec90) = 0x0000000120ca19d8
            millisecondsTimeout (0x000000002083ec98) = 0x00000000ffffffff
            cancellationToken = <no data>

    0:010> !dumparray 0000000120ca19d8
    Name:        System.Threading.Tasks.Task[]
    MethodTable: 000007fee6f424c8
    EEClass:     000007fee5e31238
    Size:        72(0x48) bytes
    Array:       Rank 1, Number of elements 6, Type CLASS
    Element Methodtable: 000007fee642c650
    [0] 0000000120ca1048
    [1] 0000000120ca11f0
    [2] 0000000120ca1398
    [3] 0000000120ca1540
    [4] 0000000120ca16e8
    [5] 0000000120ca1890

    Cada task tem a seguinte estrutura, onde aparentemente as ativas tem o campo m_taskID preenchido

    0:010> !DumpObj /d 0000000120ca1048
    Name:        System.Threading.Tasks.Task
    MethodTable: 000007fee642c650
    EEClass:     000007fee5e36a30
    Size:        72(0x48) 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
    000007fee6419540  4001a16       38         System.Int32  1 instance            42082 m_taskId
    000007fee64170f0  4001a17        8        System.Object  0 instance 0000000000000000 m_action
    000007fee64170f0  4001a18       10        System.Object  0 instance 0000000000000000 m_stateObject
    000007fee64202b8  4001a19       18 ...sks.TaskScheduler  0 instance 0000000003e83d28 m_taskScheduler
    000007fee642c650  4001a1a       20 ...eading.Tasks.Task  0 instance 0000000000000000 m_parent
    000007fee6419540  4001a1b       3c         System.Int32  1 instance         16982024 m_stateFlags
    000007fee64170f0  4001a2e       28        System.Object  0 instance 0000000003e83da8 m_continuationObject
    000007fee64247e8  4001a33       30 ...tingentProperties  0 instance 0000000120ca1148 m_contingentProperties
    000007fee6419540  4001a14      f30         System.Int32  1   shared           static s_taskIdCounter
                                     >> Domain:Value  00000000004492e0:42084 <<
    000007fee6430ac8  4001a15      e80 ...Tasks.TaskFactory  0   shared           static s_factory
                                     >> Domain:Value  00000000004492e0:0000000003e83d80 <<
    000007fee64170f0  4001a2f      e88        System.Object  0   shared           static s_taskCompletionSentinel
                                     >> Domain:Value  00000000004492e0:0000000003e83da8 <<
    000007fee6439b50  4001a30      f34       System.Boolean  1   shared           static s_asyncDebuggingEnabled
                                     >> Domain:Value  00000000004492e0:0 <<
    000007fee5d942c8  4001a31      e90 ....Task, mscorlib]]  0   shared           static s_currentActiveTasks
                                     >> Domain:Value  00000000004492e0:0000000003e83dc0 <<
    000007fee64170f0  4001a32      e98        System.Object  0   shared           static s_activeTasksLock
                                     >> Domain:Value  00000000004492e0:0000000003e83e10 <<
    000007fee6492148  4001a34      ea0 ...bject, mscorlib]]  0   shared           static s_taskCancelCallback
                                     >> Domain:Value  00000000004492e0:0000000003e83e28 <<
    000007fee6492288  4001a35      ea8 ...rties, mscorlib]]  0   shared           static s_createContingentProperties
                                     >> Domain:Value  00000000004492e0:0000000003e83e68 <<
    000007fee642c650  4001a36      eb0 ...eading.Tasks.Task  0   shared           static s_completedTask
                                     >> Domain:Value  00000000004492e0:0000000000000000 <<
    000007fee6492320  4001a37      eb8 ....Task, mscorlib]]  0   shared           static s_IsExceptionObservedByParentPredicate
                                     >> Domain:Value  00000000004492e0:0000000003e83ec0 <<
    000007fee6427a38  4001a38      ec0 ...g.ContextCallback  0   shared           static s_ecCallback
                                     >> Domain:Value  00000000004492e0:0000000003e84910 <<
    000007fee64923b0  4001a39      ec8 ...bject, mscorlib]]  0   shared           static s_IsTaskContinuationNullPredicate
                                     >> Domain:Value  00000000004492e0:0000000003e83f00 <<
    000007fee642c650  4001a12       28 ...eading.Tasks.Task  0   shared         TLstatic t_currentTask
        >> Thread:Value 60d8:0000000000000000 239c:0000000000000000 2e2c:0000000120ca1540 28ac:0000000120ca16e8 47c8:0000000120ca1890 <<
    000007fee649d940  4001a13       30 ....Tasks.StackGuard  0   shared         TLstatic t_stackGuard
        >> Thread:Value 60d8:0000000005d88880 239c:0000000003fbbdd8 2e2c:0000000000000000 28ac:0000000000000000 47c8:0000000000000000 <<

    Gostaria de saber como fazer o relacionamento desta Task com a Thread onde a mesma está sendo executada. Este campo m_taskID não me levou a nenhuma conclusão. Os campos do final t_currentTask e t_stackGuard tem várias threads válidas, incluindo a do form onde está sendo executado o processo. Avaliei outras tasks do array e estes 2 últimos campos são iguais em todas, impedindo a identificação da thread correta.Alguém sabe como correlacionar a Task com a Thread correspondente?

    Obrigado


    • Editado Fabio Venuto quarta-feira, 31 de janeiro de 2018 18:07 Adic.Informacao
    quarta-feira, 31 de janeiro de 2018 17:59

Respostas

  • Boa tarde

    Encontrei algumas pessoas da Microsoft que me ajudaram. Eu só consigo encontrar se a thread onde está a task estive r"viva". Basta rastrear a instância no heap, conforme abaixo. Porém, ao contrário do que eu presumia, os objetos Task que estavam com o m_taskId = 0 é que eram as Tasks em execução. Sendo assim, caso haja algum processo travado esperando alguma Task, se eu não encontrá-la em nenhum lugar é porque ela abortou e não reportou o status para quem estava aguardando sua conclusão.

    0:010> !DumpArray /d 0000000120ca19d8
    Name:        System.Threading.Tasks.Task[]
    MethodTable: 000007fee6f424c8
    EEClass:     000007fee5e31238
    Size:        72(0x48) bytes
    Array:       Rank 1, Number of elements 6, Type CLASS
    Element Methodtable: 000007fee642c650
    [0] 0000000120ca1048
    [1] 0000000120ca11f0
    [2] 0000000120ca1398
    [3] 0000000120ca1540
    [4] 0000000120ca16e8
    [5] 0000000120ca1890
    0:010> !gcroot 0000000120ca1890
    Thread 239c:
        000000002083ead0 000007fee6c3bf95 System.Threading.Tasks.Task.WaitAllBlockingCore(System.Collections.Generic.List`1<System.Threading.Tasks.Task>, Int32, System.Threading.CancellationToken) [f:\dd\ndp\clr\src\BCL\system\threading\Tasks\Task.cs @ 5193]
            rbp+10: 000000002083eb70
                ->  0000000120ca1a20 System.Collections.Generic.List`1[[System.Threading.Tasks.Task, mscorlib]]
                ->  0000000120ca1a48 System.Threading.Tasks.Task[]
                ->  0000000120ca1890 System.Threading.Tasks.Task
        000000002083eb70 000007fee6c3bbd0 System.Threading.Tasks.Task.WaitAll(System.Threading.Tasks.Task[], Int32, System.Threading.CancellationToken) [f:\dd\ndp\clr\src\BCL\system\threading\Tasks\Task.cs @ 5109]
            rbp+10: 000000002083ec90
                ->  0000000120ca19d8 System.Threading.Tasks.Task[]
                ->  0000000120ca1890 System.Threading.Tasks.Task
    Thread 47c8:
        000000002059e020 000007fee629c686 System.Threading.Tasks.Task.Execute() [f:\dd\ndp\clr\src\BCL\system\threading\Tasks\Task.cs @ 2498]
            rbp+10: 000000002059e060
                ->  0000000120ca1890 System.Threading.Tasks.Task
        000000002059e060 000007fee6274750 System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) [f:\dd\ndp\clr\src\BCL\system\threading\executioncontext.cs @ 954]
            r14:
                ->  0000000120ca1890 System.Threading.Tasks.Task
        000000002059e160 000007fee629c928 System.Threading.Tasks.Task.ExecuteWithThreadLocal(System.Threading.Tasks.Task ByRef) [f:\dd\ndp\clr\src\BCL\system\threading\Tasks\Task.cs @ 2827]
            rbp+18: 000000002059e218 (interior)
                ->  0000000120cb0fe8 System.Object[]
                ->  0000000120ca1890 System.Threading.Tasks.Task
        000000002059e160 000007fee629c928 System.Threading.Tasks.Task.ExecuteWithThreadLocal(System.Threading.Tasks.Task ByRef) [f:\dd\ndp\clr\src\BCL\system\threading\Tasks\Task.cs @ 2827]
            rbp+10: 000000002059e210
                ->  0000000120ca1890 System.Threading.Tasks.Task
        000000002059e250 000007fee627f74e System.Threading.ThreadPoolWorkQueue.Dispatch() [f:\dd\ndp\clr\src\BCL\system\threading\threadpool.cs @ 820]
            rbp-20: 000000002059e2c0
                ->  0000000120ca1890 System.Threading.Tasks.Task

    Found 7 unique roots (run '!GCRoot -all' to see all roots).

    Voilá!

    • Marcado como Resposta Fabio Venuto sexta-feira, 16 de fevereiro de 2018 19:48
    sexta-feira, 16 de fevereiro de 2018 19:39