Help! Do not understand what debugger is doing


I’ll try to explain this as best as possible. I’m new to AX development and the company I just started working for is running large and highly customized AX installation. I’m working in a part of the code that creates PDF reports (basically PDF files) using “Create!Form”. As if the code isn’t complicated enough, as I’m trying to step through the code it seems to jump into random methods, where there is no explicit call to that method at the line I’m in. Or, at the very end of a function (at the closing bracket), it will jump to another method but don’t see any call whatsoever to that function, and it would seem that the execution should simply return out of the original method to where it was called. Basically there is no “rhyme or reason” as to what it is doing. Is there something I’m missing, does it have to do with the inheritance, or possibly multi-threading? Is my installation messed up?

Not sure if the code below will actually help, but basically at the very end of the startReport method (at the closing bracket) I then jump to other methods that are not explicitly called, such as startPage and startSection etc.

Does anyone know what is going on here, or do I just a long way to go in understanding how AX development works?

public void startReport(PrintJobSettings _printJobSettings)
UserInfo userInfo;
str finalFile, finalFilePath, errorMsg;
#define.SLASH( “\” )
#define.READ_MODE( ‘r’ )
xmlWriter = BT_DPA_XmlWriter::construct();
NumberOfDocInBatch = reportRun.getNumberDocsInBatch();
tempPath = BT_DPA_Global::getTempPath();
if(!reportRun.isBatchMode()) // batch mode has enhance security, ignore this.
if(NumberOfDocInBatch <= 1)
finalFile = reportRun.getFileName();
finalFile = reportRun.getCommonFile();
tempFileName = tempPath + finalFile;
finalFilePath = reportRun.getFilePath();
// check that the path for the final file name exists
if(!BT_DPA_Defaults::pathExists(finalFilePath) )
errorMsg = strFmtLb(strFmt("@DPA136", finalFilePath));
throw Error(errorMsg);
finalFileName = finalFilePath + #SLASH + finalFile;
select userInfo where userInfo.Id == curUserId();
xmlWriter.setAttribute( #REPORT_NAME ,;
xmlWriter.setAttribute( #USER_ID , curUserId());
xmlWriter.setAttribute( #FILE_NAME , finalFileName);

BT_DPA_Global::btProlog(_printJobSettings, userInfo, curUserId(), finalFile,
xmlWriter,, reportRun.getPrintSettings(), reportRun.getOriginalPrintMedium(),
reportRun.get_BT_DPA_Destination(),, reportRun.getFilePath(),
reportRun.getPdfFilePath(), reportRun.getPdfFileName(), NumberOfDocInBatch);


The problem is that the class extends a kernel class (ReportOutputUser; you can find it in AOT under System documentation > Classes) and you can’t debug kernel code (it’s not X++). Therefore debugger skips all kernel calls and shows you the first accessible method, i.e. a method called by kernel which is overriden in X++.

Thanks for the reply Martin, that clears it up a bit.