in agent/native/ext/AST_debug.cpp [704:772]
void debugDumpAstSubTreeToFile( StringView compiledFileFullPath, zend_ast* ast, bool isBeforeProcess )
{
ResultCode resultCode;
StringBuffer debugDumpFileFullPath = ELASTIC_APM_EMPTY_STRING_BUFFER;
FILE* debugDumpFile = NULL;
int errnoValue = 0;
char txtOutStreamBuf[ELASTIC_APM_TEXT_OUTPUT_STREAM_ON_STACK_BUFFER_SIZE];
TextOutputStream txtOutStream = ELASTIC_APM_TEXT_OUTPUT_STREAM_FROM_STATIC_BUFFER( txtOutStreamBuf );
DebugDumpAstPrintToFileCtx ctx;
DebugDumpAstPrinter printer;
ELASTIC_APM_LOG_DEBUG_FUNCTION_ENTRY_MSG( "compiledFileFullPath: %s", compiledFileFullPath.begin );
StringView pathPrefix = stringBufferToView( g_astProcessDebugDumpForPathPrefix );
if ( ! isFileSystemPathPrefix( compiledFileFullPath, pathPrefix ) )
{
ELASTIC_APM_LOG_DEBUG_FUNCTION_ENTRY_MSG( "Skipping this file because it does not have required prefix: %s", pathPrefix.begin );
return;
}
StringView compiledFileRelativePath = subStringView( compiledFileFullPath, pathPrefix.length );
StringView isBeforeProcessSuffix = isBeforeProcess ? ELASTIC_APM_STRING_LITERAL_TO_VIEW( ".before_AST_process" ) : ELASTIC_APM_STRING_LITERAL_TO_VIEW( ".after_AST_process" );
StringView debugDumpFileExtensionSuffix = ELASTIC_APM_STRING_LITERAL_TO_VIEW( ".txt" );
StringView debugDumpFileFullPathParts[] = {
stringBufferToView( g_astProcessDebugDumpOutDir ),
compiledFileRelativePath,
isBeforeProcessSuffix,
debugDumpFileExtensionSuffix
};
ELASTIC_APM_CALL_IF_FAILED_GOTO( buildFileFullPath( ELASTIC_APM_MAKE_ARRAY_VIEW_FROM_STATIC( StringViewArrayView, debugDumpFileFullPathParts ), /* out */ &debugDumpFileFullPath ) );
ELASTIC_APM_CALL_IF_FAILED_GOTO( ensureDirectoriesExist( stringBufferToView( debugDumpFileFullPath ) ) );
errnoValue = openFile( debugDumpFileFullPath.begin, "w", /* out */ &debugDumpFile );
if ( errnoValue != 0 )
{
ELASTIC_APM_LOG_ERROR( "Failed to open file; debugDumpFileFullPath: %s; errno: %d (%s)", debugDumpFileFullPath.begin, errnoValue, streamErrNo( errnoValue, &txtOutStream ) );
ELASTIC_APM_SET_RESULT_CODE_AND_GOTO_FAILURE();
}
ELASTIC_APM_LOG_INFO( "Printing AST debug dump of %s to %s ...", compiledFileFullPath.begin, debugDumpFileFullPath.begin );
ctx = (DebugDumpAstPrintToFileCtx){ .outFile = debugDumpFile };
printer = (DebugDumpAstPrinter){ .printLine = &debugDumpAstPrintLineToFile, .ctx = &ctx };
debugDumpAst( &printer, ast, /* nestingDepth */ 0 );
ELASTIC_APM_LOG_INFO( "Printed AST debug dump of %s to %s", compiledFileFullPath.begin, debugDumpFileFullPath.begin );
if ( g_astProcessDebugDumpConvertedBackToSource )
{
debugDumpAstSubTreeConvertedBackToSource( compiledFileFullPath, compiledFileRelativePath, ast, isBeforeProcessSuffix, &txtOutStream );
}
resultCode = resultSuccess;
finally:
ELASTIC_APM_LOG_DEBUG_RESULT_CODE_FUNCTION_EXIT_MSG();
if ( debugDumpFile != NULL )
{
fclose( debugDumpFile );
debugDumpFile = NULL;
}
ELASTIC_APM_FREE_STRING_BUFFER_AND_SET_TO_NULL( /* in,out */ debugDumpFileFullPath );
ELASTIC_APM_UNUSED( resultCode );
return;
failure:
goto finally;
}