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/emeadaxsupport/archive/2010/05/12/possibilities-to-create-memory-dumps-from-crashing-processes.aspx Setting up WinDbg: http://blogs.msdn.com/b/emeadaxsupport/archive/2011/04/10/setting-up-windbg-and-using-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/emeadaxsupport/archive/2011/04/10/finding-the-ax-user-and-the-x-call-stack-from-a-memory-dump-the-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:
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:
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):
Look for the Ax32Serv!interpret::evalFunc frames take the location from the line below and then run:
In AX2009 64 bit:
In AX4 32 bit: take the location from the current evalFunc line (not the line below as in AX2009 64 bit) and run:
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 AX4 32 bit:
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:
Then take the first location returned and run:
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:
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/emeadaxsupport/archive/2011/04/10/finding-the-ax-user-that-caused-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/emeadaxsupport/archive/2011/04/10/finding-the-ax-user-and-the-x-call-stack-from-a-memory-dump-the-easy-way.aspx