11.04.2011, 00:12 | #1 |
Участник
|
emeadaxsupport: Finding the X++ call stack that caused a crash
Источник: http://blogs.msdn.com/b/emeadaxsuppo...d-a-crash.aspx
============== This post explains how to find the X++ call stack that caused an AOS crash - before reaching this stage you need to first have captured a memory dump, and then set up WinDbg ready to do some analysis, we have posts which explain both of those steps: Capturing memory dumps: http://blogs.msdn.com/b/emeadaxsuppo...processes.aspx Setting up WinDbg: http://blogs.msdn.com/b/emeadaxsuppo...g-symbols.aspx Once you have your memory dumps and have set up WinDbg, just open WinDbg, go to file- open a crash dump, and open the *.dmp file you created. Note: if you fail to load symbols in WinDbg then you won't be able to follow the steps below, instead see the link below for an alternative way to find the X++ stack: http://blogs.msdn.com/b/emeadaxsuppo...-easy-way.aspx To find the X++ call stack you need to find certain frames in the kernel call stack – they are “Ax32Serv!interpret::evalFunc”, this is the function in the kernel which runs an X++ method, from there you need to check the variables in that function to find out which class/table, which method and also whether it is a class or a table. First run off the kernel call stack using this command: kp You can also add a hex number to the end of this command to run off more frames of the stack, as by default it will only run off 20 or so frames, if you have a longer call stack you might run: kp100 Or if you have a stack overflow type issue, so the call stack will be hundreds of lines long then run the command below to return the whole stack, you will know when you reach the bottom of the stack as it will start with ntdll!_RtlUserThreadStart (the Windows function used to start a thread): kpfffff Look for the Ax32Serv!interpret::evalFunc frames take the location from the line below and then run: In AX2009 64 bit: dw 000000002311b150+30 In AX4 32 bit: take the location from the current evalFunc line (not the line below as in AX2009 64 bit) and run: dw 20abf7f0+14 I have added the “+30” or the “+14” to the end, this is the location of the class or table ID variable, the number will be in hex so you need to convert it to decimal to see the normal number. You can run “?ffe4” in WinDbg to convert a hex number to decimal where ffe4 is the hex number to convert. Next you can run: In AX2009 64 bit: db 000000002311b150+38 In AX4 32 bit: db 20abf7f0+18 The first two digits returned from this function indicate whether it’s a table (02) or a class (04). Next to find the method name run: In AX2009 64 bit: dq 000000002311b150+18 In AX4 32 bit: db 20abf7f0+18 Then take the first location returned and run: In AX2009 64 bit: du 00000000`3ba01260 In AX4 32 bit: du 08dec1cc This will return the method name. Below is an example in WinDbg with all of these functions used to find the X++ class and method, for one frame, you would need to run this for each instance of Ax32Serv!interpret::evalFunc that you see in the call stack to find the whole X++ stack. This example uses AX2009 64 bit, but the steps are essentially the same for AX4 32bit just using the different commands mentioned above: 0:010> kp100 Child-SP RetAddr Call Site 00000000`02848930 000007fe`fe1f9c24 rpcrt4!NdrServerCall2+0x1d 00000000`02848960 000007fe`fe1f9d86 rpcrt4!DispatchToStubInCNoAvrf+0x14 00000000`02848990 000007fe`fe1fc44b rpcrt4!RPC_INTERFACE::DispatchToStubWorker+0x146 00000000`02848ab0 000007fe`fe2a1386 rpcrt4!RPC_INTERFACE::DispatchToStub+0x9b 00000000`02848af0 000007fe`fe2b0c1b rpcrt4!OSF_SCALL::SendReceive+0x156 00000000`02848ba0 000007fe`fe2b0c0d rpcrt4!NdrpClientCall2+0xa38 00000000`02849310 00000000`008d24b9 rpcrt4!NdrClientCall2+0x1d 00000000`02849340 00000000`00614a9c Ax32Serv!ClientEvalFunc+0x139 00000000`02849410 00000000`006157cc Ax32Serv!callClientEvalFunc+0x1dc 00000000`02849500 00000000`006178d2 Ax32Serv!interpret::Srv_evalFunc+0x6dc 00000000`02849740 00000000`00617fe4 Ax32Serv!interpret::xal_eval_func+0xa92 00000000`02849850 00000000`0061ecb5 Ax32Serv!interpret::xal_eval_id+0x94 00000000`02849890 00000000`0061ee38 Ax32Serv!interpret::evalLoop+0x1d5 00000000`02849910 00000000`005facfe Ax32Serv!interpret::eval+0x58 00000000`02849940 00000000`00616843 Ax32Serv!interpret::CQLEvalProc+0x48e 00000000`0284a0e0 00000000`00616c62 Ax32Serv!interpret::doEval+0x4c3 00000000`0284a2b0 00000000`006178a2 Ax32Serv!interpret::evalFunc+0x322 00000000`0284a370 00000000`00617fe4 Ax32Serv!interpret::xal_eval_func+0xa62 00000000`0284a480 00000000`0061ecb5 Ax32Serv!interpret::xal_eval_id+0x94 00000000`0284a4c0 00000000`0061ee38 Ax32Serv!interpret::evalLoop+0x1d5 0:010> dw 00000000`0284a370+20 00000000`0284a390 f006 06eb 0000 0000 a304 0284 0000 0000 00000000`0284a3a0 ff04 ffff ffff ffff 0000 0000 0000 0000 00000000`0284a3b0 0000 0000 0000 0000 c7fd 005c 0000 0000 00000000`0284a3c0 0000 0000 f006 0000 0004 0000 0400 0000 00000000`0284a3d0 d500 0511 0000 0000 0000 0000 0000 0000 00000000`0284a3e0 f0a8 06eb 0000 0000 cffe 009d 0000 0000 00000000`0284a3f0 0000 0000 0000 0000 0000 0000 0000 0000 00000000`0284a400 0000 0000 0000 0000 dc78 06e1 0000 0000 0:010> ?f006 Evaluate expression: 61446 = 00000000`0000f006 0:010> db 00000000`0284a370+28 00000000`0284a398 04 a3 84 02 00 00 00 00-04 ff ff ff ff ff ff ff ................ 00000000`0284a3a8 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 00000000`0284a3b8 fd c7 5c 00 00 00 00 00-00 00 00 00 06 f0 00 00 ..\............. 00000000`0284a3c8 04 00 00 00 00 04 00 00-00 d5 11 05 00 00 00 00 ................ 00000000`0284a3d8 00 00 00 00 00 00 00 00-a8 f0 eb 06 00 00 00 00 ................ 00000000`0284a3e8 fe cf 9d 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 00000000`0284a3f8 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 00000000`0284a408 78 dc e1 06 00 00 00 00-00 00 00 00 00 00 00 00 x............... 0:010> dq 00000000`0284a370+8 00000000`0284a378 00000000`0522a216 00000000`06ebec50 00000000`0284a388 00000000`006c0c00 00000000`06ebf006 00000000`0284a398 00000000`0284a304 ffffffff`ffffff04 00000000`0284a3a8 00000000`00000000 00000000`00000000 00000000`0284a3b8 00000000`005cc7fd 0000f006`00000000 00000000`0284a3c8 00000400`00000004 00000000`0511d500 00000000`0284a3d8 00000000`00000000 00000000`06ebf0a8 00000000`0284a3e8 00000000`009dcffe 00000000`00000000 0:010> du 00000000`0522a216 00000000`0522a216 "info" Next you might want to find out which AX user caused the crash, we have a post on that below: http://blogs.msdn.com/b/emeadaxsuppo...d-a-crash.aspx There is an easier way to do this for AX2009 x64 - we have created scripts to automate the process in WinDbg - see this post: http://blogs.msdn.com/b/emeadaxsuppo...-easy-way.aspx --author: Tariq Bell --editor: Tariq Bell --date: 10/04/2011 Источник: http://blogs.msdn.com/b/emeadaxsuppo...d-a-crash.aspx
__________________
Расскажите о новых и интересных блогах по Microsoft Dynamics, напишите личное сообщение администратору. |
|
|
За это сообщение автора поблагодарили: shogel (2). |
16.08.2011, 16:44 | #2 |
Moderator
|
Поскольку мне таки пришлось анализировать crashdump для упавшего Ax 2009 32 bit, выяснилось, что смешения в стековом фрейме там такие же как и для Ax 4.0 32Bit. (Тарик для DAX2009 указал смещения только для 64битной версии).
Кроме того - обратите внимание на то место, где Тарик пишет что адрес стекового фрейма для 32 и 64 битных версий определяется разным образом. Я сначала попробовал 64битный метод применить для 32битного дампа и в итоге потратил впустую часа два. |
|
|
За это сообщение автора поблагодарили: Logger (10). |
14.01.2020, 13:20 | #3 |
Участник
|
Описание опечаток
RPC Error 1726 полный набор ссылок единственный способ это исправить - зарегистрировать соответствующий запрос в поддержке |
|