16.03.2013, 15:12 | #1 |
Участник
|
axsa: Finding the X++ stack and AX user with public symbols in AX2012
Источник: http://blogs.msdn.com/b/axsa/archive...in-ax2012.aspx
============== This is an extension of a series of articles I wrote some time ago for AX2009 - this just brings it up to date to do it with AX2012. This enables you to take a snapshot of your AOS and see what's running on it - call stacks and user sessions. If you're not familiar with analysing memory dumps then check this post first, it explains how to get set up etc.. http://blogs.msdn.com/b/emeadaxsuppo...t-s-doing.aspx Here’s a run through finding the X++ call stack and the AX user for AX2012. When you open the dump in WinDbg, run the command “kv” to see the call stack, you’ll see output like this: 0:007> kv Child-SP RetAddr : Args to Child : Call Site 00000000`040b4c40 00000001`406ffc75 : ffffffff`fffffffe 00000000`00000001 00000000`00000001 00000001`403bc721 : Ax32Serv!cqlCursor::connection+0x14 00000000`040b4c70 00000001`406ffec6 : 00000000`1e84a7a0 00000000`1e56c720 00000000`00000001 00000000`040b50b0 : Ax32Serv!cqlCursor::DropTempDBTableInstance+0x75 00000000`040b4eb0 00000001`403b9771 : 00000000`00000001 00000000`00000001 00000000`040b50b0 00000001`40437346 : Ax32Serv!cqlCursor::Dispose+0x26 00000000`040b4ee0 00000001`403bc714 : 00000000`1e56c720 00000001`404351f0 00000000`1ac20d28 00000001`407d8d4b : Ax32Serv!cqlCursor::~cqlCursor+0x101 00000000`040b4f60 00000001`40369815 : 00000000`1e56c720 00000000`194c0d00 00000000`1b912800 00000001`407d8ead : Ax32Serv!cqlCursor::`vector deleting destructor'+0x14 00000000`040b4f90 00000001`403801d5 : 00000000`1e56c720 00000000`040b6100 00000000`1e0bfe40 00000001`4058067b : Ax32Serv!cqlCursor::freeRef_AdHoc+0x35 00000000`040b4fc0 00000001`40582026 : 00000000`040b50b0 00000000`00000006 00000000`040b51a0 00000001`4049e2b1 : Ax32Serv!assignCursor+0x75 00000000`040b4ff0 00000001`40582d95 : 00000000`000000c8 00000000`00000000 00000000`040b51b0 00000000`040b51a0 : Ax32Serv!CQLFreeVars+0x116 00000000`040b5040 00000001`40430c43 : 00000000`1b912800 00000000`00000005 00000000`00000005 00000000`00000005 : Ax32Serv!interpret::CQLEvalProc+0x715 00000000`040b52c0 00000001`4043370a : 00000000`03720cc8 000007fe`8f8fc3a1 00000000`18ebfb90 00000000`1b913940 : Ax32Serv!interpret::doEval+0x3e3 00000000`040b55c0 00000001`40434517 : 00000000`18ebfb00 00000000`1e522736 00000000`1e665e60 00000000`00930200 : Ax32Serv!interpret::evalFunc+0x2ca 00000000`040b56a0 00000001`404351f0 : ffffffff`fffffffe 00000001`4065167a ffffffff`fffffffe 00000000`040b6190 : Ax32Serv!interpret::xal_eval_func+0xc77 00000000`040b6030 00000001`4049e127 : 00000000`1b912800 00000000`1b912800 00000000`040b6190 00000000`040b7000 : Ax32Serv!interpret::xal_eval_id+0xd0 00000000`040b6070 00000001`4049e268 : 00000000`1b912800 00000000`00000000 00000000`1b912800 00000000`040b70e0 : Ax32Serv!interpret::evalLoop+0x167 00000000`040b60d0 00000001`40582b53 : 00000000`00000001 00000000`00000000 00000000`040b6180 00000000`00000000 : Ax32Serv!interpret::eval+0x58 For the X++ stack we care about the ax32serv!interpret::evalfunc frames. Let’s take the evalfunc line nearest to the top of the stack as an example: 00000000`040b55c0 00000001`40434517 : 00000000`18ebfb00 00000000`1e522736 00000000`1e665e60 00000000`00930200 : Ax32Serv!interpret::evalFunc+0x2ca Take the third column shown above in green and then run “du ” as shown below. This gives you the X++ method name: 0:007> du 00000000`1e522736 00000000`1e522736 "saveBudgetCheckResultErrorWarnin" 00000000`1e522776 "gDetails" Now to find the class, take the first column in that line and run “dd ” as shown below, this gives you the class ID in hexadecimal: 0:007> dd 00000000`040b55c0+44 00000000`040b5604 000f554e 1b913940 00000000 00000000 00000000`040b5614 00000000 00000000 00000000 00000000 00000000`040b5624 00000000 00000000 00000000 00000000 00000000`040b5634 00000000 00000000 00000000 00000000 00000000`040b5644 00000000 ffffff00 00000000 1e665e60 00000000`040b5654 00000000 fffffffe ffffffff 00000001 00000000`040b5664 00000000 1b913940 00000000 1e522736 00000000`040b5674 00000000 1b912800 00000000 040b7000 To find out what the class name is from this, first you can convert the ID to decimal, just run “? ” 0:007> ? 000f554e Evaluate expression: 1004878 = 00000000`000f554e Above 1004878 is the classID, you can find the class name in an X++ job, like this: info(classid2name(1004878)); Now for you to find the AX user you run the command “!tls -1”, this is following the instructions from this post but I am giving you different offsets here: 0:007> !tls -1 TLS slots on thread: 2ed4.176c 0x0000 : 0000000000000000 0x0001 : 0000000000000000 0x0002 : 0000000000000000 0x0003 : 0000000000000000 0x0004 : 0000000000000000 0x0005 : 0000000000000000 0x0006 : 0000000000000000 0x0007 : 0000000000e29900 0x0008 : 0000000000000000 0x0009 : 0000000000000000 0x000a : 0000000000000000 0x000b : 0000000000000000 0x000c : 0000000000000000 0x000d : 0000000000000000 0x000e : 0000000000000000 0x000f : 0000000000000000 0x0010 : 0000000000000000 0x0011 : 0000000000000000 0x0012 : 0000000000000000 0x0013 : 0000000000000000 0x0014 : 0000000000000000 0x0015 : 0000000000000000 0x0016 : 0000000000000000 0x0017 : 00000000005c70f0 0x0018 : 0000000000000000 0x0019 : 0000000000000000 0x001a : 0000000000000000 0x001b : 0000000000000000 0x001c : 0000000000000000 0x001d : 0000000000000000 0x001e : 000000000f2442a0 0x001f : 00000000005daca0 0x0020 : 000000000f177e60 0x0021 : 0000000001829210 0x0022 : 000000001916a600 0x0023 : 0000000000000000 0x0024 : 0000000000000000 0x0025 : 0000000000000000 0x0026 : 0000000000000000 …… Then take the location above and run the command below, this is to find the user’s session block (the class instance that represents their session). Note that in this example I’ve picked the 0x0022 entry in the list that came from the !tls -1, this won’t always be the same entry – unfortunately with public symbols (i.e. outside of Microsoft) you can’t do the !tls part more accurately, you’ll need to try each entry and has a value other than zero and you’ll know if it’s right in the next step if you see a username at 17c. 0:007> dq 000000001916a600+68 00000000`1916a668 00000000`194c0d00 00000000`0f26f790 00000000`1916a678 00000000`00000000 00000000`00000000 00000000`1916a688 00001d5b`00000000 00000001`3feebdc0 00000000`1916a698 00000000`00000001 00000000`00000000 00000000`1916a6a8 74007300`69004c00 65006700`61005000 00000000`1916a6b8 fff30002`00000000 00073ea8`0e010000 00000000`1916a6c8 02000000`00010001 00000000`000001ff 00000000`1916a6d8 10a8effc`a833b3d8 00000000`19152760 Then take the location in green above, and at various offsets you’ll find information about the user as shown below. User’s AX username: 0:007> du 00000000`194c0d00+17c 00000000`194c0e7c "kkidder" User’s AX company: 0:007> du 00000000`194c0d00+298 00000000`194c0f98 "dat" User’s client machine name: 0:007> du 00000000`194c0d00+57c 00000000`194c127c "eeax2008" Happy debugging! /Tariq Bell Источник: http://blogs.msdn.com/b/axsa/archive...in-ax2012.aspx
__________________
Расскажите о новых и интересных блогах по Microsoft Dynamics, напишите личное сообщение администратору. |
|
|
За это сообщение автора поблагодарили: Logger (1). |
|
|