--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/analyzetoolcleaner/bwins/atoolcleaneru.def Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,3 @@
+EXPORTS
+ ?GetCallBackAddress@@YAPAV?$TFixedArray@K$09@@XZ @ 1 NONAME ; class TFixedArray<unsigned long, 10> * GetCallBackAddress(void)
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/analyzetoolcleaner/eabi/atoolcleaneru.def Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,3 @@
+EXPORTS
+ _Z18GetCallBackAddressv @ 1 NONAME
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/analyzetoolcleaner/group/analyzetoolcleaner.mmp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,39 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: The .mmp file for atoolcleaner.
+*
+*/
+
+#include <platform_paths.hrh>
+
+TARGET atoolcleaner.dll
+TARGETTYPE dll
+UID 0x1000008d 0x2002DC71
+CAPABILITY ALL -TCB
+EPOCALLOWDLLDATA
+
+SMPSAFE
+
+SOURCEPATH ../src
+SOURCE analyzetoolcleaner.cpp
+
+USERINCLUDE ../inc
+USERINCLUDE ../../inc
+
+OS_LAYER_SYSTEMINCLUDE
+
+LIBRARY euser.lib
+LIBRARY flogger.lib
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/analyzetoolcleaner/group/bld.inf Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,8 @@
+PRJ_PLATFORMS
+ARMV5 WINSCW
+
+PRJ_EXPORTS
+../inc/analyzetoolcleaner.h OS_LAYER_PLATFORM_EXPORT_PATH(analyzetool/analyzetoolcleaner.h)
+
+PRJ_MMPFILES
+analyzetoolcleaner.mmp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/analyzetoolcleaner/inc/analyzetoolcleaner.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,63 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Definitions for the class TAnalyzeToolCleanerBase.
+*
+*/
+
+#ifndef __ANALYZETOOLCLEANER_H__
+#define __ANALYZETOOLCLEANER_H__
+
+// INCLUDES
+#include <e32std.h>
+
+// CONSTANTS
+#define ATCLEANERTABLESIZE 10
+#define ATCLEANERTABLE TFixedArray<TUint32, ATCLEANERTABLESIZE>
+_LIT( KATCleanerDllName, "atoolcleaner.dll" );
+
+// CLASS DECLARATION
+
+/**
+* Cleaner base class
+*/
+class TAnalyzeToolCleanerBase
+ {
+public:
+ /**
+ * Cleanup function which uninstall allocator
+ */
+ virtual void Cleanup() = 0;
+ };
+
+// CLASS DECLARATION
+
+/**
+* Cleaner class
+*/
+class THookCleaner
+ {
+public:
+ /**
+ * C++ default constructor.
+ */
+ THookCleaner();
+
+ /**
+ * Destructor.
+ */
+ ~THookCleaner();
+
+ ATCLEANERTABLE iTable;
+ };
+#endif // __ANALYZETOOLCLEANER_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/analyzetoolcleaner/src/analyzetoolcleaner.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,67 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: THookCleaner implementation
+*
+*/
+
+// INCLUDES
+#include "analyzetoolcleaner.h"
+#include <e32debug.h>
+#include "atlog.h"
+
+// Global cleaner object
+static THookCleaner cleaner;
+
+// ordinal 1
+EXPORT_C ATCLEANERTABLE* GetCallBackAddress()
+ {
+ LOGSTR1( "ATC GetCallBackAddress()" );
+
+ return &( cleaner.iTable );
+ }
+
+// -----------------------------------------------------------------------------
+// THookCleaner::THookCleaner()
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+THookCleaner::THookCleaner()
+ {
+ LOGSTR1( "ATC THookCleaner::THookCleaner()" );
+
+ iTable.Reset();
+ }
+
+// -----------------------------------------------------------------------------
+// THookCleaner::~THookCleaner()
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+THookCleaner::~THookCleaner()
+ {
+ LOGSTR1( "ATC THookCleaner::~THookCleaner()" );
+
+ for ( TUint i = 0; i < ATCLEANERTABLESIZE; i++ )
+ {
+ if ( iTable.At( i ) )
+ {
+ TAnalyzeToolCleanerBase* obj =
+ ( TAnalyzeToolCleanerBase* ) iTable.At( i );
+ obj->Cleanup();
+ }
+ }
+ }
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/group/atool.vcproj Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,375 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="atool"
+ ProjectGUID="{2C50DD86-958B-4189-8DA2-DB388C71F65F}"
+ RootNamespace="atool"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ TreatWChar_tAsBuiltInType="false"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="..\inc\stdafx.h"
+ WarningLevel="4"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="..\lib\xerces-c_2.lib ..\lib\dbghelp.lib Version.lib"
+ OutputFile="..\install\atool.exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/atool.pdb"
+ SubSystem="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="0"
+ TreatWChar_tAsBuiltInType="false"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="..\lib\xerces-c_2.lib ..\lib\dbghelp.lib Version.lib"
+ OutputFile="..\install\atool.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\src\arguments.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\atool.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\cataddr2line.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\cataddr2lineserver.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\catalloc.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\catallocs.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\CATBase.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\CATDataSaver.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\CATDatParser.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\catdbghelper.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\catfilereader.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\CATMemoryAddress.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\CATMmp.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\CATModule2.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\CATParseTraceFile.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\CATParseXML.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\CATProject.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\catromsymbol.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\helps.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\librarychecks.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\stdafx.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\utility.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\src\version.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\inc\ATCommonDefines.h"
+ >
+ </File>
+ <File
+ RelativePath="..\inc\cataddr2line.h"
+ >
+ </File>
+ <File
+ RelativePath="..\inc\cataddr2lineserver.h"
+ >
+ </File>
+ <File
+ RelativePath="..\inc\catalloc.h"
+ >
+ </File>
+ <File
+ RelativePath="..\inc\catallocs.h"
+ >
+ </File>
+ <File
+ RelativePath="..\inc\CATBase.h"
+ >
+ </File>
+ <File
+ RelativePath="..\inc\CATDataSaver.h"
+ >
+ </File>
+ <File
+ RelativePath="..\inc\CATDatParser.h"
+ >
+ </File>
+ <File
+ RelativePath="..\inc\catdbghelper.h"
+ >
+ </File>
+ <File
+ RelativePath="..\inc\catfilereader.h"
+ >
+ </File>
+ <File
+ RelativePath="..\inc\CATMemoryAddress.h"
+ >
+ </File>
+ <File
+ RelativePath="..\inc\CATMmp.h"
+ >
+ </File>
+ <File
+ RelativePath="..\inc\CATModule2.h"
+ >
+ </File>
+ <File
+ RelativePath="..\inc\CATParseTraceFile.h"
+ >
+ </File>
+ <File
+ RelativePath="..\inc\CATParseXML.h"
+ >
+ </File>
+ <File
+ RelativePath="..\inc\CATProject.h"
+ >
+ </File>
+ <File
+ RelativePath="..\inc\catromsymbol.h"
+ >
+ </File>
+ <File
+ RelativePath="..\inc\iaddresstoline.h"
+ >
+ </File>
+ <File
+ RelativePath="..\inc\stdafx.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ <File
+ RelativePath=".\ReadMe.txt"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/group/bld.inf Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,22 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+PRJ_EXPORTS
+../install/atool.exe +/tools/
+../install/addr2line.exe +/tools/
+../install/xerces-c_2_7.dll +/tools/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/ATCommonDefines.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,598 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Common defines for cpp files.
+*
+*/
+
+
+#ifndef __ATCOMMONDEFINES_H__
+#define __ATCOMMONDEFINES_H__
+
+#include "../inc/stdafx.h"
+
+using namespace std;
+
+/**
+* Atool return code.
+*/
+struct AT_RETURN_CODE {
+ /**
+ * Enumeration containing all return codes used by atool.
+ * When error happens this value set as the exit code.
+ * Note! Values can be only added not modified/deleted.
+ */
+ enum RETURN_CODE {
+ /* basic */
+ OK = 0, /** All ok. */
+ INVALID_ARGUMENT_ERROR = 1, /** Arguments failty. */
+ AT_LIBS_MISSING = 2, /** Missing at libraries cannot compile hooked apps. */
+ CANNOT_FIND_EPOCROOT = 3, /** Epocroot not set. */
+ UNHANDLED_EXCEPTION = 4, /** General return code when unhandled exception occurs. */
+ /* compile errors */
+ MAKEFILE_ERROR = 5, /** Cannot read/create etc makefiles sbs1/2. */
+ COMPILE_ERROR = 6, /** Some error related to compilation of code. */
+ UNKNOWN = 7, /** General compilation error not specific. */
+ NO_SUPPORTED_MODULES_ERROR = 8, /** Cannot find supported modules from project. */
+ KERNEL_SIDE_MODULE_ERROR = 9, /** Cannot find supported modules from project because kernel side. */
+ /* Analyze errors */
+ WRONG_DATA_FILE_VERSION = 10, /** Invalid data file version in internal gathering mode. */
+ INVALID_DATA_FILE = 11, /** Data file content invalid. */
+ ANALYZE_ERROR = 12, /** General error in analyze part not specific. */
+ EMPTY_DATA_FILE = 13, /** Data file is empty. */
+ SYMBOL_FILE_ERROR = 14, /** Symbol file content invalid or do not exist. */
+ /* building&releasing errors */
+ RELEASABLES_ERROR = 20, /** Cannot find the binaries of module. */
+ RESTORE_MODULES_ERROR = 21, /** Error restoring mmp file to original. */
+ CREATING_TEMP_CPP_ERROR = 22, /** Error creating temporary cpps to store variables to s60 core.*/
+ CLEANING_TEMP_ERROR = 23, /** Error cleaning atool_temp folder from module. */
+ READ_MAKEFILE_ERROR = 24, /** Some error when reading makefile of module / project (sbs1/2). */
+ MODIFY_MODULES_ERROR = 25, /** Error modifying module mmp file. */
+ INVALID_MMP_DEFINED = 27, /** Specified module does not exist in project. */
+ /* Attribute file related */
+ WRITE_ATTRIBUTES_ERROR = 30, /** Error writing the cfg file into atool_temp folder (contains arguments).*/
+ READ_ATTRIBUTES_ERROR = 31, /** Error reading hooking related arguments from cfg file. */
+ /* User issued exit */
+ USER_ISSUED_EXIT = 40, /** User aborted the run of application. */
+ };
+};
+
+// Debug logging to console
+extern bool g_bDebugConsole;
+// Debug logging to windows api debug
+extern bool g_bDebugDbgView;
+// Debug (low level functions).
+extern bool g_bDebugLowLevel;
+
+// Temporary directory definition's.
+const char AT_TEMP_DIR[] = "atool_temp";
+const char AT_TEMP_LST_DIR[] = "atool_temp\\static_lsts\\";
+
+// makefile dir is used in atool.cpp to check will we use sbs2 (in analyze and clear)
+#define RAPTOR_MAKEFILE_DIR "atool_temp\\build"
+
+// Atool version number and date
+#define ATOOL_VERSION "1.9.1" // NOTE! This version number is written also to temporary cpp file.
+#define ATOOL_DATE "29th April 2010"
+
+// Default/min/max call stack sizes
+const int AT_ALLOC_CALL_STACK_SIZE_DEFAULT = 40;
+const int AT_FREE_CALL_STACK_SIZE_DEFAULT = 0;
+const int AT_CALL_STACK_SIZE_MIN = 0;
+const int AT_CALL_STACK_SIZE_MAX = 256;
+
+// What version of data file contains timestamps in dll's.
+const int AT_DLL_TIMESTAMP_DATA_VERSION = 2;
+
+// Constant compatibility string in temporary cpp.
+// Api version ; current version.
+#define ATOOL_COMPATIBILITY_STRING "1.7.5;1.9.1"
+
+// Datafile version
+#define AT_DATA_FILE_VERSION "DATA_FILE_VERSION 11"
+
+// Latest dbghelp.dll version
+const int DBGHELP_VERSION_MAJ = 6;
+const int DBGHELP_VERSION_MIN = 3;
+const int DBGHELP_VERSION_BUILD = 0;
+const int DBGHELP_VERSION_REVIS = 0;
+const char DBGHELP_DLL_NAME[] = "dbghelp.dll";
+
+
+// Build summary constants
+const string AT_BUILD_SUMMARY_HEADER = "\n### AnalyzeTool ###\n### Build Summary ###\n\n";
+const string AT_BUILD_SUMMARY_INSTRUMENTED_BUILD_COMPLETE = "Instrumented build complete: ";
+const string AT_BUILD_SUMMARY_TARGET = "\tTarget: ";
+const string AT_BUILD_SUMMARY_FAILED = "Build failed: ";
+const string AT_BUILD_SUMMARY_ERRORS = "\tErrors: ";
+const string AT_BUILD_SUMMARY_DATA_FILE_NAME = "\tInternal data gathering filename: ";
+const string AT_BUILD_SUMMARY_NORMAL_BUILD_COMPLETE = "Normal build complete: ";
+const string AT_BUILD_SUMMARY_STATIC_LIBRARY = "\tModule is static library.";
+const string AT_BUILD_SUMMARY_UNSUPPORTED_TARGET_TYPE = "\tModule has unsupported target type.";
+const string AT_BUILD_SUMMARY_UNSUPPORTED_COMPILE_DEFINITION = "\tModule defined unsupported compile definition.";
+const string AT_BUILD_SUMMARY_BUILD_TYPE = "Build type: ";
+const string AT_BUILD_SUMMARY_BUILD_TARGET = "Build target: ";
+const string AT_BUILD_SUMMARY_BUILD_PLATFORM = "Build platform: ";
+const string AT_BUILD_SUMMARY_BUILD_VARIANT = "Build variant: ";
+const string AT_BUILD_SUMMARY_LOGGING_MODE = "Data gathering mode: ";
+const string AT_BUILD_SUMMARY_ALLOC_CALL_STACK_SIZE = "Allocation call stack size: ";
+const string AT_BUILD_SUMMARY_FREE_CALL_STACK_SIZE = "Free call stack size: ";
+const string AT_BUILD_SUMMARY_FILE = "monitored internal";
+const string AT_BUILD_SUMMARY_TRACE = "monitored external";
+const string AT_BUILD_SUMMARY_TRACE_FAST = "external";
+
+const string AT_UNSUPPORTED_TARGET_TYPE = "\tModule has unsupported target type.";
+const string AT_UNSUPPORTED_COMPILE_DEFINITION = "\tModule defined unsupported compile definition.";
+
+// List of locations under epocroot where analyzetool.h can be found.
+// Add all possible to this list so core version information can be read
+// from file.
+const string AT_CORE_INCLUDE_FILE_WITH_VERSION_NUMBER[] = {
+ "epoc32\\include\\domain\\osextensions\\analyzetool\\analyzetool.h",
+ "epoc32\\include\\oem\\analyzetool\\analyzetool.h",
+ "epoc32\\include\\platform\\analyzetool\\analyzetool.h"
+};
+const string AT_CORE_VERSION_NUMBER_TAG = "ANALYZETOOL_CORE_VERSION_FOR_CLE";
+
+// Temporary cpp name
+const char AT_TEMP_CPP_LOWER_START[] = "0a1b2c3d_atool_temp_";
+const char AT_TEMP_CPP_LOWER_END[] = ".cpp";
+
+const char TAB_CHAR_VALUE = 9;
+const char SPACE_CHAR_VALUE = 32;
+
+// Bldmake error msg
+#define AT_BLDMAKE_ERROR "AnalyzeTool : bldmake bldfiles error.\n"
+
+// File copy/move/etc... message definitions
+#define AT_MSG "AnalyzeTool : "
+#define AT_MSG_SYSTEM_CALL "AnalyzeTool : System call, "
+#define AT_FILE_TO " to "
+
+// -c messages
+#define AT_CLEANING_DONE "AnalyzeTool : Cleaning done."
+#define AT_CLEANING_NOTHING_FOUND "AnalyzeTool : Nothing found to clean."
+
+// Analyzing data without process start or dll load
+#define AT_ANALYZE_INSUFFICIENT_LOGGING_DATA "Insufficient logging data to locate code lines for memory addresses.\nLogging has been started after process start."
+#define AT_ANALYZE_NO_PROCESS_START "AnalyzeTool : No processes start information found in test run data."
+#define AT_ANALYZE_NO_DLL_LOAD "AnalyzeTool : No dll load information found in test run data."
+#define AT_ANALYZE_CANNOT_PINPOINT "AnalyzeTool : Memory addresses cannot be pinpointed."
+#define AT_ANALYZE_ABNORMAL_EXIT "Abnormal process end"
+
+// Analyzing without map / lst files
+#define AT_ANALYZE_MISSING_LST_MAP_FILES "AnalyzeTool : Missing lst or map files, memory addresses shown only to module level.\n"
+//#define AT_UNINSTRUMENT_FAILED_IN_ANALYZE_MESSAGE "AnalyzeTool: Error creating map/lst files, leaks shown only to module level.\nRun atool -u to try create lst/map files again after binaries build successfully.\n"
+
+// Mmp error msg
+#define INVALID_MMP_ERROR "AnalyzeTool : Error, Specified mmp is invalid.\n"
+
+// Make error msg
+#define MAKE_ERROR "AnalyzeTool : Error, Running make.\n"
+
+#define AT_NOT_BEEN_BUILD_ERROR "AnalyzeTool : Error, project has not been build using AnalyzeTool.\n"
+
+// Makefile errors
+#define LEVEL1_MAKEFILE_ERROR "AnalyzeTool : Error, reading level 1 makefile.\n"
+#define LEVEL2_MAKEFILE_ERROR "AnalyzeTool : Error, reading level 2 makefile.\n"
+#define MAKEFILE_ERROR_TIP "AnalyzeTool : Tip, your environment might require you to use -variant [target] argument.\n";
+
+//Variant messages
+#define INVALID_VARIANT_ERROR "AnalyzeTool : Error,Specified variant is invalid.\n"
+#define USING_DEFAULT_VARIANT_MESSAGE "AnalyzeTool : Note, Using DEFAULT variant.\n"
+#define NO_DEFAULT_VARIANT_ERROR "AnalyzeTool : Error, environment does not specify DEFAULT variant (No variant support?).\n"
+
+// Variant dir is the dir where all variants are defined
+#define VARIANT_DIR "\\epoc32\\tools\\variant\\"
+
+// Variants defined extension name of the variant must equal filename
+#define VARIANT_FILE_EXTENSION ".VAR"
+
+//Max file name length
+const int MAX_FILENAME_LENGTH = 1024;
+
+//Max line length when reading lines from text file.2048 should be enought.
+const int MAX_LINE_LENGTH = 2048*8;
+
+// ATs project file name to store project attributes
+#define AT_PROJECT_ATTRIBUTES_FILE_NAME "project.cfg"
+const string AT_PROJECT_ATTRIBUTES_SEPARATOR( ":$:" );
+
+// ATs level1 makefile name
+#define AT_LEVEL_1_MAKEFILE_NAME "main.at"
+
+// ATs level2 makefiles extension
+#define AT_LEVEL_2_MAKEFILE_EXT "atm"
+
+//Default logging level
+const int DEFAULT_LOGGING_LEVEL = 3;
+
+//Minimun value of logging level
+const int MIN_LOGGING_LEVEL = 0;
+
+//Maximun value of logging level
+const int MAX_LOGGING_LEVEL = 3;
+
+//Const char represeting dash
+const char DASH = '\\';
+
+/**
+ * Table of file extension not to delete
+ * from atools temp directory when compiling
+ * note define all in lowercase
+ */
+const string TEMP_EXTENSION_NO_DELETE[] = {
+ "xml",
+ "dat",
+ "tmp",
+ "cpp",
+ "at",
+ "atm",
+ "cfg"
+};
+
+// Allowed characters/digits, other than these will be filtered out when using CATBase FilterString
+const char CFILTERSTRING[] = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_";
+
+/**
+ * Table of unsupported target types
+ * (i.e. mmp file syntax targettype in makefile)
+ * List of target types which will not be hooked:
+*/
+const string UNSUPPORTED_TARGET_TYPES[] = {
+ "CTL",
+ "ECOMIIC",
+ "IMPLIB",
+ "KDLL",
+ "KEXT",
+ "KLIB",
+ "LDD",
+ /* "LIB", currently have own vector in project.*/
+ "MDA",
+ "MDL",
+ "NONE",
+ "NOTIFIER",
+ "PDD",
+ "RDL",
+ "STDLIB",
+ "VAR"
+};
+
+/**
+* Kernel side target types
+*/
+const string KERNEL_SIDE_TARGET_TYPES[] = {
+ "VAR",
+ "LDD",
+ "PDD",
+ "KEXT"
+};
+
+// Kernel mode compile definition
+const string KERNEL_MODE_COMPILE_DEFINITION = "__KERNEL_MODE__";
+
+/**
+* MMP file changes for AT
+* Note "SOURCE 0a1b2c3d_atool_temp_TARGET.cpp" is added also.
+*/
+const string MMPFILECHANGES[] = {
+ "//*** AnalyzeTool changes start ***",
+ "SOURCEPATH atool_temp",
+ "LIBRARY AToolMemoryHook.lib",
+ "STATICLIBRARY AToolStaticLib.lib",
+ "OPTION ARMCC --interleave",
+ "//*** AnalyzeTool changes end ***"
+};
+
+//MMP file changes for AT
+//For targettype Dll
+const string MMPFILECHANGES_DLL[] = {
+ "//*** AnalyzeTool changes start ***",
+ "OPTION ARMCC --interleave",
+ "//*** AnalyzeTool changes end ***"
+};
+
+// Trace file constants definitions
+#define LABEL_DATA_FILE_VERSION "DATA_FILE_VERSION"
+#define LABEL_PROCESS_START "PROCESS_START"
+#define LABEL_DLL_LOAD "DLL_LOAD"
+#define LABEL_DLL_UNLOAD "DLL_UNLOAD"
+#define LABEL_MEM_LEAK "MEM_LEAK"
+#define LABEL_PROCESS_END "PROCESS_END"
+#define LABEL_ERROR_OCCURED "ERROR_OCCURED"
+#define LABEL_HANDLE_LEAK "HANDLE_LEAK"
+#define LABEL_TEST_START "TEST_START"
+#define LABEL_TEST_END "TEST_END"
+#define LABEL_LOGGING_CANCELLED "LOGGING_CANCELLED"
+
+// AddressToLine related constants
+
+#define LABEL_ABNORMAL "ABNORMAL"
+const int FUNCTIONS_OFFSET_IN_MAP_FILE_ARMV5 = 0x8000;
+const int FUNCTIONS_OFFSET_IN_GCCE = 0x8000;
+const int FUNCTIONS_OFFSET_IN_MAP_FILE_WINSCW = 0x400000;
+#define TEXT_NO_HANDLE_LEAKS "No handle leaks."
+
+// Make file constant labels
+#define MAKEFILE_TARGETTYPE_STRING "# TargetType "
+#define MAKEFILE_BASIC_TARGETTYPE_STRING "# BasicTargetType "
+#define MAKEFILE_TARGET_STRING "# Target "
+#define MAKEFILE_FEATURE_VARIANT_NAME "# FeatureVariantName "
+#define MAKEFILE_FEATURE_VARIANT_UREL_LABEL "# FeatureVariantURELLabel "
+#define MAKEFILE_FEATURE_VARIANT_UDEB_LABEL "# FeatureVariantUDEBLabel "
+#define UDEB_OPTIMIZATION_LEVEL 0
+
+// Listing file contant labels
+#define LST_FILE_SOURCE_FILE_LABEL "Source file:"
+
+/**
+* Struct for saving module info from .dat file and number of leaks in module.
+*/
+struct DLL_LOAD_INFO
+{
+ string sModuleName; /** name of the code segment/binary */
+ unsigned long iStartAddress; /** start address of code segment (in memory) */
+ unsigned long iEndAddress; /** end address of code segment (in memory) */
+ int iLeaks; /** leak count in this code segment */
+ unsigned long iPID; /** process id which loaded this code segment */
+ int iSubTestStartOpenHandles; /** open handle count when sub test started */
+ int iSubTestEndOpenHandles; /** open handle count when sub test ended */
+ // Load/Unload times, note these are micro seconds from 1970 so size is huge.
+ unsigned long long iLoadTime; /** code segment load time */
+ unsigned long long iUnloadTime; /** code segment unload time */
+ /**
+ * Default constructor to set default values
+ */
+ DLL_LOAD_INFO() {
+ iStartAddress = 0;
+ iEndAddress = 0;
+ iLeaks = 0;
+ iPID = 0;
+ iSubTestStartOpenHandles = 0;
+ iSubTestEndOpenHandles = 0;
+ iLoadTime = 0;
+ iUnloadTime = 0;
+ };
+};
+
+/**
+* Struct for saving symbol information from listing file
+*/
+struct LINE_IN_FILE
+{
+ int iLine; /** line number */
+ string sFileName; /** filename */
+ string sFunction; /** function / symbol */
+ string sMangledName; /** function / symbol name in mangled / coded form */
+ string sLstName; /** listing filename */
+};
+
+/**
+* Struct for saving symbol information from map file
+*/
+struct MAP_FUNC_INFO
+{
+ int iAddress; /** memory address (start of symbol) */
+ int iFuncLength; /** symbol length */
+ string sMangledName;/** symbol name in mangled / coded form */
+ string sWholeLine; /** whole symbol line from map file */
+ string sFunctionName; /** symbol clear name */
+};
+
+/**
+* State that represents the outcome
+* of locating memory address code line from module
+*/
+enum ADDRESS_TO_LINE_STATE {
+ no_map_data = 0, /** Map data was missing */
+ out_of_function_range, /** Could not locate it to any function */
+ mangled_symbol_name, /** symbol name but mangled / coded form */
+ only_function_name, /** Only got function name not code line */
+ succesfull /** Have line number, function, etc...*/
+};
+
+/**
+* Struct to store detail data and state when
+* locating memory addresses code lines
+*/
+struct ADDRESS_TO_LINE_ITEM {
+ ADDRESS_TO_LINE_STATE eState; /** outcome */
+ string sFileName; /** Filename of address */
+ string sFunctionName; /** Function name of address */
+ string sMangledFunctionName; /** function/Symbol name */
+ int iFunctionLineNumber; /** Functions line number */
+ int iExactLineNumber; /** Exact line number of address */
+};
+
+/**
+* Struct to store memory leaks
+* call stack entry data
+*/
+struct CALL_STACK_ITEM {
+ string sAddress; /** Address in string */
+ int iAddress; /** Address in number (converted)*/
+ int iLocation; /** Location. i.e. corresponds m_vDllLoadModList's index*/
+ int iCalculatedLeakAddress; /** calculated address from code segment start */
+ bool bBuildUdeb; /** Optimization level */
+ string sModuleName; /** Modules name were leak is*/
+ ADDRESS_TO_LINE_ITEM addressToLine; /** Data from locating code line for memory address */
+};
+
+/**
+* Enumerations used in argument structure.
+*/
+enum MAIN_SWITCH
+{
+ SWITCH_UNKNOWN = 0, /** not defined */
+ SWITCH_ANALYZE = 1, /** analyze */
+ SWITCH_HOOK = 2, /** compile/instrument */
+ SWITCH_UNHOOK = 3, /** uninstrument */
+ SWITCH_PARSE_TRACE = 5, /** parse raw data */
+ SWITCH_CLEAN = 6, /** clean AT changes */
+ SWITCH_VERSION = 9, /** display version infromation */
+ SWITCH_HELP = 10, /** show help with syntax examples */
+ SWITCH_DBGHELP_VERSION = 11
+};
+
+/**
+* Enumeration used when hooking project.
+*/
+enum HOOK_SWITCH
+{
+ HOOK_UNKNOWN = 0, /** not defined */
+ HOOK_INTERNAL, /** monitored internal data gathering */
+ HOOK_EXTERNAL, /** monitored external data gathering */
+ HOOK_EXTERNAL_FAST, /** external data gathering */
+ HOOK_EXTENSION_INTERNAL, /** Extension call, monitored internal data gathering */
+ HOOK_EXTENSION_EXTERNAL, /** Extension call, monitored external data gathering */
+ HOOK_EXTENSION_EXTERNAL_FAST, /** Extension call, external data gathering */
+ HOOK_EXTENSION_UNINSTRUMENT, /** Extension call, uninstrument (post-build)*/
+ HOOK_EXTENSION_FAILED, /** Extension call, build failed, cleanup */
+ HOOK_OLD_EXTENSION_INSTRUMENT, /** Old extension call, instrument project */
+ HOOK_OLD_EXTENSION_UNINSTRUMENT, /** Old extension call, uninstrument project */
+ HOOK_OLD_EXTENSION_FAILED /** Old extension call, cleanup */
+};
+
+/**
+* Represents hooking parameters, these are set
+* by the user arguments from command line.
+*/
+struct ARGUMENTS_HOOK
+{
+ bool bNoBuild; /** Only intrument project? (no build) */
+ bool bDataFileName; /** Is internal data gathering filename defined */
+ bool bAbldTest; /** Is build only for test modules (abld test build.. */
+ string sDataFileName; /** Internal data gathering filename */
+ int iBuildSystem; /** 1 = sbs, 2 = raptor */
+ int iLoggingMode; /** Just for old parameter parsing. 1=trace, 2=file, 0=? */
+ int iAllocCallStackSize; /** Call stack size when memory allocated */
+ int iFreeCallStackSize; /** Call stack size when memory freed */
+ string sBuildCmd; /** Original build command / user defined or given */
+ vector<string> vBuildCmd; /** Build command split in vector */
+ string sPlatform; /** Build platform */
+ string sBuildType; /** Build type (udeb/urel) */
+ string sFeatureVariant; /** Build variant defined */
+ vector<string> vTargetPrograms; /** User defined single or multiple modules from project? */
+ /**
+ * Default constructor to set default values.
+ */
+ ARGUMENTS_HOOK()
+ {
+ bNoBuild = false;
+ bAbldTest = false;
+ bDataFileName = false;
+ sDataFileName = "";
+ iBuildSystem = 0;
+ iLoggingMode = 0;
+ iAllocCallStackSize = AT_ALLOC_CALL_STACK_SIZE_DEFAULT;
+ iFreeCallStackSize = AT_FREE_CALL_STACK_SIZE_DEFAULT;
+ sBuildCmd = "";
+ sPlatform = "";
+ sBuildType = "";
+ sFeatureVariant = "";
+ vTargetPrograms.clear();
+ };
+};
+
+/**
+* Represents analyze parameters, these are set
+* by the user arguments from command line.
+*/
+struct ARGUMENTS_ANALYZE
+{
+ string sDataFile; /** Data file to be analyzed */
+ string sOutputFile; /** Output file */
+ bool bSymbolFile; /** Is rom/rofs symbol file(s) defined? */
+ vector<string> vSymbolFiles; /** Collection of symbol files */
+ int iLoggingLevel; /** Logging level of report */
+ /**
+ * Default constructor to set default values.
+ */
+ ARGUMENTS_ANALYZE()
+ {
+ sDataFile = "";
+ sOutputFile = "";
+ bSymbolFile = false;
+ iLoggingLevel = 3;
+ };
+};
+
+/**
+* Represents raw trace parsing parameters, these are set
+* by the user arguments from command line.
+*/
+struct ARGUMENTS_PARSE
+{
+ bool bDataFile; /** Is raw data file defined */
+ string sDataFile; /** Raw data file (input) */
+ bool bOutputFile; /** Is output file defined */
+ string sOutputFile; /** Output (AT specific data file)*/
+ /**
+ * Default constructor to set default values.
+ */
+ ARGUMENTS_PARSE()
+ {
+ bDataFile = false;
+ sDataFile = "";
+ bOutputFile = false;
+ sOutputFile = "";
+ };
+};
+
+
+/**
+* Represents main parameters, these are set
+* by the user arguments from command line.
+*/
+struct ARGUMENTS
+{
+ // Base arguments.
+ MAIN_SWITCH eMainSwitch; /** mandatory/main parameter */
+ HOOK_SWITCH eHookSwitch; /** if compile/instrument its "mode" */
+ bool bHelp; /** show help? */
+ bool bDebugConsole; /** enable debug logging to console? */
+ bool bDebugDbgView; /** enable debug logging to win api? */
+ bool bDebugLowLevel; /** enable debug logging for also low level functions? */
+ bool bEnableSbs2; /** use raptor as build system? */
+ ARGUMENTS_HOOK HOOK; /** hooking/instrument/compiling attributes */
+ ARGUMENTS_ANALYZE ANALYZE; /** analyze related attributes */
+ ARGUMENTS_PARSE PARSE; /** parsing related attributes */
+ /**
+ * Default constructor to set default values.
+ */
+ ARGUMENTS()
+ {
+ eMainSwitch = SWITCH_UNKNOWN;
+ eHookSwitch = HOOK_UNKNOWN;
+ bHelp = false;
+ bDebugConsole = false;
+ bDebugDbgView = false;
+ bEnableSbs2 = false;
+ };
+};
+
+// DEBUG MACROS
+// constant string for all beginning of all debug messages
+const char START_LOG_MESSAGE[] = "*** CLE ";
+// Log normal function entry (AAA = class::function )
+#define LOG_FUNC_ENTRY( AAA ) { if( g_bDebugDbgView) { stringstream strs; strs << START_LOG_MESSAGE << "ENTRY: " << AAA << endl; OutputDebugString( strs.str().c_str() ); } else if ( g_bDebugConsole ) { stringstream strs; strs << START_LOG_MESSAGE << "ENTRY: " << AAA << endl; cout << strs.str(); } }
+// Log normal function exit
+#define LOG_FUNC_EXIT( AAA ){ if( g_bDebugDbgView) { stringstream strs; strs << START_LOG_MESSAGE << "EXIT: " << AAA << endl; OutputDebugString( strs.str().c_str() ); } else if ( g_bDebugConsole ) { stringstream strs; strs << START_LOG_MESSAGE << "EXIT: " << AAA << endl; cout << strs.str(); } }
+// Log low level function entry
+#define LOG_LOW_FUNC_ENTRY( AAA ) { if ( g_bDebugLowLevel ) { if( g_bDebugDbgView) { stringstream strs; strs << START_LOG_MESSAGE << AAA << endl; OutputDebugString( strs.str().c_str() ); } else if ( g_bDebugConsole ) { stringstream strs; strs << START_LOG_MESSAGE << AAA << endl; cout << strs.str(); } } }
+// Log low level function exit
+#define LOG_LOW_FUNC_EXIT( AAA ) { if ( g_bDebugLowLevel ) { if( g_bDebugDbgView) { stringstream strs; strs << START_LOG_MESSAGE << AAA << endl; OutputDebugString( strs.str().c_str() ); } else if ( g_bDebugConsole ) { stringstream strs; strs << START_LOG_MESSAGE << AAA << endl; cout << strs.str(); } } }
+// Log stringstream (string, int, etc..) i.e. string1 << int1 << "log this"
+#define LOG_STRING( AAA ) { if( g_bDebugDbgView) { stringstream strs; strs << START_LOG_MESSAGE << AAA << endl; OutputDebugString( strs.str().c_str() ); } else if ( g_bDebugConsole ) { stringstream strs; strs << START_LOG_MESSAGE << AAA << endl; cout << strs.str(); } }
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/CATBase.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,418 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Defines CATBase "utility" class.
+*
+*/
+
+#ifndef __CATBASE_H__
+#define __CATBASE_H__
+
+#include "../inc/ATCommonDefines.h"
+
+/**
+* This class implements lot of utility type of functions used all around atool project.
+* All functions are static so they can be used without inheritance of this class. But still
+* this is a base class of almost all others.
+*/
+class CATBase
+{
+public:
+
+ /**
+ * Constructor
+ */
+ CATBase();
+
+ /**
+ * Destructor
+ */
+ virtual ~CATBase(void);
+
+public:
+
+ /**
+ * FilterExtraSpaces
+ * Filters/replaces multiple continuous spaces with single. Won't leave
+ * spaces in start or end of string.
+ * @param sString to filter.
+ * @return void.
+ */
+ static void FilterExtraSpaces( string& sString );
+
+ /**
+ * Convert hex value in string to signed decimal.
+ * @param sHex
+ * @param iDec
+ * @return true if successful
+ */
+ static bool hexToDec( string& sHex, int& iDec );
+
+ /**
+ * Convert hex value in string to unsigned decimal
+ * @param sHex
+ * @param iDec
+ * @return true if successful
+ */
+ static bool hexToDec( string& sHex, unsigned int& iDec );
+
+ /**
+ * Convert hex value in string to unsigned long.
+ * @param sHex
+ * @param ulDec
+ * @return true if successful
+ */
+ static bool hexToDec( string& sHex, unsigned long& ulDec );
+
+ /**
+ * Convert hex value in string to unsigned long long.
+ * @param sHex
+ * @param ullDec
+ * @return true if successful
+ */
+ static bool hexToDec( string& sHex, unsigned long long& ullDec );
+
+ /**
+ * Convert hex value to integer
+ * @param value
+ * @return unsigned long
+ */
+ static unsigned long _httoi(const TCHAR *value);
+
+ /**
+ * Convert integer to hex string.
+ * @param i
+ * @return hex string
+ */
+ static string NumberToHexString( unsigned int i );
+
+ /**
+ * Convert long to hex string.
+ * @param i
+ * @return hex string
+ */
+ static string NumberToHexString( unsigned long i );
+
+ /**
+ * Helper function checks is given character hex.
+ * @param value value to check.
+ * @return true if value is hex char.
+ */
+ static bool IsHexCharacter(const TCHAR *value);
+
+ /**
+ * Parse string to vector of strings using
+ * separator. (Tokenizer with delimeter).
+ * @param sInput string to split
+ * @char separator
+ * return vector<string>
+ */
+ static vector<string> ParseStringToVector( const string& sInput, char separator );
+
+ /**
+ * Remove spaces and tabulatures from beginning and
+ * end of given string.
+ * @param sInput String to trim.
+ */
+ static void TrimString( string& sInput );
+
+ /**
+ * Searches files with given extension from path.
+ * @param pPathAndExt path with extension
+ * @return string filename
+ */
+ static string GetFileNameUsingExt( const char* pPathAndExt );
+
+ /**
+ * Changes all BackSlash characters to Slash character from string.
+ * @param sInput String including backslashes.
+ * @return String without backslashes.
+ */
+ static string ChangeSlashToBackSlash( string sInput );
+
+ /**
+ * Changes given string to uppercase
+ * @param sInput
+ */
+ static void ChangeToUpper( string& sInput );
+
+ /**
+ * Converts any uppercase letter to lowercase.
+ *
+ * @param sInput Reference to string.
+ */
+ static void ChangeToLower( string& sInput );
+
+ /**
+ * Filter string out of unwanted characters. The list of allowed
+ * characters is defined in CFILTERSTRING.
+ * @param sString string to filter.
+ * @return filtered string.
+ */
+ static string FilterString( const string& sString );
+
+ /**
+ * Removes path and extension from given filename string
+ * @param sFileName
+ * @param bReverseFindExt if true extension will be looked starting from end
+ * @return string
+ */
+ static string RemovePathAndExt( string sFileName, bool bReverseFindExt = false );
+
+ /**
+ * Check if given file exists.
+ * @param pFilename Pointer to file name.
+ * @return False If file does not exists.
+ */
+ static bool FileExists( const char* pFilename );
+
+ /**
+ * Check if given file is flagged read only.
+ * @param pFileName pointer to file name
+ * @return true if read only flag set.
+ */
+ static bool IsFileReadOnly( const char* pFileName );
+
+ /**
+ * Set file read only.
+ * @param pFileName Pointer to file name
+ * @return true if successful.
+ */
+ static bool SetFileReadOnly( const char* pFileName );
+
+ /**
+ * Set file writable (remove read only flag).
+ *
+ * @param pFilename Pointer to file name.
+ * @return true if successful.
+ */
+ static bool SetFileWritable( const char* pFileName );
+
+ /**
+ * Copy file to given path
+ * @param sFile
+ * @param sToPath
+ * @return true if successful
+ */
+ static bool FileCopyToPath(const string& sFile, const string& sToPath);
+
+ /**
+ * Move file to given path
+ * @param sFile File to be moved
+ * @param sToPath path where to move file
+ * @return true if successful
+ */
+ static bool FileMoveToPath(const string& sFile, const string& sToPath);
+
+ /**
+ * Delete file
+ * Note! if file does not exists no error message is displayed
+ * but function returns false
+ * @param sFile File to be deleted
+ * @param bPrint display messages or not, default true
+ * @return true if successful
+ */
+ static bool FileDelete(const string& sFile, bool bPrint = true );
+
+ /**
+ * Delete dir
+ * Note! if dir does not exists no error message is displayed
+ * but function returns false.
+ * This function wont delete directory if string does not contain
+ * AT_TEMP...
+ * @param sDir Directory to be deleted
+ * @param bPrint display message or not, default true
+ * @return true if successful
+ */
+ static bool DirDelete(const string& sDir, bool bPrint = true );
+
+ /**
+ * Create dir
+ * Note! if dir cannot be created no error message is displayed
+ * but function returns false.
+ * @param sDir Directory to be deleted
+ * @param pPrint display message or not, default true
+ * @return true if successful
+ */
+ static bool DirCreate(const string& sDir, bool pPrint = true );
+
+ /**
+ * Create temp path string for given
+ * mmpfile (full path+mmpname)
+ * @param sMmpFileWithPath
+ * @return string containing full path to
+ * AnalyzeTool temporary directory
+ */
+ static string CreateTempPath(const string& sMmpFileWithPath);
+
+ /**
+ * Search files with extensions from given path.
+ * @param pPathAndExt path with extension definition
+ * @param bPrintErrors do print errors?
+ * @param sErrorLog errors
+ * @return true if found.
+ */
+ static bool SearchFileWithExtension( const char* pPathAndExt, bool bPrintErrors, string& sErrorLog );
+
+ /**
+ * Helper function to parse filename or path from given string
+ * @param bFileName if true returns filename otherwise the path
+ * @param sInput string where to get path or filename
+ * @return string filename or path
+ */
+ static string GetPathOrFileName( bool bFileName, string sInput );
+
+ /**
+ * Function returns string from begin of given string until next space,
+ * characters until next space are removed from sInput string.
+ *
+ * @param sInput Line where data is separated with spaces.
+ * @param bEraseFromInput If true characters before space will be removed.
+ * @return string String until next space.
+ */
+ static string GetStringUntilNextSpace( string& sInput, bool bEraseFromInput = true );
+
+ /**
+ * Convert unix path to windows
+ * @param sPath
+ */
+ static void ConvertUnixPathToWin( string& sPath );
+
+ /**
+ * Create Temporary AT Cpp file
+ * @param sId unique id to add in file name
+ * @param sPath where to create
+ * @param sS60FileName of the logging file
+ * @param iLogOption logging mode
+ * @param iIsDebug build type
+ * @param iAllocCallStackSize
+ * @param iFreeCallStackSize
+ * @return true if successful
+ */
+ static bool CreateTemporaryCpp( const string& sId
+ ,const string& sPath
+ ,const string& sS60FileName
+ ,int iLogOption
+ ,int iIsDebug
+ ,int iAllocCallStackSize
+ ,int iFreeCallStackSize );
+ /**
+ * Acquire a list of files in given directory
+ * @param sDirectory can end to \ or x but not to *
+ * @param bListDirs if true directories will be listed as well, default false
+ * @param bAddPathToFile if true given sDirectory path is added to file string, default false
+ * @return vector<string> list of files in folder
+ */
+ static vector<string> DirList(const string& sDirectory, bool bListDirs = false, bool bAddPathToFile = false);
+
+ /**
+ * Get extension from given "file" string
+ * returns string after last . if any otherwise returns same
+ * what was given
+ * @param sString
+ * @return string string after last '.' if no '.' returns given string
+ */
+ static string GetExtension(const string& sString);
+
+ /**
+ * Convert TCHAR pointer to string
+ * @param charArray to convert
+ * @return string
+ */
+ static string ConvertTCHARtoString(TCHAR* charArray);
+
+ /**
+ * if given string contains two dots '.' this will remove
+ * all characters after first '.'
+ */
+ static void RemoveAllAfterDotIfTwoDots(string& sString);
+
+ /**
+ * checks given file is it data file
+ * @param sFile
+ * @return true if it is datafile
+ */
+ static bool IsDataFile( string sFile );
+
+ /**
+ * Parses a path string containing ".." to a valid
+ * path without relations. If given string does
+ * not contain relations it will not be changed
+ * @param sPathString
+ * @return void
+ */
+ static void ParseRelativePathString(string& sPathString);
+
+ /**
+ * Remove relative path ".." from string
+ * @param sString string to remove from
+ * @param iDots index of ".."
+ * @return void
+ */
+ static void RemoveRelativePath(string& sString, size_t iDots);
+
+ /**
+ * Check if given directory exists.
+ *
+ * @param pDirname Pointer to directory name.
+ * @return False If directory does not exists.
+ */
+ static bool DirectoryExists( const char* pDirname );
+
+ /**
+ * Checks from constant array is this targettype
+ * unsupported by AT
+ * @param sTargetType type to check
+ * @return true if it is supported by atool
+ */
+ static bool IsTargetTypeSupported(string sTargetType);
+
+ /**
+ * Checks from constant array is this targettype
+ * kernel side.
+ * @param sTargetType type to check
+ * @return true if it is kernel type
+ */
+ static bool IsTargetTypeKernelSide(string sTargetType);
+
+ /**
+ * Check is given variant defined in environment.(SBS v.1)
+ * @param sEpocroot
+ * @param sVariantName
+ * @return true if it is.
+ */
+ static bool CheckVariant( const string& sEpocroot, const string& sVariantName );
+
+ /**
+ * Check has the environment defined "DEFAULT" variant
+ * @param sEpocRoot
+ * @return true if it is
+ */
+ static bool IsDefaultVariant( const string& sEpocRoot );
+
+ /**
+ * Check is all character ascii
+ * @param pInput pointer to characters
+ * @param iLength length of the string
+ * @return true if all character are ascii
+ */
+ static bool IsAscii( const char* pInput, const unsigned int iLength );
+
+ /**
+ * Get current environments epocroot.
+ * @param sEpocRoot value is stored in this if successful.
+ * @return true if successful.
+ */
+ static bool GetEpocRoot( string& sEpocRoot );
+};
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/CATDatParser.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,283 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Defines CATDatParser class and its used enumerations.
+*
+*/
+
+
+#ifndef __CATDatParser_H__
+#define __CATDatParser_H__
+
+// Includes.
+#include "ATCommonDefines.h"
+#include "CATBase.h"
+#include "CATDataSaver.h"
+
+// Forward declarations.
+class CATModule2;
+class CATMemoryAddress;
+class CATRomSymbol;
+
+/**
+* Provides the analyze feature for AnalyzeTool specific data file.
+* Is used by CATProject. Uses CATModule2 and/or CATRomSymbol to locate symbols or
+* codelines of memory addressses. Uses CATDataSaver to create report.
+*/
+class CATDatParser : public CATBase
+{
+
+public:
+ /**
+ * enumeration representing the "mode" depending on build system
+ */
+ enum ANALYZE_MODE
+ {
+ SBS_1 = 0,
+ SBS_2 = 1
+ };
+ /**
+ * Representing current process state
+ */
+ enum PROCESS_STATE
+ {
+ not_started = 0,
+ ongoing = 1,
+ stopped = 2
+ };
+
+ /**
+ * Constructor.
+ */
+ CATDatParser();
+
+#ifndef MODULE_TEST
+private:
+#endif
+ /**
+ * Real constructor.
+ */
+ void Construct();
+
+ /**
+ * Prevent copy
+ */
+ CATDatParser& operator =( const CATDatParser& /*other*/ ) { }
+ CATDatParser( const CATDatParser& /*other*/ ) { }
+
+public:
+ /**
+ * Constructor for SBS2
+ * @param pModules pointer to vector containing project modules
+ */
+ CATDatParser( vector<CATModule2*>* pModules );
+
+ /**
+ * Destructor
+ */
+ ~CATDatParser();
+
+ /**
+ * Set offset to be used with mapfiles
+ * @param iOffSet
+ */
+ void SetOffSet( int iOffSet );
+
+ /**
+ * Get offset value
+ * @return int
+ */
+ int GetOffSet( ) const;
+
+ /**
+ * Analyze data file set
+ * This method includes try/catch in parsing
+ * @return int error codes specified in CATProject (0=OK)
+ */
+ int Analyze();
+
+ /**
+ * Set log level
+ * @param iLogLevel
+ */
+ void SetLogLevel(int iLogLevel);
+ /**
+ * Get Log level
+ * @return int
+ */
+ int GetLogLevel() const ;
+
+ /**
+ * Set data file to be analyzed
+ * @param sInputFile
+ */
+ void SetInputFile(const string& sInputFile);
+
+ /**
+ * Set output file
+ * @param sOutputFile
+ */
+ void SetOutputFile(const string& sOutputFile);
+
+ /**
+ * Set rom symbol file(s).
+ * @param sRomSymbolFile
+ */
+ void SetRomSymbolFiles(const vector<string>& vRomSymbolFile);
+
+ /**
+ * Set print flag
+ * @param pPringFlag
+ */
+ void SetPringFlag( bool bPrintFlag );
+
+ /**
+ * Set addr2line.exe pinpoint state
+ * @param bInput
+ */
+ void SetAddr2lineExeState( bool bInput );
+
+ /**
+ * Set project platform.
+ * @param sPlatform platform.
+ */
+ void SetProjectPlatform( const string& sPlatform );
+
+ /**
+ * Set projects build type. Use enumeration defined in CATProject.
+ * @param eBuildType.
+ */
+ void SetProjectBuildType( int eBuildType );
+
+#ifndef MODULE_TEST
+private:
+#endif
+
+ /**
+ * Start parsing datafile
+ * @return error codes defined in CATProject
+ */
+ int Parse();
+
+ /**
+ * Helper functio to print header of report
+ */
+ void Header();
+
+ /**
+ * Helper functio to print footer of report
+ */
+ void Footer();
+
+ /**
+ * Helper function reseting/clearing all
+ * member variables related to parsing
+ */
+ void ClearParsingVariables();
+
+ // Helpers for data file tags
+ bool ParseProcessStart( string& sLine );
+ bool ParseDllLoad( string& sLine );
+ bool ParseDllUnload( string& sLine );
+ bool ParseMemLeak( string& sLine );
+ bool ParseProcessEnd( string& sLine );
+ bool ParseHandleLeak( string& sLine );
+ bool ParseTestStart( string& sLine );
+ bool ParseTestEnd( string& sLine );
+ bool ParseLoggingCancelled( string& sLine );
+ bool ParseErrorOccured( string& sLine );
+
+ void PrintMemLeak(const string& sTime,
+ const string& sLeakSize,
+ const string& sLeakAddr,
+ const string& sModuleName);
+
+ // Utilities
+ string ConvertTimeToLocalTime( string sInputTime );
+
+ /**
+ * Create a winscw module into pModules vector.
+ * Used when we have dll load of module not in project to create them
+ * after this they are used in locating code lines.
+ * @param sBinaryName name of the binary with extension.
+ * @return true if successful.
+ */
+ bool CreateWinscwModule( const string& sBinaryName );
+
+#ifndef MODULE_TEST
+private:
+#endif
+
+ void CleanMemoryAddresses();
+
+ // Members
+ unsigned int m_iDataVersion; // Version of data file.
+ int m_eProcess_state; // is process started, etc..
+ bool m_bProcessStartFound;
+ bool m_bDllLoadFound;
+ int m_iLogLevel; // specified logging level
+ string m_sInputFile; // input file
+ vector<string> m_vRomSymbolFiles; // Rom symbol file.
+ string m_sOutputFile; // output file
+ string m_sInputFileTemp; // temporary input file (parsed from trace)
+ ifstream m_In; // Handle to input file
+ // Datasaver
+ CATDataSaver m_DataSaver;
+
+ // Modules to be used in pinpointing
+ vector<CATModule2*>* m_pModules;
+
+ // Rom symbol file.
+ CATRomSymbol* m_pRomSymbol;
+
+ // Build type from dat.
+ int m_eBuildType;
+ // Build type from project.
+ int m_eProjectBuildType;
+ // Offset of map file.
+ int m_iOffSet;
+ // Platform of project.
+ string m_sProjectPlatform;
+
+ // Process related
+ unsigned long m_iCurrentProcessId;
+ string m_sCurrentProcessName;
+ int m_iTotalRuns;
+ int m_iSuccesfullRuns;
+
+ // Leak counting related
+ int m_iTotalNumberOfLeaks;
+ bool m_bSubtestOnGoing;
+ int m_iPinPointedLeaks;
+ int m_iPinPointedSubTestLeaks;
+ int m_iLeakNumber;
+
+ // Handle count related
+ int m_iSubtestStartHandleCount;
+ vector<string> m_vHandleLeaks;
+
+ // Module related
+ vector<DLL_LOAD_INFO> m_vDllLoadModList;
+ vector<DLL_LOAD_INFO> m_vDllLoadModListSubTest;
+
+ // Sbs 1 support functions
+ int FindModuleUsingAddress( unsigned long iAddress ) const;
+ //int FindModuleUsingPID( unsigned long iPID ) const;
+ int FindModuleUsingName( const char* pModName );
+
+ // Memory addresses
+ vector<CATMemoryAddress*> m_vMemoryAddress;
+
+};
+#endif
+//EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/CATDataSaver.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,214 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Defines CATDataSaver class and element type enumeration.
+*
+*/
+
+
+#ifndef __CATDATASAVER_H__
+#define __CATDATASAVER_H__
+
+#include <xercesc/dom/DOM.hpp>
+#include <xercesc/framework/LocalFileFormatTarget.hpp>
+#include "ATCommonDefines.h"
+
+/**
+* Represents element types
+*/
+enum element_types
+{
+ RESULT = 0,
+ RUN,
+ LEAK,
+ CALLSTACK,
+ ITEM,
+ RUN_END,
+ ERROR_IN_RUN,
+ MEM_LEAKS,
+ MEM_LEAK_MODULE,
+ HANDLE_LEAKS,
+ HANDLE_LEAK_MODULE,
+ TEST_START,
+ TEST_END,
+ SUBTEST_MEM_LEAKS,
+ SUBTEST_MEM_LEAK_MODULE,
+ LOGGING_CANCELLED,
+ SUBTEST_HANDLE_LEAKS
+};
+
+//#define CARBIDE_DATA 0
+#define XML_DATA 1
+#define TEXT_DATA 2
+
+/**
+* TProvides features for creating the analyze report in
+* basic text or XML formats. Uses xerces library for XML output.
+*/
+class CATDataSaver
+{
+
+public:
+
+ /**
+ * Constructor.
+ */
+ CATDataSaver( void );
+
+ /**
+ * Destructor.
+ */
+ ~CATDataSaver(void);
+
+ /**
+ * Save all lines to file with given format.
+ * @param pFileName Pointer to file name.
+ * @param iDataToSave Format of data.
+ */
+ void SaveLinesToFile( const char* pFileName, int iDataToSave );
+
+ /**
+ * Prints all saved lines to screen.
+ */
+ void PrintLinesToScreen( void );
+
+ /**
+ * Adds saved line to first in database.
+ */
+ void AddLineToFirst( void );
+
+ /**
+ * Adds saved line to last in database.
+ */
+ void AddLineToLast();
+
+ /**
+ * Adds string to current line.
+ * @param pData string to add
+ * @param bSaveCarbideData add string to xml?
+ */
+ void AddString( const char* pData, bool bSaveCarbideData = false );
+
+ /**
+ * Converts integer to string and adds it to current line.
+ * @param iValue integer value to add
+ * @param bSaveCarbideData add string to xml?
+ */
+ void AddInteger( int iValue, bool bSaveCarbideData = false );
+
+ /**
+ * Sets logging level.
+ * If value is invalid DEFAULT_LOGGING_LEVEL is used
+ * value must be between MIN_LOGGING_LEVEL and MAX_LOGGING_LEVEL
+ * @param iLoggingLevel Logging level.
+ */
+ void SetLoggingLevel( int iLoggingLevel );
+
+ /**
+ * Gets logging level.
+ * @return Logging level.
+ */
+ int GetLoggingLevel( void );
+
+ /**
+ * Sets print immediately flag.
+ * @param bPrintImmediately
+ */
+ void SetPrintFlag( bool bPrintImmediately );
+
+ /**
+ * Sets data header for carbide data.
+ */
+ void SaveCarbideDataHeader( void );
+
+ /**
+ * Initializes xercer xml parser.
+ */
+ bool InitXML( void );
+
+ /**
+ * Writes data to xml tree.
+ * @param sInput data
+ * @param iElementType element to write
+ */
+ void SaveXML( string sInput, int iElementType );
+
+ /**
+ * Converts char* -> wchar_t*.
+ * @param str
+ * @return LPWSTR
+ */
+ static LPWSTR CharToWChar( const char* str );
+
+ /**
+ * Converts wchar_t* -> char*.
+ * @param sInput
+ * @param Source
+ */
+ static void WCharToChar( string& sInput, const WCHAR* Source );
+
+ /**
+ * Set is build type debug?
+ * @param bUdebBuild true if build type debug
+ */
+ void SetBuild( bool bUdebBuild );
+
+ /**
+ * Add xml data for extension
+ * @param sInput data
+ */
+ void AddCarbideData( const string& sInput );
+
+ /**
+ * Convert given integer to string
+ * @param iValueToConvert
+ * @return string
+ */
+ static string IntegerToString( int iValueToConvert );
+
+#ifndef MODULE_TEST
+private:
+#endif
+ vector<string> m_vLines;
+ string m_sLine;
+ string m_sCarbideDataLine;
+
+ string m_sCarbideDataHeader;
+
+ int m_iLoggingLevel;
+ int m_iRunNumber;
+ bool m_bPrintImmediately;
+ bool m_bXMLInitOk;
+ bool m_bUdebBuild;
+
+ xercesc::DOMDocument* m_pDomDoc;
+ xercesc::DOMElement* m_pRootElem;
+ xercesc::DOMElement* m_pCurrentLeakElem;
+ xercesc::DOMWriter* m_Serializer;
+ xercesc::DOMElement* m_pRunElement;
+ xercesc::DOMElement* m_pMemoryLeaks;
+ xercesc::DOMElement* m_pHandleLeaks;
+ xercesc::DOMElement* m_pCurrentSubTestElem;
+ xercesc::DOMElement* m_pSubtestMemoryLeaks;
+
+ /**
+ * Utility to get sub string from string using char as separator
+ * @param sInput
+ * @param cCharacter
+ * @return string
+ */
+ string GetStringUntilNextGivenChar( string& sInput, char cCharacter );
+
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/CATMemoryAddress.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,202 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Defines the CATMemoryAddress class.
+*
+*/
+
+
+#ifndef __CATMEMORYADDRESS_H__
+#define __CATMEMORYADDRESS_H__
+
+#include "../inc/ATCommonDefines.h"
+
+/**
+* Represents a single memory address / call stack item.
+* State tells the "success" of locating the symbol / code line.
+* Contains some utility functions used in this feature.
+*/
+class CATMemoryAddress
+{
+public:
+ /**
+ * Enumeration representing the state of locating code lines.
+ */
+ enum ADDRESS_TO_LINE_STATE
+ {
+ OUT_OF_PROCESS = 0, /** Not located code line.*/
+ OUT_OF_RANGE, /** Outside functions range. */
+ SYMBOL, /** Symbol/ Function located (no codeline) */
+ FUNCTION, /** Function and line number.*/
+ EXACT /** Exact code line located with all information.*/
+ };
+ /**
+ * Constructor
+ * @param sAddress
+ * @param iOffSet value used if need to use offset value
+ */
+ CATMemoryAddress( string& sAddress, unsigned long iOffSet );
+ /**
+ * Destructor
+ */
+ virtual ~CATMemoryAddress();
+ /**
+ * Find which binary this address belongs to.
+ * Sets also the offsetfrommodulestart.
+ * @param vDlls container of binarys to find from.
+ * @return true if found
+ */
+ bool FindSetModuleName(vector<DLL_LOAD_INFO>* vDlls);
+ /**
+ * Get vector index to which module we found this address to belong to.
+ * @return -1 if not set.
+ */
+ int GetDllLoadInfoIndex();
+ /**
+ * Note return value includes the set offset.
+ * So this value is not binary start - address.
+ * Instead it is.
+ * memory address - binary start address + offset
+ * @return adress
+ */
+ unsigned long GetOffSetFromModuleStart();
+ /**
+ * Get the binary start address
+ * @return binary start address
+ */
+ unsigned long GetModuleStartAddress() const;
+ /**
+ * Set time
+ * @param ullTime
+ */
+ void SetTime( unsigned long long& ullTime );
+ /**
+ * Get time
+ * @return unsigned long long
+ */
+ unsigned long long GetTime();
+ /**
+ * Set address
+ * @param sAddess
+ */
+ void SetAddress( string& sAddress );
+ /**
+ * Get address string
+ * @return string
+ */
+ string GetAddressString();
+ /**
+ * Set address
+ * @param iAddress
+ */
+ void SetAddress( unsigned long iAddress );
+ /**
+ * Get Address
+ * @return unsigned long
+ */
+ unsigned long GetAddress();
+ /**
+ * Set module name
+ * @param sModuleName
+ */
+ void SetModuleName( string& sModuleName );
+ /**
+ * Get module name
+ * @return string
+ */
+ string GetModuleName();
+ /**
+ * Set state of locating code line
+ * @param eState
+ */
+ void SetAddressToLineState( ADDRESS_TO_LINE_STATE eState );
+ /**
+ * Get current state of locating code line
+ * @return int
+ */
+ int GetAddressToLineState();
+ /**
+ * Set filename
+ * @param sFileName
+ */
+ void SetFileName(string& sFileName);
+ /**
+ * Get filename
+ * @return string
+ */
+ string GetFileName();
+ /**
+ * Set function name
+ * @param sFunctionName
+ */
+ void SetFunctionName(string& sFunctionName);
+ /**
+ * Get function name
+ * @return string
+ */
+ string GetFunctionName();
+ /**
+ * Set function line number
+ * @param iFunctionLineNumber
+ */
+ void SetFunctionLineNumber(int iFunctionLineNumber);
+ /**
+ * Get function line number
+ * @return int
+ */
+ int GetFunctionLineNumber();
+ /**
+ * Set exact line number
+ * @param iExactLineNumber
+ */
+ void SetExactLineNumber(int iExactLineNumber);
+ /**
+ * Get exact line number
+ * @return int
+ */
+ int GetExactLineNumber();
+ /**
+ * Set module start address
+ * @param iAddress
+ */
+ void SetModuleStartAddress(unsigned long iAddress);
+
+#ifndef MODULE_TEST
+private:
+#endif
+ // Used offset to add to addresses
+ unsigned long m_iOffSet;
+ // Address related members
+ string m_sAddress;
+ unsigned long m_iAddress;
+
+ // Time (microseconds from 1970)
+ unsigned long long m_iTime;
+
+ // Module related members(if FindSetModule is successful)
+ string m_sModuleName;
+ unsigned long m_iOffSetFromModuleStart;
+ unsigned long m_iModuleStartAddress;
+
+ // Module to which address belong.
+ int m_iDllLoadinfoIndex;
+
+ // Pin pointing related members
+ int m_ePinPointState;
+ string m_sFileName;
+ string m_sFunctionName;
+
+ int m_iFunctionLineNumber;
+ int m_iExactLineNumber;
+};
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/CATMmp.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,106 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Class responsible of handling mmp files.
+*
+*/
+
+
+#ifndef __CATMMP_H__
+#define __CATMMP_H__
+
+// Includes
+#include "ATCommonDefines.h"
+#include "CATBase.h"
+
+/**
+* CATMmp represents mmp file of module.
+* All mmp file related actions are done using this class.
+* @author
+*/
+class CATMmp : public CATBase
+{
+
+public:
+
+ // Constructor
+ CATMmp();
+
+ // Destructor
+ ~CATMmp();
+
+ string m_sMmpFile; /** The mmp file with path */
+
+ /**
+ * Makes AnalyzeTool changes to given mmp file.
+ * @param sTargetType target type of module i.e. exe / dll
+ * @param sId unique identification string added to source file name
+ * @return true if editing was successful.
+ */
+ bool EditMmpFile(const string& sTargetType, const string& sId);
+
+ /**
+ * Backups mmp file to atool_temp/file
+ * to path/atool_temp/filename.mmp.tmp.
+ * Calling this function results always to
+ * none edited mmp & none edited backup.
+ * @return true if successful.
+ */
+ bool BackupMmpFile();
+
+ /**
+ * Restores backup from temporary directory (replacing current).
+ * @return true if successful.
+ */
+ bool RestoreMmpFile();
+
+ /**
+ * VerifyAndRecover mmp file.
+ * Wont change mmp if it is not edited
+ * Replaces mmp file using backup if it exists and it is
+ * not edited otherwise removes changes from mmp file.
+ * @return true if successful
+ */
+ bool VerifyAndRecover();
+
+#ifndef MODULE_TEST
+private:
+#endif
+ /**
+ * Checks if the given mmp file is modified by AT
+ * @param bBackup if true checks backup
+ * @return bool true if it is edited
+ */
+ bool IsMmpEdited(bool bBackup = false );
+
+ /**
+ * CreateBackupPath creates string containinig
+ * full path to backup mmp file
+ */
+ string CreateMmpBackupPath();
+
+ /**
+ * Removes AnalyzeTool changes from given file
+ * @param bBackup if true removes changes from backup
+ * @return true if successfully removed changes
+ */
+ bool RemoveMmpFileChanges(bool bBackup = false);
+
+ /**
+ * Removes write protections from mmp file and its backup if exists.
+ * @return true if successful.
+ */
+ bool RemoveWriteProtections();
+
+};
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/CATModule2.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,545 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Class representing a module in project (sbs2).
+*
+*/
+
+
+#ifndef __CATMODULE2_H__
+#define __CATMODULE2_H__
+
+// Includes.
+#include "ATCommonDefines.h"
+#include "CATBase.h"
+#include "CATMmp.h"
+
+// Forward declarations.
+class CATMemoryAddress;
+class IAddressToLine;
+
+/**
+* CATModule2 represents a module/component (single binary) in project.
+* CATProject contains a collection of these.
+*/
+class CATModule2 : public CATBase
+{
+
+public:
+ /**
+ * Constructor.
+ */
+ CATModule2(void);
+
+ /**
+ * Destructor.
+ */
+ ~CATModule2(void);
+
+ /**
+ * Read modules attributes from SBS v.1 makefile.
+ * Also copies makefile to temporary directory if successful.
+ */
+ bool ReadMakeFile();
+
+ /**
+ * Read modules attributes from SBS v.1 makefile.
+ * From make file which is in modules temporary directory.
+ */
+ bool ReadMakeFileFromTemp();
+
+ /**
+ * Add sources using line where source files separated by spaces.
+ * @param sSourceLine.
+ */
+ void AddSources(string& sSourceLine);
+
+ /**
+ * Add sources by giving source file and its corresponding listing file.
+ * @param sSourceFile
+ * @param sLstFile
+ */
+ void AddSource(const string& sSourceFile, const string& sLstFile);
+
+ /**
+ * Create AT temporary cpp file for module.
+ * @param sS60FileName.
+ * @param eLoggingMode.
+ * @param eBuildType.
+ * @param iAllocCallStackSize.
+ * @param iFreeCallStackSize.
+ * @return true if successful.
+ */
+ bool CreateTempCpp(const string& sS60FileName
+ , int eLoggingMode
+ , int eBuildType
+ , int iAllocCallStackSize
+ , int iFreeCallStackSize );
+
+ /**
+ * Add AT changes to modules mmp file.
+ * @return true if successful.
+ */
+ bool ModifyMmp();
+
+ /**
+ * Restore any changes made to modules mmp file.
+ * @return true if successful.
+ */
+ bool RestoreMmp();
+
+ /**
+ * Verify tha mmp does not contain AnalyzeTool made changes.
+ * If it does contain them will remove them manually or using backup.
+ * @return true if successful.
+ */
+ bool VerifyAndRecoverMmp();
+
+ /**
+ * Copy modules releasables to its temporary dir.
+ * This includes map & lst files.
+ * @return true if successful.
+ */
+ bool CopyReleasables();
+
+ /**
+ * Copy modules listing files to given directory.
+ * After copy they will be deleted.
+ * @param sDir target directory.
+ * @return true if successful.
+ */
+ bool CopyLstFilesToDir( const string& sDir );
+
+ /**
+ * Delete modules lst files from their source
+ * directories.
+ * @return true if succesfful.
+ */
+ bool DeleteLstFilesFromSrc();
+
+ /**
+ * Clean modules temporary directory of files,
+ * not defined in UNDELETE list.
+ * @return true if successful
+ */
+ bool CleanTemporaryDir();
+
+ /**
+ * Delete modules temporary directory.
+ * @return true if successful.
+ */
+ bool DeleteTemporaryDir();
+
+ /**
+ * Locate codeline of given memory address.
+ * Given address must be calculated to correspond map file addresses.
+ * @param pMemoryAddress object where to store results.
+ * @return true if successful.
+ */
+ bool AddressToLine(CATMemoryAddress* pMemoryAddress);
+
+ /**
+ * Check does modules symbol file(s) exist.
+ * @return true if it exists.
+ */
+ bool SymbolFileExist( void );
+
+ /**
+ * Check does modules map file(s) exists.
+ * @return true if it exists.
+ */
+ bool MapFileExist( void );
+
+ /**
+ * Check does modules binary file(s) exist.
+ * @return true if it exists.
+ */
+ bool BinaryFileExist( void );
+
+#ifndef MODULE_TEST
+private:
+#endif
+
+ /**
+ * Read modules attributes from make file.
+ */
+ bool ReadMakeFilePrivate();
+
+ /**
+ * Locate codeline of given memory address (winscw platform).
+ * Given address must be calculated to correspond map file addresses.
+ * @param pMemoryAddress object where to store results.
+ * @return true if successful.
+ */
+ bool AddressToLineWinscw(CATMemoryAddress* pMemoryAddress );
+
+ /**
+ * Locate codeline of given memory address (armv5 platform).
+ * Given address must be calculated to correspond map file addresses.
+ * @param pMemoryAddress object where to store results.
+ * @return true if successful.
+ */
+ bool AddressToLineArmv5(CATMemoryAddress* pMemoryAddress );
+
+ /**
+ * Locate codeline of given memory address.
+ * Given address must be calculated to correspond map file addresses.
+ * @param pMemoryAddress object where to store results.
+ * @return true if successful.
+ */
+ bool AddressToLineAddr2lineExe( CATMemoryAddress* pMemoryAddress );
+
+ /**
+ * Search map file data (symbols) using given address.
+ * @param iAddress memory address.
+ * @return index of the symbol or -1 if not found.
+ */
+ int GetSymbolIndexUsingAddress(unsigned long iAddress) const;
+
+ /**
+ * Search listing files data using the given symbol name.
+ * @param sSymbolName symbols name to find.
+ * @return index of the found lst data or -1 if not found.
+ */
+ int GetLineInFileIndexUsingSymbolName(const string& sSymbolName) const;
+
+ /**
+ * Search the exact code line from given file.
+ * @param sFileName listing file to search from.
+ * @param iLine functions line number.
+ * @param iFromFuncAddress how many bytes from functions start.
+ * @return line number or -1 if not found.
+ */
+ int FindLeakCodeLine( string& sFileName, int iLine, unsigned long iFromFuncAddress ) const;
+
+public:
+
+ /**
+ * Set used build system (CATProject::BUILD_SYSTEM).
+ * @param eBuildSystem.
+ */
+ void SetBuildSystem( int eBuildSystem );
+
+ /**
+ * Get defined build system.
+ * @return int CATProject::BUILD_SYSTEM
+ */
+ int GetBuildSystem( void ) const ;
+
+ /**
+ * Set SBS v.1 makefile.
+ * @param sMakeFile
+ */
+ void SetMakeFile( const string& sMakeFile );
+
+ /**
+ * Get SBS v.1 makefile.
+ * @return string makefile.
+ */
+ string GetMakeFile( void ) const;
+
+ /**
+ * Initialize module ready for locating code lines.
+ * with memory addresses (reads map and listing files).
+ * return true if successful.
+ */
+ bool InitializeAddressToLine();
+
+ /**
+ * Set modules mmp file.
+ * This also creates temporary dir if it is missing.
+ * @return true if successful.
+ */
+ bool SetMmpFile(const string& sMmpFile);
+
+ /**
+ * Create modules own temporary directory.
+ * @return true if successful.
+ */
+ bool CreateTemporaryDirectory();
+
+ /**
+ * Get modules mmp file.
+ * @return mmp file.
+ */
+ string GetMmpFile() const;
+
+ /**
+ * Get modules atool_temp directory path.
+ * @return atool_temp directory path.
+ */
+ string GetTempPath() const;
+
+ /**
+ * Get S60 logging file name.
+ * @return s60 logging file name.
+ */
+ string GetS60FileName() const;
+
+ /**
+ * Set target binary name.
+ * @param sTarget binary file name.
+ */
+ void SetTarget(const string& sTarget);
+
+ /**
+ * Get target binary name.
+ * @return modules binary file name.
+ */
+ string GetTarget() const;
+
+ /**
+ * Set binary target type.
+ * @param sTargetType binary target type.
+ */
+ void SetTargetType(const string& sTargetType);
+
+ /**
+ * Get binary target type.
+ * @return binary target type.
+ */
+ string GetTargetType() const;
+
+ /**
+ * Set requested binary target file extension.
+ * @param sRequestedTargetExt binary target file extension.
+ */
+ void SetRequestedTargetExt( const string& sRequestedTargetExt );
+
+ /**
+ * Get requested binary target file extension.
+ * @return binary target file extension.
+ */
+ string GetRequestedTargetExt() const;
+
+ /**
+ * Get full name of modules binary.
+ * @return modules binary files full name.
+ */
+ string GetBinaryName() const;
+
+ /**
+ * Set variant platform.
+ * @param sVariantPlatform variant platform.
+ */
+ void SetVariantPlatform(const string& sVariantPlatform);
+
+ /**
+ * Get variant platform.
+ * @return variant platform.
+ */
+ string GetVariantPlatform() const;
+
+ /**
+ * Set variant type.
+ * @param sVariantType variant type.
+ */
+ void SetVariantType(const string& sVariantType);
+
+ /**
+ * Get variant type.
+ * @return variant type.
+ */
+ string GetVariantType() const;
+
+ /**
+ * Set feature variant.
+ * @param sFeatureVariant feature variant.
+ */
+ void SetFeatureVariant(const string& sFeatureVariant);
+
+ /**
+ * Get feature variant.
+ * @return feature variant.
+ */
+ string GetFeatureVariant() const;
+
+ /**
+ * Set feature variant name.
+ * @param sFeatureVariantName feature variant name.
+ */
+ void SetFeatureVariantName(const string& sFeatureVariantName);
+
+ /**
+ * Get feature variant name.
+ * @return feature variant name.
+ */
+ string GetFeatureVariantName() const;
+
+ /**
+ * Set release path.
+ * @param sReleasePath release path.
+ */
+ void SetReleasePath(const string& sReleasePath);
+
+ /**
+ * Get release path.
+ * @return release path.
+ */
+ string GetReleasePath() const;
+
+ /**
+ * Set full variant path.
+ * @param sFullVariantPath full variant path.
+ */
+ void SetFullVariantPath(const string& sFullVariantPath);
+
+ /**
+ * Get full variant path.
+ * @return full variant path.
+ */
+ string GetFullVariantPath() const;
+
+ /**
+ * Set compile definition(s) of the module.
+ * @param sCompileDefinitions
+ */
+ void SetCompileDefinitions( const string& sCompileDefinitions );
+
+ /**
+ * Get compile definition(s) of the module.
+ * @return compile definition(s).
+ */
+ string GetCompileDefinitions() const;
+
+ /**
+ * Is modules target type udeb?
+ * @return true if modules target type is udeb.
+ */
+ bool IsUDEB() const;
+
+ /**
+ * Is module build successfully?
+ * This includes check of listing and map files from temporary directory.
+ * @return true if module build successfully.
+ */
+ bool IsMakeSuccessfull();
+
+ /**
+ * Get error string. This includes possible erros what are generated when
+ * IsMakeSuccesfull is called.
+ * @return error string.
+ */
+ string GetErrors() const;
+
+ /**
+ * Create build complete file to modules temporary directory.
+ * @return true if build complete file created successfully.
+ */
+ bool CreateBuildCompleteFile( void );
+
+ /**
+ * Read map file (armv5 platform).
+ * @return true if map file read successfully.
+ */
+ bool ReadMapFileArmv5();
+
+ /**
+ * Set compile info text
+ * @param sCompileInfoText
+ */
+ void SetCompileInfoText( string sCompileInfoText );
+
+ /**
+ * Get compile info text
+ * @return compile info text
+ */
+ string GetCompileInfoText() const;
+
+#ifndef MODULE_TEST
+private:
+#endif
+
+ /**
+ * Struct for saving source information
+ * sCpp is source file.
+ * sLst sources corresponding lst file.
+ * bStatic true if source information from static library.
+ */
+ struct SOURCE
+ {
+ bool bStatic;
+ string sCpp;
+ string sLst;
+ SOURCE() : bStatic(false), sCpp(""), sLst("") {}
+ };
+
+ // Build system
+ int m_eBuildSystem;
+ // Sbs v.1 makefile
+ string m_sMakeFile;
+ // Mmp file.
+ CATMmp m_Mmp;
+ // Temporary directory with path.
+ string m_sTempPath;
+ // Target.
+ string m_sTarget;
+ // Target type.
+ string m_sTargetType;
+ // True target extension.
+ string m_sRequestedTargetExt;
+ // Variant platform.
+ string m_sVariantPlatform;
+ // Variant type.
+ string m_sVariantType;
+ // Feature variant.
+ string m_sFeatureVariant;
+ // Feature variant name.
+ string m_sFeatureVariantName;
+ // Release path (releasables).
+ string m_sReleasePath;
+ // Full variant path (path to releasables).
+ string m_sFullVariantPath;
+ // String to store information of compile
+ string m_sCompileInfoText;
+ // String to store possible error messages.
+ string m_sErrors;
+ // Compile definition(s)
+ string m_sCompileDefinitions;
+ // Source files.
+ vector<SOURCE> m_vSources;
+ // Listing data.
+ vector<LINE_IN_FILE> m_vLineInFile;
+ // Modules map data (symbols).
+ vector<MAP_FUNC_INFO> m_vMapFileFuncList;
+ // File logging mode filename.
+ string m_sS60FileName;
+ // Is all data loaded for address to code line functions.
+ bool m_bAddressToLineInitialized;
+ // Read listing files (armv5 platform).
+ bool ReadListingFilesArmv5();
+ // Get listing file name of given source file.
+ string GetLstNameOfSource(string sSource) const;
+ // Copy listing files to temporary directory.
+ bool CopyLstFilesToTemp();
+ // Copy map file to temporary directory.
+ bool CopyMapFileToTemp();
+ // Get full map file name.
+ string GetMapFile() const;
+ // Get full symbol file name.
+ string GetSymbolFile() const;
+ // Get full binary file name.
+ string GetBinaryFile() const;
+ // Helper function to check is platform armv5.
+ bool IsPlatformArmv5() const;
+ // Get "unique" id of module
+ string GetUniqueId() const;
+ // Sbs v.1 variant urel label.
+ string m_sFeatureVariantURELLabel;
+ // Sbs v.1 variant udeb label.
+ string m_sFeatureVariantUDEBLabel;
+ // Object used to get codelines of memory addresses.
+ IAddressToLine* m_pAddressToLine;
+};
+#endif
+//EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/CATParseTraceFile.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,91 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Definitions for class CATParseTrace, CProcessData and
+* CSubTestData.
+*
+*/
+
+
+#ifndef __CATPARSETRACEFILE_H__
+#define __CATPARSETRACEFILE_H__
+
+#include "../inc/ATCommonDefines.h"
+#include "../inc/CATDataSaver.h"
+#include "../inc/CATBase.h"
+#include "../inc/catallocs.h"
+
+/**
+* Parses raw trace data to AnalyzeTool specific data file.
+*/
+class CATParseTraceFile : public CATBase
+{
+public:
+ /**
+ * Constructor
+ */
+ CATParseTraceFile();
+
+ /**
+ * Main function to start parse.
+ *
+ * @param pFileName A trace file name
+ * @param pOutputFileName Pointer to output file name
+ */
+ bool StartParse( const char* pFileName, const char* pOutputFileName );
+
+ /**
+ * Get data saver
+ * @return CATDataSaver*
+ */
+ CATDataSaver* GetDataSaver(void);
+
+#ifndef MODULE_TEST
+private:
+#endif
+ CATDataSaver m_DataSaver; /** Data saver */
+};
+
+/**
+* Represents data of a single subtest.
+*/
+class CSubTestData : public CATAllocs
+{
+public:
+ // Members
+
+ bool bRunning; /** Is sub test running */
+ vector<string> vData; /** data */
+ string sSubTestName; /** test name */
+ string sStartTime; /** start time */
+ string sEndTime; /** end time */
+ string sSubTestStartHandleCount; /** handle count at start */
+ string sSubTestEndHandleCount; /** handle count at end */
+};
+
+/**
+* Represents data of a single run.
+*/
+class CProcessData : public CATAllocs
+{
+public:
+ // Members
+
+ bool bProcessOnGoing; /** is process on going */
+ int iProcessID; /** process id (pid)*/
+ vector<string> vData; /** data */
+ vector<string> vHandleLeaks; /** handle leak(s) */
+ vector<CSubTestData> vSubTests; /** process sub test(s) */
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/CATParseXML.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Declarations for the class CATParseXML.
+*
+*/
+
+
+#ifndef __CATPARSEXML_H__
+#define __CATPARSEXML_H__
+
+#include "../inc/ATCommonDefines.h"
+
+/**
+* CATParseXML is used to parse xml data.
+*/
+class CATParseXML
+{
+public:
+ /**
+ * Constructor
+ */
+ CATParseXML(void);
+
+ /**
+ * Destructor
+ */
+ virtual ~CATParseXML(void);
+
+ /**
+ * Find epocroot path in xml file
+ * @param sourcePath Location of the xml file
+ */
+ string GetEpocRootPathFromXML(const char* sourcePath);
+};
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/CATProject.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,629 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Class representing a project.
+*
+*/
+
+
+#ifndef __CATPROJECT_H__
+#define __CATPROJECT_H__
+
+#include "ATCommonDefines.h"
+#include "CATBase.h"
+
+class CATModule2;
+class CATDatParser;
+
+// Raptor cmd and makefile constants used
+#define RAPTOR_CMD_BASE "sbs -b bld.inf --makefile=atool_temp/build/make_build --config="
+#define RAPTOR_MAKEFILE "atool_temp\\build\\make_build.default"
+#define RAPTOR_MAKEFILE_LOG " --logfile=atool_temp\\build\\makefile.xml"
+#define RAPTOR_BUILD_LOG " --logfile=atool_temp\\build\\build.xml"
+#define RAPTOR_REALLYCLEAN_LOG " --logfile=atool_temp\\build\\reallyclean.xml"
+#define RAPTOR_BUILD_LOG_NAME "atool_temp\\build\\build.xml"
+#define RAPTOR_LISTING_LOG " --logfile=atool_temp\\build\\listing.xml"
+
+#define RAPTOR_NOBUILD_SWITCH " --nobuild"
+#define RAPTOR_MAKEFILE_SWITCH "--makefile=atool_temp/build/make_build"
+
+
+// Raptor makefile constant variable names
+#define RAPTOR_PROJECT_META "PROJECT_META:="
+#define RAPTOR_SOURCE "SOURCE:="
+#define RAPTOR_TARGET "TARGET:="
+#define RAPTOR_TARGETYPE "TARGETTYPE:="
+#define RAPTOR_REQUESTEDTARGETEXT "REQUESTEDTARGETEXT:="
+#define RAPTOR_VARIANTPLATFORM "VARIANTPLATFORM:="
+#define RAPTOR_VARIANTTYPE "VARIANTTYPE:="
+#define RAPTOR_FEATUREVARIANT "FEATUREVARIANT:="
+#define RAPTOR_FEATUREVARIANTNAME "FEATUREVARIANTNAME:="
+#define RAPTOR_RELEASEPATH "RELEASEPATH:="
+#define RAPTOR_FULLVARIANTPATH "FULLVARIANTPATH:="
+#define RAPTOR_COMPILE_DEFINITIONS "CDEFS:="
+
+// Sbs v.1 makefile constants.
+#define MAKEFILE_SEARCH_STRING "@perl -S checksource.pl"
+#define MMPFILE_SEARCH_STRING "PRJ_MMPFILES MMP"
+#define MMPTESTFILE_SEARCH_STRING "PRJ_TESTMMPFILES MMP"
+#define SOURCE_PATH "SOURCEPATH"
+#define SOURCE_STRING "SOURCE"
+#define TARGET_STRING "TARGET"
+
+/**
+* CATProject represents a project (collection of modules).
+* It has to be set mode in which it operates like
+* compile / analyze and necessary parameters for that.
+* Then call Run method which also returs error codes
+* defined in AT_ERROR_CODES enumeration.
+* @author
+*/
+class CATProject : public CATBase
+{
+public:
+
+ /**
+ * Enumeration representing used build systems
+ */
+ enum BUILD_SYSTEM {
+ SBS_V1 = 1,
+ SBS_V2 = 2
+ };
+
+ /**
+ * Enumeration representing the mode project is run.
+ */
+ enum PROJECT_MODE {
+ COMPILE = 0,
+ INSTRUMENT = 1,
+ UNINSTRUMENT = 2,
+ UNINSTRUMENT_FAILED =3,
+ FAILED = 4,
+ CLEAN = 5,
+ ANALYZE = 6,
+ INSTRUMENT_CONSOLE = 7,
+ UNINSTRUMENT_CONSOLE = 8,
+ FAILED_CONSOLE = 9,
+ NOT_DEFINED = 10
+ };
+
+ /**
+ * Enumeration repserenting the logging mode.
+ */
+ enum LOGGING_MODE {
+ DEFAULT = 0,
+ FILE = 1,
+ TRACE = 2,
+ TRACE_FAST = 3
+ };
+
+ /**
+ * Enumeration representing build type.
+ */
+ enum BUILD_TYPE {
+ UREL = 0,
+ UDEB = 1
+ };
+
+public:
+
+ /**
+ * Constructor
+ */
+ CATProject();
+
+ /**
+ * Destructor
+ */
+ ~CATProject();
+
+ /**
+ * Set arguments.
+ * @param arguments.
+ * @return true if arguments ok.
+ */
+ bool SetArguments( ARGUMENTS& arguments );
+
+ /**
+ * Set build system to be used with project.
+ * See BUILD_SYSTEM enumeration for available systems.
+ * @param eSystem system.
+ */
+ void SetBuildSystem( BUILD_SYSTEM eSystem );
+
+ /**
+ * Set mode which to run.
+ * See PROJECT_MODE enumeration for available modes.
+ * @param eMode mode.
+ */
+ void SetMode(PROJECT_MODE eMode);
+
+ /**
+ * Get project mode.
+ * @return mode of project.
+ */
+ int GetMode() const;
+
+ /**
+ * Set epocroot.
+ * @param sEpocroot
+ */
+ void SetEpocRoot( const string& sEpocRoot );
+
+ /**
+ * Set project platform.
+ * @param sPlatform platform.
+ */
+ void SetPlatform( const string& sPlatform );
+
+ /**
+ * Set variant.
+ * @sVariant variant.
+ */
+ void SetVariant( const string& sVariant );
+
+ /**
+ * Set logging mode. See LOGGING_MODE enumeration for available modes.
+ * @param eLogginMode logging mode.
+ */
+ void SetLoggingMode( LOGGING_MODE eLoggingMode);
+
+ /**
+ * Set build type. See BUILD_TYPE enumeration for available types.
+ * @param eType build type.
+ */
+ void SetBuildType( BUILD_TYPE eType );
+
+ /**
+ * Set S60 logging filename.
+ * @param sFileName filename.
+ */
+ void SetS60FileName( const string& sFileName);
+
+ /**
+ * Set target module.
+ * @param sTargetModule target module name.
+ */
+ void SetTargetModule( const string& sTargetModule );
+
+ /**
+ * Set multiple target modules used in project.
+ * @param vTargetModules target module names.
+ */
+ void SetTargetModules( const vector<string>& vTargetModules );
+
+ /**
+ * Set Binary target name to create analysis results to.
+ * @param sBinaryTarget binary target name.
+ */
+ void SetBinaryTarget( const string& sBinaryTarget );
+
+ /**
+ * Set data file to analyze.
+ * @param sDataFile datafile.
+ */
+ void SetDataFile( const string& sDataFile );
+
+ /**
+ * Set rom symbol file(s) used in analyze.
+ * @param sRomSymbolFile.
+ */
+ void SetRomSymbolFiles(const vector<string>& vRomSymbolFiles);
+
+ /**
+ * Set the logging level of analysis report.
+ * @param iLogLevel log level.
+ */
+ void SetLogLevel( int iLogLevel );
+
+ /**
+ * Set the size of allocation call stack to be written in temporary cpp.
+ * @param iAllocCallStackSize
+ */
+ void SetAllocCallStackSize( int iAllocCallStackSize );
+
+ /**
+ * Set the size of free call stack to be written in temporary cpp.
+ * @param iFreeCallStackSize
+ */
+ void SetFreeCallStackSize( int iFreeCallStackSize );
+
+ /**
+ * Set the output file name to store analyse report.
+ * @param sDataFileOutput data file name.
+ */
+ void SetDataFileOutput( const string& sDataFileOutput );
+
+ /**
+ * Set build command used in compile phase.
+ * @param sBuildCommand build command.
+ */
+ void SetBuildCommand( const string& sBuildCommand );
+
+ /**
+ * Run the set mode.
+ * @return error code.
+ */
+ int Run();
+
+ /**
+ * Run recovery, used when "instatly" need to recover modules and exit.
+ */
+ int RunRecoveryAndExit();
+
+ /**
+ * Get build type string.
+ * @param eType type from which to get correponding string.
+ * @return types corresponding string.
+ */
+ static string GetBuildTypeString( int eType );
+
+ /**
+ * Reads projects configuration file if it exists.
+ * @return false in case the data contains information that project is uninstrumented. Otherwise returns always true.
+ */
+ bool IsUninstrumented();
+
+#ifndef MODULE_TEST
+private:
+#endif
+ /**
+ * Run compiling in console.
+ * @return error code.
+ */
+ int RunCompile( void );
+
+ /**
+ * Run cleaning project.
+ * @return error code.
+ */
+ int RunClean( void );
+
+ /**
+ * Run running analyze.
+ * @return error code.
+ */
+ int RunAnalyze( void );
+
+ /**
+ * Run instrumenting of project for Carbide extension (pre-build).
+ * @return error code.
+ */
+ int RunInstrument( void );
+
+ /**
+ * Run uninstrumenting of project for Carbide extension (post-build).
+ * @return error code.
+ */
+ int RunUninstrument( void );
+
+ /**
+ * Run uninstrumenting of project for Carbide extension(post-build), when build failed.
+ * @return error code.
+ */
+ int RunUninstrumentFailed( void );
+
+ /**
+ * Run console instrumenting.
+ * @return error code.
+ */
+ int RunInstrumentConsole( void );
+
+ /**
+ * Run Console uninstrumenting.
+ * @return error code.
+ */
+ int RunUninstrumentConsole( void );
+
+ /**
+ * Run console uninstrumenting, when build failed.
+ * @return error code.
+ */
+ int RunFailedConsole( void );
+
+ /**
+ * Show summary of compilation.
+ */
+ void DisplayCompileSummary( void );
+
+ /**
+ * Show summary, build target, build type, logging mode...
+ */
+ void DisplayBuildSummary( void );
+
+ /**
+ * Create make files.
+ * @return true if successful
+ */
+ bool CreateMakeFile( void );
+ /**
+ * Create SBS v.1 make files.
+ * @return true if successful.
+ */
+ bool CreateMakeFileSbs1( void );
+ /**
+ * Copy sbs1 makefile to temporary folder.
+ * @return true if successful.
+ */
+ bool CopyMakeFileSbs1ToTemporaryFolder( void );
+ /**
+ * Run really clean in SBS v.1.
+ * @return true if successful.
+ */
+ bool RunReallyCleanSbs1( void );
+ /**
+ * Run really clean in SBS v.2.
+ * @return true if successful.
+ */
+ bool RunReallyCleanSbs2( void );
+ /**
+ * Run export in SBS v.1.
+ * @return true if successful.
+ */
+ bool RunExportSbs1( void );
+ /**
+ * Create make files (level2) SBS v.1.
+ * @return true if successful.
+ */
+ bool CreateMakeFileSbs1Level2( void );
+ /**
+ * Create makefile SBS v.2.
+ * @return true if successful.
+ */
+ bool CreateMakeFileSbs2( void );
+ /**
+ * Read makefile.
+ * @return true if successful.
+ */
+ bool ReadMakeFile( void );
+ /**
+ * Read SBS v.1 makefile.
+ * @return true if successful.
+ */
+ bool ReadMakeFileSbs1( void );
+ /**
+ * Read SBS v.1 makefile (Level1).
+ * @return true if successful.
+ */
+ bool ReadMakeFileSbs1Level1( void );
+ /**
+ * Read SBS v.2 makefiles.
+ * @return true if successful.
+ */
+ bool ReadMakeFileSbs2( void );
+ /**
+ * Read specified SBS v.2 makefile.
+ * @param sMakeFile makefile to be read.
+ * @return true if succesful.
+ */
+ bool ReadMakeFileSbs2( string& sMakeFile );
+
+ /**
+ * Filter unsupported and static libraries to their own vectors.
+ * Unsupported include kernel types, modules with kernel mode compile definition.
+ * @return true if successful.
+ */
+ bool FilterModules();
+
+ /**
+ * Creates temporary directories for all modules
+ * in member vector.
+ * @return true if successful.
+ */
+ bool CreateTemporaryDirectories();
+
+ /**
+ * Creates tempororary cpp files for all modules
+ * in member vector.
+ * @return true if successful.
+ */
+ bool CreateTemporaryCpps();
+
+ /**
+ * Hooks all modules in member vector
+ * (modifies mmp files)
+ * @return true if successful
+ */
+ bool ModifyModules( void );
+
+ /**
+ * Unhooks all modules in member vector
+ * (removes changes from mmp files)
+ * @return true if successful
+ */
+ bool RestoreModules( void );
+
+ /**
+ * Verifys that member vectors modules
+ * mmp files unchanged. Restores if they are
+ * from backup or from original.
+ * @return true if successful
+ */
+ bool VerifyAndRecoverModules( void );
+
+ /**
+ * Runs compilation.
+ * @return true if successful.
+ */
+ bool Compile( void );
+ /**
+ * @return true if successful.
+ */
+ bool CompileSbs1( void );
+ /**
+ * @return true if successful.
+ */
+ bool CompileSbs2( void );
+
+ /**
+ * Runs listing creatation.
+ * @return true if successful
+ */
+ bool CreateListings( void );
+ /**
+ * @return true if successful.
+ */
+ bool CreateListingsSbs1( void );
+ /**
+ * @return true if successful.
+ */
+ bool CreateListingsSbs2( void );
+ /**
+ * Copies releasables of modules including lst & map files
+ * for all modules in project to their temporary directories.
+ * @return true if successful.
+ */
+ bool CopyReleasables( void );
+ /**
+ * Deletes all atool_temp directories
+ * of member vector modules.
+ * @return true if successful.
+ */
+ bool DeleteTemporaryDirs( void );
+ /**
+ * Deletes files from atool_temp directory
+ * of member vector modules which extension not defined
+ * in TEMP_EXTENSION_NO_DELETE table.
+ * @return true if successful.
+ */
+ bool CleanTemporaryDirs( void );
+ /**
+ * Writes class attributes to a file
+ * under atool_temp directory.
+ * @return true if successful.
+ */
+ bool WriteAttributes( void ) const;
+ /**
+ * Read class attributes from a file
+ * under atool_temp directory.
+ * @return true if successful.
+ */
+ bool ReadAttributes( void );
+
+ /**
+ * Creates atool_temp directory if it does not
+ * exist in current directory.
+ * @return true if successful.
+ */
+ bool MakeTempDirIfNotExist( void );
+
+#ifndef MODULE_TEST
+private:
+#endif
+
+ /**
+ * Clean all module vectors.
+ */
+ void CleanModuleVectors();
+
+ /**
+ * Get build type as string.
+ * @return buildtype string.
+ */
+ string GetBuildTypeString();
+
+ /**
+ * Helper function to add target module(s)
+ * if any defined in class to given sbs command.
+ * @param sCmd command to add modules to.
+ */
+ void AddTargetModuleIfDefined(string& sCmd);
+
+ /**
+ * Run given system/abld command to all defined target modules in vector.
+ * Space char (if its missing) will be added to given command + one target
+ * module at a time.
+ * @param sCommand sCommand to run.
+ * @return true if none system call sets error level other than 0.
+ */
+ bool RunAbldCommandToAllTargets( const string& sCommand );
+
+ /**
+ * Check is target module in project.
+ * If no modules / targets defined return value is true.
+ * @return true if target module is in project.
+ */
+ bool IsTargetModuleInProject( void ) const;
+
+ /**
+ * Initializes member make file variable with correct full path to point (epoc32/build)...
+ * @return true if successful.
+ */
+ bool InitSbs1MakeFileWithPath();
+
+ /**
+ * Initializes member make file variable with correct full path to (atoo_temp...)
+ * @return true if successful.
+ */
+ bool InitSbs1MakeFileWithPathToTemp();
+
+#ifndef MODULE_TEST
+private:
+#endif
+ // System current directory.
+ char m_cCurrentDir[ MAX_LINE_LENGTH ];
+ // Projects build system
+ int m_eBuildSystem;
+ // Project modules.
+ vector<CATModule2*> m_vModules;
+ // Static libraries.
+ vector<CATModule2*> m_vStaticLibraries;
+ // Unsupported project modules.
+ vector<CATModule2*> m_vUnsupportedModules;
+ // Run mode.
+ int m_eMode;
+ // Logging level (used in analyse).
+ int m_iLoggingLevel;
+ // Is project unsinstrumented.
+ bool m_bUninstrumented;
+ // Is build just for test modules
+ bool m_bAbldTest;
+ // Build command.
+ string m_sBuildCommand;
+ // Epocroot
+ string m_sEpocRoot;
+ // Platform i.e. armv5.
+ string m_sPlatform;
+ // SBS2 variant.
+ string m_sVariant;
+ // Logging mode (used in compile,instrumenting).
+ int m_eLoggingMode;
+ // Allocation call stack size
+ int m_iAllocCallStackSize;
+ // Free call stack size
+ int m_iFreeCallStackSize;
+ // Build type udeb / urel.
+ int m_eBuildType;
+ // Sbs v.1 level 1 make file
+ string m_sMakeFile;
+ // User given S60 log file name.
+ string m_sS60FileName;
+ // Target module.
+ string m_sTargetModule;
+ // Target modules (used in carbide instrumenting).
+ vector<string> m_vTargetModules;
+ // Binary target (used in analyse).
+ string m_sBinaryTarget;
+ // User given datafile to analyse.
+ string m_sDataFile;
+ //
+ vector<string> m_vRomSymbolFiles;
+ // Temporary data file name if user gave trace file.
+ string m_sDataFileTemp;
+ // User given output file to store analyse results.
+ string m_sDataFileOutput;
+ // Analyser object.
+ CATDatParser* m_pAnalyzer;
+};
+#endif
+// End of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/cataddr2line.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,130 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Windows debug api implementation for IAddressToLine interface.
+*
+*/
+
+#ifndef __CATADDR2LINE_H__
+#define __CATADDR2LINE_H__
+
+#include "iaddresstoline.h"
+#include "../inc/cataddr2lineserver.h"
+
+// Allowed characters in output.
+//const char ADDR2LINEALLOWEDCHARS[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :/\\_.-";
+
+/**
+* Implements addresstoline interface using one of the GNU binutils tool called addr2line.
+* This is used on gcce platform. In release build type also map files are used.
+*/
+class CATAddr2line : public IAddressToLine
+{
+
+public:
+
+ /**
+ * Constructor
+ */
+ CATAddr2line();
+
+ /**
+ * Open binary.
+ * @sString Full filename with path to binary.
+ * @iLong base address of binary.
+ * @return true if successful.
+ */
+ bool Open( const string& sString, const unsigned long iLong);
+
+ /**
+ * Get error string. In case of any method failed use this to acquire details on error.
+ * @return error string.
+ */
+ string GetError( void );
+
+ /**
+ * Close binary.
+ * @return true if succesful.
+ */
+ bool Close( void );
+
+ /**
+ * Locate code line and file for given address.
+ * @result
+ * @return true if successful.
+ */
+ bool AddressToLine( CATMemoryAddress* result );
+
+#ifndef MODULE_TEST
+private:
+#endif
+
+ // Modules map data (symbols).
+ vector<MAP_FUNC_INFO> m_vMapFileFuncList;
+
+ //Map file name
+ string m_sMapFileName;
+
+ //Addr2line server class
+ CATAddr2lineServer server;
+
+ /**
+ * Get function name for given address.
+ * @iAddress Memory address as unsigned long.
+ * @return Function name as string or empty string if not found.
+ */
+ string GetFunctionNameUsingAddress( unsigned long iAddress );
+
+ /**
+ * Read map file (armv5 platform).
+ * @return true if map file read successfully.
+ */
+ bool ReadMapFileArmv5();
+
+ //Note: New filtering functions commented out until they are taken into use.
+ //These were part of task which would filter unwanted characters, etc.. from results.
+
+ /**
+ * Filter any char not defined in constant
+ * ADDR2LINEALLOWEDCHARS from given string.
+ * @param sString string to be filtered.
+ */
+ //void FilterString( string &sString );
+
+ /**
+ * Find first occurence of LF/CR from string.
+ * @param sString string to find LF/CR.
+ * @return position of first occurence.
+ */
+ //size_t FindLineFeed( const string& sString );
+
+ /**
+ * Erase all LF/CR from start of the string until other
+ * characters are found.
+ * @param sString string to erase LF/CR.
+ */
+ //void EraseUntilNoLineFeed( string& sString );
+
+ /**
+ * Split string containing multiple lines with mixed line feeds to
+ * vector of lines.
+ * @sMultiLineString string containing multiple lines.
+ * @return vector containing one line per cell.
+ */
+ //vector<string> SplitToStrings( string& sMultiLineString );
+
+ //Debugging for addr2line task.
+ //ofstream debug;
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/cataddr2lineserver.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,93 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Defines CATAddr2lineServer class.
+*
+*/
+
+#ifndef __CATADDR2LINESERVER_H__
+#define __CATADDR2LINESERVER_H__
+
+// Includes.
+#include "ATCommonDefines.h"
+
+#define BUFSIZE 4096
+
+/**
+* This class "runs" the addr2line binary as a server for CATAddr2Line.
+* It redirects the pipes from the tool.
+*/
+class CATAddr2lineServer
+{
+public:
+
+ //Creator
+ CATAddr2lineServer();
+
+ //Destructor
+ ~CATAddr2lineServer();
+
+ /**
+ * Get function name for given address.
+ * @sFullPathAndBinaryName
+ * @return True if initialization succesfull.
+ */
+ bool Initialize( const string& sFullPathAndBinaryName );
+
+ /**
+ * Write data to a pipe.
+ * @sAddress
+ */
+ VOID WriteToPipe( const string& sAddress );
+
+ /**
+ * Read data to a pipe.
+ * @return Data from pipe.
+ */
+ string ReadFromPipe(VOID);
+
+ /**
+ * Gets process created state.
+ * @return True if process created successfully.
+ */
+ bool GetProcessCreatedState( void );
+
+#ifndef MODULE_TEST
+private:
+#endif
+
+ HANDLE m_hChildStdinRd, m_hChildStdinWr, m_hChildStdinWrDup,
+ m_hChildStdoutRd, m_hChildStdoutWr, m_hChildStdoutRdDup,
+ m_hChildErroutRd, m_hChildErroutWr, m_hChildErroutRdDup,
+ m_hSaveStdin, m_hSaveStdout, m_hSaveErrout;
+
+ SECURITY_ATTRIBUTES m_saAttr;
+ string m_sFullPathAndBinaryName;
+ bool m_bProcessCreated;
+
+ /**
+ * Creates child process for addr2line.exe.
+ * @return True if process created successfully.
+ */
+ BOOL CreateChildProcess(VOID);
+
+ /**
+ * Prints error and returns false.
+ * @param sInput error string.
+ * @return false.
+ */
+ bool PrintErrorAndExit( const string sInput );
+
+
+};
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/catalloc.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,59 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Defines CATAlloc class.
+*
+*/
+
+
+#ifndef __CATALLOC_H__
+#define __CATALLOC_H__
+
+#include "../inc/ATCommonDefines.h"
+
+/**
+* Class representing single memory allocation.
+*/
+class CATAlloc
+{
+public:
+ /**
+ * Constructor.
+ */
+ CATAlloc() : m_iCSCount(0) {}
+
+ /**
+ * Destructor.
+ */
+ ~CATAlloc(){}
+
+ /**
+ * Get alloc string after address, it contains:
+ * time, size, call stack..
+ * @return string allocation string
+ */
+ string GetAllocString();
+
+ // Members
+
+ string m_sTime; /** Allocation time */
+
+ string m_sSize; /** Allocation size */
+
+ unsigned long m_iCSCount; /** Call stack address count */
+
+ map<unsigned long,string> m_vCallStack; /** Call stack where packet number is key */
+
+};
+#endif
+//EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/catallocs.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,87 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Defines CATAllocs "collection" class.
+*/
+
+#ifndef __CATALLOCS_H__
+#define __CATALLOCS_H__
+
+#include "../inc/ATCommonDefines.h"
+#include "../inc/CATBase.h"
+#include "../inc/catalloc.h"
+
+/**
+* Class representing a collection of memory allocations.
+* It is used to acquire the data of memory leaks by giving all
+* data on single allocations and frees.
+*/
+class CATAllocs : public CATBase
+{
+public:
+
+ /**
+ * "old" alloc message (prior to 1.6).
+ * @param sAllocString allocation string
+ */
+ void Alloc( const string& sAllocString );
+
+ /*
+ * Alloc header message (multimessage call stack).
+ * @param sAllocHString allocation string
+ */
+ void AllocH( const string& sAllocHString );
+
+ /*
+ * Alloc fragment message (fragment of call stack in multimessage alloc).
+ * @param sAllocFString allocation string
+ */
+ void AllocF( const string& sAllocFString );
+
+ /**
+ * Free message.
+ * @param sFreeString string
+ */
+ void Free( const string& sFreeString );
+
+ /**
+ * Free header message.
+ * (not implemented yeat.)
+ * @param sFreeHString string
+ */
+ void FreeH( const string& sFreeHString );
+
+ /**
+ * Free fragment message.
+ * (not implemented yeat.)
+ * @param sFreeFString string
+ */
+ void FreeF( const string& sFreeFString );
+
+ /**
+ * Get "leak" list ordered by allocation time.
+ * @param vLeakList container where leaks stored
+ */
+ void GetLeakList( vector<string>& vLeakList);
+
+ /**
+ * Clear leaks.
+ */
+ void ClearAllocs();
+#ifndef MODULE_TEST
+private:
+#endif
+ map<string, CATAlloc> m_vAllocs; /** Collection of allocation(s) */
+};
+#endif
+//EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/catdbghelper.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,97 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Defines the CATDbgHelper class.
+*
+*/
+
+
+#include "iaddresstoline.h"
+// Static variable to represent state of dbghelper api.
+static bool CDBGHELPER_OPEN = false;
+static unsigned int CDBGHELPER_CLIENTS = 0;
+
+// Used "virtual" offset for all loaded modules and addresses.
+// This is used so no module is loaded to the binary address range of atool.exe.
+const unsigned long AT_VIRTUAL_OFFSET_DBGHELPER = 0x1000000;
+
+/**
+* Provides feature to locate code lines using Windows Debug Api. This is done
+* by using dbghelper library. Implements the IAddressToLine interface.
+*/
+class CATDbgHelper : public IAddressToLine
+{
+
+public:
+
+ /**
+ * Constructor
+ */
+ CATDbgHelper();
+
+ /**
+ * Destructor
+ */
+ ~CATDbgHelper();
+
+ /**
+ * Open binary.
+ * @sString Full filename with path to binary.
+ * @iLong base address of binary.
+ * @return true if successful.
+ */
+ bool Open( const string& sString, const unsigned long iLong);
+
+ /**
+ * Get error string. In case of any method failed use this to acquire details on error.
+ * @return error string.
+ */
+ string GetError( void );
+
+ /**
+ * Close binary.
+ * @return true if succesful.
+ */
+ bool Close( void );
+
+ /**
+ * Read map file for function's.
+ */
+ void ReadMapFile( const string sMapFileName );
+
+ /**
+ * Locate code line and file for given address.
+ * @result
+ * @return true if successful.
+ */
+ bool AddressToLine( CATMemoryAddress* result );
+
+ /**
+ * Try get function name for address (only when map is read).
+ * @result
+ * @return true if succesful.
+ */
+ bool AddressToFunction( CATMemoryAddress* result );
+
+#ifndef MODULE_TEST
+private:
+#endif
+ // Base address used.
+ DWORD64 m_BaseAddress;
+ // Map file read?
+ bool m_bMap;
+ // Map file functions.
+ vector<MAP_FUNC_INFO> m_vMapFileFuncList;
+ // Binary in file system.
+ PSTR m_pBinaryFile;
+};
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/catfilereader.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,86 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Defines CATFileReader class.
+*
+*/
+
+
+#ifndef __CATFILEREADER_H__
+#define __CATFILEREADER_H__
+
+#include "ATCommonDefines.h"
+
+/**
+* Provides a feature to read a file as single block into memory and parse it
+* from there line by line (iterating). This can fail or be very slow if file
+* size is bigger than available physical memory for process.
+* But is faster when file fits in free physical memory.
+*/
+class CATFileReader
+{
+public:
+ /**
+ * Constructor.
+ */
+ CATFileReader();
+ /**
+ * Destructor.
+ */
+ ~CATFileReader();
+#ifndef MODULE_TEST
+private:
+#endif
+ /**
+ * Prevent copy of this class.
+ */
+ CATFileReader& operator =( const CATFileReader& /*other*/ ) { }
+ CATFileReader( const CATFileReader& /*other*/ ) { }
+public:
+ /**
+ * Open/Read file.
+ * @param cFile file to be read/opened.
+ * @return true if succesful.
+ */
+ bool Open( const char* cFile );
+ /**
+ * Close file.
+ * @return true if succesful.
+ */
+ bool Close( void );
+ /**
+ * Get line from file.
+ * @sLine where line content is stored.
+ * @return true if lines left.
+ */
+ bool GetLine( string& sLine );
+ /**
+ * Set the line delimiter.
+ * @param cDelimiter char that ends the line.
+ */
+ void SetDelimiter( char cDelimiter );
+ /**
+ * Get current line delimiter.
+ * @return char that ends the line.
+ */
+ char GetDelimiter() const;
+#ifndef MODULE_TEST
+private:
+#endif
+ // Stream where file content is stored.
+ stringstream m_stream;
+ // Line delimiting character used.
+ char m_cDelimiter;
+};
+#endif
+// EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/catromsymbol.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,196 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Defines CATRomSymbol, RofsBinary classes and Symbol
+* structure.
+*
+*/
+
+
+#ifndef __CATROMSYMBOL_H__
+#define __CATROMSYMBOL_H__
+
+#include "ATCommonDefines.h"
+#include "iaddresstoline.h"
+
+const string ROM_SYMBOL_IDENTIFY_STRING = "80";
+const string ROFS_SYMBOL_IDENTIFY_STRING = "00";
+const int IDENTIFY_MAX_LINES_READ = 20;
+
+/**
+* Represents a single symbol in a binary.
+*/
+struct Symbol
+{
+ unsigned long iStartAddress; /** Start address */
+ unsigned long iEndAddress; /** End address */
+ string sFunction; /** Function/Symbol name */
+ /**
+ * Default constructor for structure to set default values
+ */
+ Symbol() { iStartAddress=0; iEndAddress=0; sFunction = ""; }
+ /**
+ * Empty destructor
+ */
+ ~Symbol() {}
+};
+
+
+/**
+* Represents a single binary in ROM/ROFS which
+* contains a collection of Symbols.
+*/
+class RofsBinary {
+public:
+ /**
+ * Constructor
+ */
+ RofsBinary();
+ /**
+ * Constructor
+ * @param sbinary
+ */
+ RofsBinary( const string& sbinary );
+ /**
+ * Destructor
+ */
+ ~RofsBinary();
+
+ // Members
+
+ string m_sBinary; /** Binary / code segment */
+ vector<Symbol*> vSymbols; /** Collection of symbols */
+};
+
+/**
+* Implements IAddressToLine interface to acquire symbol information
+* using memory addresses from rom/rofs symbol files.
+*/
+class CATRomSymbol : public IAddressToLine
+{
+public:
+ /**
+ * Constructor.
+ */
+ CATRomSymbol();
+ /**
+ * Destructor.
+ */
+ virtual ~CATRomSymbol();
+ bool m_bShowProgressMessages; /** "Flag" will we show progress when reading files */
+ /**
+ * Empty functions does nothing returns false always.
+ * @param sString
+ * @param iLong
+ * @return true if successful.
+ */
+ bool Open( const string& sString, const unsigned long iLong);
+ /**
+ * Set symbol files.
+ * This also checks that files exists and identifies them as rom/rofs.
+ * @param vSymbols
+ * @return bool
+ */
+ bool SetSymbols( const vector<string>& vSymbols);
+ /**
+ * Get error string. In case of any method failed use this to acquire details on error.
+ * @return error string.
+ */
+ string GetError( void );
+ /**
+ * Close rom symbol file.
+ * @return true if succesful.
+ */
+ bool Close( void );
+ /**
+ * Locates symbol and binary name for given address if found in rom.
+ * @param result memory address object.
+ * @return true if successful.
+ */
+ bool AddressToLine( CATMemoryAddress* result );
+#ifndef MODULE_TEST
+private:
+#endif
+ /**
+ * Represents the symbol files type
+ * (content is different / format )
+ */
+ enum SYMBOL_FILE_TYPE {
+ SYMBOL_FILE_INVALID = 0, /** not valid */
+ SYMBOL_FILE_ROM, /** rom type */
+ SYMBOL_FILE_ROFS /** rofs type */
+ };
+ /**
+ * Identify symbol file
+ * @param sFile
+ * @return int
+ */
+ int IdentifySymbolFile( const string& sFile );
+ /**
+ * Locate symbol and binary name for given address if found in rom.
+ * @param result
+ * @return bool
+ */
+ bool AddressToLineRom( CATMemoryAddress* result );
+ /**
+ * Locate symbol and binary name for given address if found in rofs.
+ * @param result
+ * @return bool
+ */
+ bool AddressToLineRofs( CATMemoryAddress* result );
+ /**
+ * Reads rom files.
+ * @return bool
+ */
+ bool ReadRomFiles();
+ /**
+ * Read specified rom file
+ * @param sFile
+ * @return bool
+ */
+ bool ReadRomFile( const string& sFile );
+ /**
+ * Read rofs files
+ * @return bool
+ */
+ bool ReadRofsFiles();
+ /**
+ * Read specified rofs file
+ * @param sFile
+ * @return bool
+ */
+ bool ReadRofsFile( const string& sFile );
+ /**
+ * Parse symbol from a line in rom/rofs file.
+ * @param sLine
+ * @param pSymbol
+ */
+ void ParseSymbolFromLine( const string& sLine, Symbol* pSymbol );
+#ifndef MODULE_TEST
+private:
+#endif
+
+ // Members
+
+ bool m_bFilesIdentified; /** Have we identified symbol file(s) */
+ bool m_bSymbolsRead; /** Have we read symbol file(s) */
+ vector<string> m_vRomFiles; /** Rom symbol file(s) */
+ vector<Symbol*> m_vRomCache; /** Cached rom symbols */
+ vector<Symbol*> m_vRomSymbols; /** All rom symbols */
+ unsigned long m_iRomStartAddress; /** Rom start address */
+ unsigned long m_iRomEndAddress; /** Rom end address */
+ vector<string> m_vRofsFiles; /** Rofs symbol file(s) */
+ vector<RofsBinary*> m_vRofsBinaries; /** Rofs binaries */
+ string m_sErrorMessage; /** Error message */
+};
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/iaddresstoline.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,60 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Interface definition for locating code lines using memory addresses.
+*
+*/
+#ifndef __IADDRESSTOLINE_H__
+#define __IADDRESSTOLINE_H__
+
+#include "ATCommonDefines.h"
+
+class CATMemoryAddress;
+
+/**
+* Codeline locating interface. Thru this interface CATModule2 locates code lines
+* using different implementations depending on platform.
+*/
+class IAddressToLine
+{
+public:
+ IAddressToLine() {};
+ virtual ~IAddressToLine() {};
+ /**
+ * Open binary.
+ * @sString
+ * @iNumber
+ * @return true if successful.
+ */
+ virtual bool Open( const string& sString, const unsigned long iLong) = 0;
+
+ /**
+ * Get error string. In case of any method failed use this to acquire details on error.
+ * @return error string.
+ */
+ virtual string GetError( void ) = 0;
+
+ /**
+ * Close binary.
+ * @return true if succesful.
+ */
+ virtual bool Close( void ) = 0;
+
+ /**
+ * Locate code line and file for given address.
+ * @result
+ * @return true if successful.
+ */
+ virtual bool AddressToLine( CATMemoryAddress* result ) = 0;
+};
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/inc/stdafx.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,45 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Include file for standard system include files,
+* or project specific include files that are used frequently, but
+* are changed infrequently.
+* Version : %version: 1 %
+*
+*/
+
+
+#pragma once
+
+// MemoryLeak checking function.
+// Note! Do not comming in svn with this flag enabled.
+//#define MEM_LEAK_CHECK
+
+// Addr2line binary used.
+//#define ADDR2LINE
+
+#ifdef MEM_LEAK_CHECK
+#define _CRTDBG_MAP_ALLOC
+#include <stdlib.h>
+#include <crtdbg.h>
+#endif
+
+#include <tchar.h>
+#include <fstream> //ifstream,ofstream
+#include <windows.h>
+#include <string> //string
+#include <vector> //string
+#include <sstream> //stringstream
+#include <iostream> // cout
+#include <map> // map
+#include <time.h>
\ No newline at end of file
Binary file analyzetool/commandlineengine/install/addr2line.exe has changed
Binary file analyzetool/commandlineengine/install/atool.exe has changed
Binary file analyzetool/commandlineengine/install/binutils-2.19.1-src.zip has changed
Binary file analyzetool/commandlineengine/install/xerces-c_2_7.dll has changed
Binary file analyzetool/commandlineengine/lib/xerces-c_2.lib has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/CATBase.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,1299 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Definitions for the class CATBase.
+*
+*/
+
+
+#include "../inc/CATBase.h"
+#include "../inc/CATParseXML.h"
+
+// -----------------------------------------------------------------------------
+// CATBase::CATBase
+// Constructor.
+// -----------------------------------------------------------------------------
+CATBase::CATBase(void)
+{
+ LOG_FUNC_ENTRY("CATBase::CATBase");
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::~CATBase
+// Destructor.
+// -----------------------------------------------------------------------------
+CATBase::~CATBase(void)
+{
+ LOG_FUNC_ENTRY("CATBase::~CATBase");
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::ChangeToLower
+// Converts any uppercase letter to lowercase.
+// -----------------------------------------------------------------------------
+void CATBase::ChangeToLower( string& sInput )
+{
+ LOG_LOW_FUNC_ENTRY("CATBase::ChangeToLower");
+ int iLength = (int)sInput.size();
+ for( int i = 0 ; i < iLength ; i++ )
+ {
+ sInput[i] = (char)tolower( sInput[i] );
+ }
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::ChangeToUpper
+// Converts any uppercase letter to lowercase.
+// -----------------------------------------------------------------------------
+void CATBase::ChangeToUpper( string& sInput )
+{
+ LOG_LOW_FUNC_ENTRY("CATBase::ChangeToUpper");
+ int iLength = (int)sInput.size();
+ for( int i = 0 ; i < iLength ; i++ )
+ {
+ sInput[i] = (char)toupper( sInput[i] );
+ }
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::TrimString
+// Remove spaces and tabulatures from beginning and
+// end of given string.
+// -----------------------------------------------------------------------------
+void CATBase::TrimString( string& sInput )
+{
+ LOG_LOW_FUNC_ENTRY("CATBase::TrimString");
+ if( sInput.empty() )
+ return;
+ //Remove spaces and tabulatures from beginning of string
+ while( !sInput.empty() && ( sInput[0] == SPACE_CHAR_VALUE || sInput[0] == TAB_CHAR_VALUE ) )
+ {
+ sInput.erase( 0, 1 );
+ }
+ //Remove spaces and tabulatures from end of string
+ while( !sInput.empty() && ( sInput[sInput.size()-1] == SPACE_CHAR_VALUE || sInput[sInput.size()-1] == TAB_CHAR_VALUE ) )
+ {
+ sInput.erase( sInput.size()-1, 1 );
+ }
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::SearchFileWithExtension
+// Searches files with given extension from path.
+// -----------------------------------------------------------------------------
+bool CATBase::SearchFileWithExtension( const char* pPathAndExt, bool bPrintErrors, string& sErrorLog )
+{
+ LOG_FUNC_ENTRY("CATBase::SearchFileWithExtension");
+ WIN32_FIND_DATA FindFileData;
+ HANDLE hFind;
+ string sTemp( pPathAndExt );
+
+ //Find file
+ hFind = FindFirstFile( sTemp.c_str(), &FindFileData );
+ if (hFind == INVALID_HANDLE_VALUE)
+ {
+ string sErrorString( "No " );
+ //Get extension
+ string sExt( pPathAndExt );
+ sExt.erase( 0, sExt.find_last_of( "." ) );
+
+ sErrorString.append( sExt );
+ sErrorString.append( " files in directory: " );
+
+ string sWithoutExt( pPathAndExt );
+ sWithoutExt.erase( sWithoutExt.find_last_of( "." )-1, string::npos );
+ sErrorString.append( sWithoutExt );
+
+ if( bPrintErrors )
+ {
+ //string sTemp( pPathAndExt );
+ //printf( "Can not find: %s.\n", pPathAndExt );
+ printf( sErrorString.c_str() );
+ }
+ else
+ {
+ //Add line change if sErrorString not empty
+ if( !sErrorLog.empty() )
+ sErrorString.insert( 0, "\n" );
+ sErrorLog.append( sErrorString );
+ }
+ return false;
+ }
+ else
+ {
+ FindClose(hFind);
+ return true;
+ }
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::GetPathOrFileName
+// Returns path to file or file name.
+// -----------------------------------------------------------------------------
+string CATBase::GetPathOrFileName( bool bFileName, string sInput )
+{
+ LOG_LOW_FUNC_ENTRY("CATBase::GetPathOrFileName");
+ string sRet;
+ size_t iPos = sInput.size();
+
+ sInput = ChangeSlashToBackSlash( sInput );
+
+ //Find character '\' starting from end of string
+ while( iPos > 0 && sInput[iPos] != '\\' )
+ {
+ iPos--;
+ }
+ if( iPos > 0 )
+ {
+ //Return file name
+ if( bFileName )
+ {
+ sInput.erase( 0, iPos+1 );
+ sRet = sInput;
+ }
+ else //Return file path
+ {
+ sInput.erase( iPos+1, string::npos );
+ sRet = sInput;
+ }
+ }
+ else
+ {
+ if( !bFileName )
+ return sRet;
+ sRet = sInput;
+ }
+ return sRet;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::GetFileNameUsingExt
+// Searches files with given extension from path.
+// -----------------------------------------------------------------------------
+string CATBase::GetFileNameUsingExt( const char* pPathAndExt )
+{
+ LOG_FUNC_ENTRY("CATBase::GetFileNameUsingExt");
+ WIN32_FIND_DATA FindFileData;
+ HANDLE hFind;
+ string sRet;
+
+ //Find file
+ hFind = FindFirstFile( pPathAndExt, &FindFileData );
+ if (hFind == INVALID_HANDLE_VALUE)
+ {
+ //if( bPrintErrors )
+ printf( "Can not find: %s.\n", pPathAndExt );
+ return sRet;
+ }
+ else
+ {
+ sRet.append( FindFileData.cFileName );
+ FindClose(hFind);
+ return sRet;
+ }
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::GetStringUntilNextSpace
+// Function returns string from begin of given string until next space,
+// characters until next space are removed from sInput string.
+// -----------------------------------------------------------------------------
+string CATBase::GetStringUntilNextSpace( string& sInput, bool bEraseFromInput )
+{
+ LOG_LOW_FUNC_ENTRY("CATBase::GetStringUntilNextSpace");
+ string sTemp( sInput );
+ size_t iSize = sTemp.find_first_of(' ');
+ if( iSize != string::npos )
+ {
+ sTemp.resize( iSize );
+ if( bEraseFromInput )
+ sInput.erase( 0, (iSize+1) );
+ }
+ else
+ {
+ if ( bEraseFromInput )
+ sInput.clear();
+ }
+ return sTemp;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::ChangeSlashToBackSlash
+// Function changes all BackSlash characters to Slash character from
+// given string.
+// -----------------------------------------------------------------------------
+string CATBase::ChangeSlashToBackSlash( string sInput )
+{
+ LOG_LOW_FUNC_ENTRY("CATBase::ChangeSlashToBackSlash");
+ for( unsigned int i = 0 ; i < sInput.length() ; i++ )
+ {
+ if( sInput[i] == '/' )
+ {
+ sInput[i] = '\\';
+ }
+ }
+ return sInput;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::FileExists
+// Check if given file exists.
+// -----------------------------------------------------------------------------
+bool CATBase::FileExists( const char * pFilename )
+{
+ LOG_FUNC_ENTRY("CATBase::FileExists");
+ DWORD dwRet = GetFileAttributes( pFilename );
+ if( dwRet == INVALID_FILE_ATTRIBUTES )
+ {
+ return false;
+ }
+ else
+ {
+ //Is file directory?
+ if( dwRet & FILE_ATTRIBUTE_DIRECTORY )
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool CATBase::IsFileReadOnly( const char* pFilename )
+{
+ LOG_FUNC_ENTRY("CATBase::IsFileReadOnly");
+ DWORD dwRet = GetFileAttributes( pFilename );
+ if( dwRet == INVALID_FILE_ATTRIBUTES )
+ return false;
+ if( dwRet & FILE_ATTRIBUTE_READONLY )
+ return true;
+ return false;
+}
+
+bool CATBase::SetFileReadOnly( const char* pFileName )
+{
+ LOG_FUNC_ENTRY("CATBase::SetFileReadOnly");
+ DWORD dw = GetFileAttributes( pFileName );
+ if( dw == INVALID_FILE_ATTRIBUTES )
+ return false;
+ if( dw & FILE_ATTRIBUTE_READONLY )
+ return true;
+ dw = dw | FILE_ATTRIBUTE_READONLY ;
+ if ( SetFileAttributes( pFileName, dw ) )
+ return true;
+ return false;
+}
+bool CATBase::SetFileWritable( const char* pFileName )
+{
+ LOG_FUNC_ENTRY("CATBase::SetFileWritable");
+ DWORD dw = GetFileAttributes( pFileName );
+ if( dw == INVALID_FILE_ATTRIBUTES )
+ return false;
+ if( ! dw & FILE_ATTRIBUTE_READONLY )
+ return true;
+ dw = dw ^ FILE_ATTRIBUTE_READONLY ;
+ if ( SetFileAttributes( pFileName, dw ) )
+ return true;
+ return false;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::FileCopyToPath
+// Copies file to given path
+// -----------------------------------------------------------------------------
+bool CATBase::FileCopyToPath(const string& sFile, const string& sToPath)
+{
+ LOG_FUNC_ENTRY("CATBase::FileCopyToPath");
+ // Display message
+ cout << AT_MSG << "Copy " << sFile << AT_FILE_TO << sToPath << endl;
+ if ( sFile.empty() || sToPath.empty() )
+ {
+ LOG_FUNC_EXIT("CATBase::FileCopyToPath Error, empty parameter");
+ return false;
+ }
+ // Copy using windows api (seems not to work when relavite path ..
+ /*
+ // Full path where to copy
+ string sDestination = sToPath;
+ // Append '\' to string if not exists
+ if ( sDestination.length() > 1 )
+ {
+ const char cLastChar = sDestination[ sDestination.length() -1 ];
+ if ( cLastChar != DASH )
+ sDestination.append("\\");
+ }
+ int iRet = 0;
+ iRet = CopyFile( sFile.c_str(), sDestination.c_str(), false );
+ if ( iRet != 0 )
+ {
+ return false;
+ }
+ */
+ string sCommand;
+ sCommand.append( "copy /Y \"");
+ sCommand.append( sFile );
+ sCommand.append( "\" \"" );
+ sCommand.append( sToPath );
+ sCommand.append( "\" > nul 2>&1" );
+ LOG_STRING( sCommand );
+ int iRet = 0;
+ iRet = (int)system( sCommand.c_str() );
+ if ( iRet != 0 )
+ return false;
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::FileMoveToPath
+// Copies file to given path
+// -----------------------------------------------------------------------------
+bool CATBase::FileMoveToPath(const string& sFile, const string& sToPath)
+{
+ LOG_FUNC_ENTRY("CATBase::FileMoveToPath");
+ // Display message
+ cout << AT_MSG << "Move " << sFile << AT_FILE_TO << sToPath << endl;
+ if ( sFile.empty() || sToPath.empty() )
+ {
+ LOG_FUNC_EXIT("CATBase::FileMoveToPath Error, empty parameter");
+ return false;
+ }
+ // Move (again windows api function does not support relative path .. in it
+ /*
+ // Get filename from sFile
+ string sFileName = GetPathOrFileName( true, sFile );
+ // Full path where to copy
+ string sDestination = sToPath;
+ // Append '\' to string if not exists
+ if ( sDestination.length() > 1 )
+ {
+ const char cLastChar = sDestination[ sDestination.length() -1 ];
+ if ( cLastChar != DASH )
+ sDestination.append("\\");
+ }
+ int iRet = 0;
+ iRet = MoveFile( sFile.c_str(), sDestination.c_str());
+ if ( iRet != 0 )
+ {
+ return false;
+ }
+ */
+ string sCommand;
+ sCommand.append( "move /Y \"");
+ sCommand.append( sFile );
+ sCommand.append( "\" \"" );
+ sCommand.append( sToPath );
+ sCommand.append( "\" > nul 2>&1" );
+ LOG_STRING( sCommand );
+ int iRet = 0;
+ iRet = (int)system( sCommand.c_str() );
+ if ( iRet != 0 )
+ return false;
+ return true;
+}
+// -----------------------------------------------------------------------------
+// CATBase::CreateTempPath
+// Creates temporary directory path for given mmp file
+// -----------------------------------------------------------------------------
+string CATBase::CreateTempPath(const string& sMmpFileWithPath)
+{
+ LOG_FUNC_ENTRY("CATBase::CreateTempPath");
+ string sTempPath = GetPathOrFileName( false, sMmpFileWithPath );
+ sTempPath.append( AT_TEMP_DIR );
+ sTempPath.append( "\\" );
+ return sTempPath;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::RemovePathAndExt
+// Removes extension from file name and returns file name without extension.
+// -----------------------------------------------------------------------------
+string CATBase::RemovePathAndExt( string sFileName, bool bReverseFindExt)
+{
+ LOG_LOW_FUNC_ENTRY("CATBase::RemovePathAndExt");
+ string sRet;
+ sFileName = GetPathOrFileName( true, sFileName );
+ if ( bReverseFindExt )
+ {
+ // Remove extension from reverse
+ size_t iPos = sFileName.find_last_of('.');
+ if( iPos != string::npos )
+ {
+ sFileName.resize( sFileName.find_last_of('.') );
+ sRet = sFileName;
+ }
+ }
+ else
+ {
+ // Remove extension finding first .
+ size_t iPos = sFileName.find_first_of('.');
+ if( iPos != string::npos )
+ {
+ sFileName.resize( sFileName.find_first_of('.') );
+ sRet = sFileName;
+ }
+ }
+ return sRet;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::IsTargetTypeSupported
+// Checks from constant array is this target unsupported
+// -----------------------------------------------------------------------------
+bool CATBase::IsTargetTypeSupported(string sTargetType)
+{
+ LOG_FUNC_ENTRY("CATBase::IsTargetTypeSupported");
+ // compare to list
+ int iArraySize = sizeof( UNSUPPORTED_TARGET_TYPES ) / sizeof( string );
+ for ( int i=0 ; i < iArraySize ; i++ )
+ {
+ string sUnsupported = UNSUPPORTED_TARGET_TYPES[i];
+ // lowercase both
+ ChangeToLower(sTargetType);
+ ChangeToLower(sUnsupported);
+ // compare
+ if ( sUnsupported.compare( sTargetType ) == 0 )
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::IsTargetTypeKernelSide
+// Checks from constant array is this target type kernel side
+// -----------------------------------------------------------------------------
+bool CATBase::IsTargetTypeKernelSide(string sTargetType)
+{
+ LOG_FUNC_ENTRY("CATBase::IsTargetTypeKernelSide");
+ // compare to list
+ int iArraySize = sizeof( KERNEL_SIDE_TARGET_TYPES ) / sizeof( string );
+ for ( int i=0 ; i < iArraySize ; i++ )
+ {
+ string sUnsupported = KERNEL_SIDE_TARGET_TYPES[i];
+ // lowercase both
+ ChangeToLower(sTargetType);
+ ChangeToLower(sUnsupported);
+ // compare
+ if ( sUnsupported.compare( sTargetType ) == 0 )
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool CATBase::CheckVariant( const string& sEpocRoot, const string& sVariant )
+{
+ LOG_FUNC_ENTRY("CATBase::CheckVariant");
+ string sFileToCheck;
+ // Add epoc root
+ if( sEpocRoot.size() > 1 )
+ sFileToCheck.append( sEpocRoot );
+ // Add path
+ sFileToCheck.append( VARIANT_DIR ) ;
+ // Add variant
+ sFileToCheck.append( sVariant );
+ // Add extension
+ sFileToCheck.append( VARIANT_FILE_EXTENSION );
+ // check does FileExists
+ return FileExists( sFileToCheck.c_str() );
+}
+bool CATBase::IsDefaultVariant( const string& sEpocRoot )
+{
+ LOG_FUNC_ENTRY("CATBase::IsDefaultVariant");
+ string sFileToCheck;
+ // Add epoc root
+ if( sEpocRoot.size() > 1 )
+ sFileToCheck.append( sEpocRoot );
+ // Add path
+ sFileToCheck.append( VARIANT_DIR ) ;
+ // Add variant
+ sFileToCheck.append( "DEFAULT" );
+ // Add extension
+ sFileToCheck.append( VARIANT_FILE_EXTENSION );
+ // check does FileExists
+ return FileExists( sFileToCheck.c_str() );
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::FileDelete
+// FileDelete
+// -----------------------------------------------------------------------------
+bool CATBase::FileDelete(const string& sFile, bool bPrint )
+{
+ LOG_FUNC_ENTRY("CATBase::FileDelete");
+ // does file even exists
+ if ( !FileExists( sFile.c_str() ) )
+ return false;
+ // delete file
+ int iRet = _unlink( sFile.c_str() );
+ // if print on display error
+ if ( iRet && bPrint )
+ {
+ cout << AT_MSG << "Error, deleting file " << sFile
+ << endl;
+ }
+ // if print on display message
+ else if ( !iRet && bPrint )
+ {
+ cout << AT_MSG << "Delete " << sFile << endl;
+ }
+ // return
+ if ( iRet )
+ return false;
+ return true;
+}
+// -----------------------------------------------------------------------------
+// CATBase::DirDelete
+// Delelete directory
+// -----------------------------------------------------------------------------
+bool CATBase::DirDelete(const string& sDir, bool bPrint )
+{
+ LOG_FUNC_ENTRY("CATBase::DirDelete");
+ if ( sDir.find( AT_TEMP_DIR) == string::npos )
+ return false;
+
+ if ( sDir.length() < 2 )
+ return false;
+
+ string sDir2;
+ if ( sDir.at(1) != ':' )
+ {
+ char cDir[MAX_LINE_LENGTH];
+ GetCurrentDirectory( MAX_LINE_LENGTH , cDir );
+ sDir2.append( cDir );
+ sDir2.append( "\\" );
+ sDir2.append( sDir );
+ }
+ else
+ sDir2.append( sDir );
+
+ // does directory exists
+ DWORD dwRet = GetFileAttributes( sDir2.c_str() );
+ if ( dwRet == INVALID_FILE_ATTRIBUTES )
+ return false;
+ else if ( ! (dwRet & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ return false;
+ }
+ // Delete dir
+ string sCmd( "rmdir /S /Q " );
+ sCmd.append( sDir2 );
+ sCmd.append( " > nul 2>&1" );
+ int iRet = (int)system( sCmd.c_str() );
+ if ( iRet && bPrint)
+ {
+ cout << AT_MSG << "Error, deleting directory " << sDir2 << endl;
+ }
+ else if ( !iRet && bPrint )
+ {
+ cout << AT_MSG << "Delete directory " << sDir2 << endl;
+ }
+ if ( iRet )
+ return false;
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::DirCreate
+// Create directory
+// -----------------------------------------------------------------------------
+bool CATBase::DirCreate(const string& sDir, bool bPrint )
+{
+ LOG_FUNC_ENTRY("CATBase::DirCreate");
+
+ if ( sDir.length() < 2 )
+ return false;
+
+ string sDir2;
+ if ( sDir.at(1) != ':' )
+ {
+ char cDir[MAX_LINE_LENGTH];
+ GetCurrentDirectory( MAX_LINE_LENGTH , cDir );
+ sDir2.append( cDir );
+ sDir2.append( "\\" );
+ sDir2.append( sDir );
+ }
+ else
+ sDir2.append( sDir );
+
+ // does directory exists
+ DWORD dwRet = GetFileAttributes( sDir2.c_str() );
+ if ( dwRet != INVALID_FILE_ATTRIBUTES )
+ {
+ if( dwRet & FILE_ATTRIBUTE_DIRECTORY )
+ return false;
+ }
+ // Create dir
+ string sCmd( "mkdir " );
+ sCmd.append( sDir2 );
+ sCmd.append( " > nul 2>&1" );
+ int iRet = (int)system( sCmd.c_str() );
+ if ( iRet && bPrint)
+ {
+ cout << AT_MSG << "Error, creating directory " << sDir2 << endl;
+ }
+ else if ( !iRet && bPrint )
+ {
+ cout << AT_MSG << "Directory " << sDir2 << " created" << endl;
+ }
+ if ( iRet )
+ return false;
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::ConvertTCHARtoString
+// Convert TCHAR* to std::string
+// -----------------------------------------------------------------------------
+string CATBase::ConvertTCHARtoString(TCHAR* charArray)
+{
+ LOG_LOW_FUNC_ENTRY("CATBase::ConvertTCHARtoString");
+ // Loop char array
+ stringstream ss;
+ int iIndex = 0;
+ char c = (char) charArray[iIndex];
+ // until null termination
+ while ( c != '\0' )
+ {
+ ss << c;
+ iIndex++;
+ c = (char) charArray[iIndex];
+ }
+ // return string
+ return ss.str();
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::ConvertTCHARtoString
+// Get list of files in directory
+// -----------------------------------------------------------------------------
+vector<string> CATBase::DirList(const string& sDirectory
+ , bool bListDirs, bool bAddPathToFile)
+{
+ LOG_FUNC_ENTRY("CATBase::DirList");
+ // Create string to modify it
+ string sDir = sDirectory;
+ // Add if missing '\' & '*' to the sDirectory
+ if ( sDir.at( sDir.size()-1 ) != '\\' )
+ sDir.append( "\\" );
+ // Path to add to file string if specified
+ string sPath = sDir;
+ // Add * to for windows api to find all files
+ sDir.append( "*" );
+ // convert directory string to LPCSTR
+ LPCSTR dir( sDir.c_str() );
+ // vector to store file list
+ vector<string> vFileList;
+ // Using win32 api to find list of files in directory
+ // file data "container"
+ WIN32_FIND_DATA fileData;
+ // handle to directory
+ HANDLE hFinder = FindFirstFile( dir, &fileData );
+ if ( hFinder == INVALID_HANDLE_VALUE )
+ {
+ // no files found
+ return vFileList;
+ }
+ // loop files add to vector and return
+ while( FindNextFile(hFinder, &fileData ) )
+ {
+ DWORD dw = fileData.dwFileAttributes;
+ // skip if its directory and bListDirs not specified
+ if ( dw & FILE_ATTRIBUTE_DIRECTORY && ! bListDirs)
+ continue;
+ // add files to vector
+ string sFile = ConvertTCHARtoString( fileData.cFileName );
+ // Add given path to file string if specified
+ if ( bAddPathToFile )
+ sFile.insert( 0, sPath );
+ vFileList.push_back( sFile );
+ }
+ // Close file find handler
+ FindClose( hFinder );
+ return vFileList;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::ParseRelativePathToString
+// ParseRelative
+// -----------------------------------------------------------------------------
+void CATBase::ParseRelativePathString(string& sPathString)
+{
+ LOG_LOW_FUNC_ENTRY("CATBase::ParseRelativePathString");
+ string sParsed;
+ // find ..
+ size_t iDots = sPathString.find( ".." );
+ while ( iDots != string::npos )
+ {
+ RemoveRelativePath( sPathString, iDots );
+ iDots = sPathString.find( ".." );
+ }
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::RemoveRelativePath
+// Remove relative path from string (using given index)
+// -----------------------------------------------------------------------------
+void CATBase::RemoveRelativePath(string& sString, size_t iDots)
+{
+ LOG_LOW_FUNC_ENTRY("CATBase::RemoveRelativePath");
+ // Chck if accidentally given wrong parameter
+ if ( iDots == string::npos
+ || iDots < 1 )
+ return;
+ // Parsed string
+ string sParsed;
+ // Find position of last backslash before dots
+ size_t i = sString.rfind("\\", iDots-2 );
+ // Pickup start part (depending is the backslash at last parts first char)
+ if ( sString.at(iDots+2) != '\\' )
+ sParsed = sString.substr( 0, i+1 ) ;
+ else
+ sParsed = sString.substr( 0, i );
+ // Pick up last part
+ sParsed.append( sString.substr( iDots+2, sString.size() ) );
+ sString = sParsed;
+}
+
+// -----------------------------------------------------------------------------
+// Get extension from given string
+// -----------------------------------------------------------------------------
+string CATBase::GetExtension(const string& sString)
+{
+ LOG_LOW_FUNC_ENTRY("CATBase::GetExtension");
+ // find last .
+ size_t iDot = sString.find_last_of( "." );
+ // return string after . if found
+ if ( iDot != string::npos )
+ return sString.substr(iDot+1, sString.length()-(iDot+1) );
+ // otherwise return given string
+ return sString;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::DirectoryExists
+// Check if given directory exists.
+// -----------------------------------------------------------------------------
+bool CATBase::DirectoryExists( const char* pDirname )
+{
+ LOG_FUNC_ENTRY("CATBase::DirectoryExists");
+ size_t iLenght = strlen( pDirname );
+
+ if ( iLenght < 2 )
+ return false;
+
+ string sDir;
+ if ( pDirname[1] != ':' )
+ {
+ char cDir[MAX_LINE_LENGTH];
+ GetCurrentDirectory( MAX_LINE_LENGTH , cDir );
+ sDir.append( cDir );
+ sDir.append( "\\" );
+ sDir.append( pDirname );
+ }
+ else
+ sDir.append( pDirname );
+
+ DWORD dwRet = GetFileAttributes( sDir.c_str() );
+ if( dwRet == INVALID_FILE_ATTRIBUTES )
+ {
+ return false;
+ }
+ else
+ {
+ //Is file directory?
+ if( dwRet & FILE_ATTRIBUTE_DIRECTORY )
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::ConvertUnixPathToWin
+// -----------------------------------------------------------------------------
+void CATBase::ConvertUnixPathToWin( string& sPath )
+{
+ LOG_LOW_FUNC_ENTRY("CATBase::ConvertUnixPathToWin");
+ size_t iSpot = 0;
+ // convert '/' to '\'
+ iSpot = sPath.find( "/" );
+ while( iSpot != string::npos )
+ {
+ sPath.replace(iSpot,1, "\\");
+ iSpot = sPath.find( "/", iSpot+1 );
+ }
+ // convert '\\' to '\'
+ iSpot = sPath.find( "\\\\" );
+ while( iSpot != string::npos )
+ {
+ sPath.replace(iSpot,2,"\\");
+ iSpot = sPath.find( "\\\\" );
+ }
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::RemoveAllAfterDotIfTwoDots
+// Removes all after first '.'
+// if given string contains 2 '.' or more
+// -----------------------------------------------------------------------------
+void CATBase::RemoveAllAfterDotIfTwoDots(string& sModName)
+{
+ LOG_LOW_FUNC_ENTRY("CATBase::RemoveAllAfterDotIfTwoDots");
+ // did we find variable?
+ size_t found;
+ // Find first '.'
+ found = sModName.find(".");
+ if ( found != string::npos )
+ {
+ // Try find second '.'
+ found = sModName.find(".", found+1);
+ if ( found != string::npos )
+ {
+ // Remove all after first '.'
+ sModName = sModName.substr(0, sModName.find(".")+1 );
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+// CATBase::CreateTemporaryCpp
+// -----------------------------------------------------------------------------
+bool CATBase::CreateTemporaryCpp( const string& sId,
+ const string& sPath
+ ,const string& sS60FileName
+ ,int iLogOption
+ ,int iIsDebug
+ ,int iAllocCallStackSize
+ ,int iFreeCallStackSize )
+{
+ LOG_FUNC_ENTRY("CATBase::CreateTemporaryCpp");
+ // Add slash to path if missing
+ string sTempCpp = sPath;
+ if( sTempCpp.at( sTempCpp.length() - 1 ) != '\\' )
+ sTempCpp.append("\\");
+
+ // append temporary cpp name with id in middle
+ sTempCpp.append( AT_TEMP_CPP_LOWER_START );
+ sTempCpp.append( sId );
+ sTempCpp.append( AT_TEMP_CPP_LOWER_END );
+
+ //Open and truncate temporary cpp
+ ofstream out( sTempCpp.c_str() , ios::trunc );
+ if ( ! out.good() )
+ {
+ out.close();
+ return false;
+ }
+ // Headers
+ out << "#include <e32base.h>";
+ // Is debug
+ out << "\nconst TInt ATTempDebug(" << iIsDebug << ");";
+ // Log option
+ out << "\nconst TInt ATTempLogOption(" << iLogOption << ");";
+ // Alloc call stack
+ out << "\nconst TInt ATTempAllocCallStackSize(" << iAllocCallStackSize << ");";
+ // Free call stack
+ out << "\nconst TInt ATTempFreeCallStackSize(" << iFreeCallStackSize << ");";
+ // Log file name
+ out << "\n_LIT( ATTempLogFileName, \"" << sS60FileName << "\" );";
+ // Version number
+ out << "\n_LIT( ATTempVersion, \"" << ATOOL_COMPATIBILITY_STRING << "\" );";
+ // Variable functions use enumeration values that are defined in memoryhook (customuser.h)
+ // We use constants here so that we don't need to include the header file, wich
+ // might cause problems.
+/* Enumeration copied to comment for notes
+ enum TATOptions
+ {
+ ELogFileName = 1,
+ EVersion = 2 ,
+ ELogOption = 3,
+ EDebug = 4,
+ EAllocCallStackSize = 5,
+ EFreeCallStackSize = 6
+ };
+*/
+ out << "\nTInt GetInt( const TUint8 aType )";
+ out << "\n{";
+ out << "\nswitch( aType )";
+ out << "\n{";
+ out << "\ncase 4: return ATTempDebug; ";
+ out << "\ncase 3: return ATTempLogOption;";
+ out << "\ncase 5: return ATTempAllocCallStackSize;";
+ out << "\ncase 6: return ATTempFreeCallStackSize;";
+ out << "\ndefault: return KErrArgument;";
+ out << "\n}";
+ out << "\n}";
+ out << "\nTPtrC GetString( const TUint8 aType )";
+ out << "\n{";
+ out << "\nswitch( aType )";
+ out << "\n{";
+ out << "\ncase 1: return ATTempLogFileName();";
+ out << "\ncase 2: return ATTempVersion();";
+ out << "\ndefault: return KNullDesC();";
+ out << "\n}";
+ out << "\n}";
+
+ /** Todo: Old way of separate functions, these here for backup support and to ease testing. */
+ /** Unnessesary in the future, so can be removed then (1.8.2). */
+
+ out << "\n_LIT( KFileName, \"";
+ out << sS60FileName;
+ out << "\" );\n";
+
+ // Hardcoded version number for support.
+ out << "\n/* The AnalyzeTool version number used. */";
+ out << "\n_LIT( KAtoolVersion, \"1.7.5;1.9.1\" );\n";
+
+ out << "\nconst TFileName LogFileName()";
+ out << "\n {";
+ out << "\n return TFileName( KFileName() );";
+ out << "\n }";
+
+ out << "\nTUint32 AllocCallStackSize()";
+ out << "\n {";
+ out << "\n return TUint32( ";
+ out << iAllocCallStackSize;
+ out << " );\n";
+ out << "\n }";
+
+ out << "\nTUint32 FreeCallStackSize()";
+ out << "\n {";
+ out << "\n return TUint32( ";
+ out << iFreeCallStackSize;
+ out << " );\n";
+ out << "\n }";
+
+ out << "\nconst TFileName AtoolVersion()";
+ out << "\n {";
+ out << "\n return TFileName( KAtoolVersion() );";
+ out << "\n }";
+
+ out << "\nTUint32 LogOption()";
+ out << "\n {";
+ out << "\n return TUint32( ";
+ out << iLogOption;
+ out << " );";
+ out << "\n }";
+
+ out << "\nTUint32 IsDebug()";
+ out << "\n {";
+ out << "\n return TUint32( ";
+ out << iIsDebug;
+ out << " );";
+ out << "\n }";
+
+ // End of file and close
+ out << "\n\n// End of File\n";
+ out.close();
+ cout << AT_MSG << "Created " << sTempCpp << endl;
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::IsDataFile
+// -----------------------------------------------------------------------------
+bool CATBase::IsDataFile( string sFile )
+{
+ LOG_FUNC_ENTRY("CATBase::IsDataFile");
+ // Check that sFile not empty
+ if ( sFile.empty() || sFile.length() < 1 )
+ return false;
+
+ // Temporary line char array.
+ char cLineFromFile[MAX_LINE_LENGTH];
+ //Open file
+ ifstream in( sFile.c_str() );
+
+ //File open ok?
+ if( !in.good() )
+ return false;
+
+ //Read all lines
+ in.getline( cLineFromFile, MAX_LINE_LENGTH );
+
+ string sLineFromFile( cLineFromFile );
+ in.close();
+ if( sLineFromFile.find( "DATA_FILE_VERSION" ) != string::npos )
+ return true;
+ else
+ return false;
+}
+
+
+// -----------------------------------------------------------------------------
+// CATBase::ParseStringToVector
+// -----------------------------------------------------------------------------
+vector<string> CATBase::ParseStringToVector( const string& sInput, char separator )
+{
+ LOG_LOW_FUNC_ENTRY("CATBase::ParseStringToVector");
+ string sString(sInput);
+ // Elements vector
+ vector<string> vStrings;
+ size_t iPos = sString.find( separator );
+ // If can not find it return vector with just one element
+ if ( iPos == string::npos )
+ {
+ // Don't add empty item into vector.
+ if ( sString.size() > 0 )
+ vStrings.push_back( sString );
+ return vStrings;
+ }
+ // Loop elements
+ while( iPos != string::npos )
+ {
+ string sElement = sString.substr(0, iPos);
+ vStrings.push_back( sElement );
+ sString.erase(0, iPos +1 );
+ iPos = sString.find( separator );
+ }
+ // Add last element if any
+ if ( sString.size() > 0 )
+ vStrings.push_back( sString );
+ // Return elements
+ return vStrings;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::FilterString
+// Filter string out of unwanted characters. The list of allowed
+// characters is defined in CFILTERSTRING.
+// -----------------------------------------------------------------------------
+string CATBase::FilterString( const string& sString )
+{
+ LOG_LOW_FUNC_ENTRY("CATBase::FilterString");
+ string sFiltered;
+ for( size_t i = 0 ; i < sString.length() ; i++ )
+ {
+ const char p = sString.at( i );
+ if ( strchr( CFILTERSTRING, p ) != 0 )
+ sFiltered.push_back( p );
+ }
+ return sFiltered;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::FilterExtraSpaces
+// Replaces multiple continuous spaces with single. Won't leave
+// spaces in start or end of string.
+// -----------------------------------------------------------------------------
+void CATBase::FilterExtraSpaces( string& sString )
+{
+ LOG_LOW_FUNC_ENTRY("CATBase::FilterExtraSpaces");
+ string sFiltered;
+ // Loop thru char array.
+ for( size_t i = 0 ; i < sString.length(); i++ )
+ {
+ // Is char space?
+ if ( sString.at( i ) == ' ' )
+ {
+ // Pick up space if filtered does not contain char as last.
+ if ( sFiltered.rbegin() == sFiltered.rend() )
+ sFiltered.push_back( sString.at( i ) );
+ else if ( * ( sFiltered.rbegin() ) != ' ' )
+ sFiltered.push_back( sString.at( i ) );
+ }
+ else
+ sFiltered.push_back( sString.at( i ) );
+ }
+
+ // Remove first and/or last character if it is space.
+ if ( sFiltered.begin() != sFiltered.end() )
+ {
+ if( * ( sFiltered.begin() ) == ' ' )
+ sFiltered.erase( 0, 1 );
+ }
+ if ( sFiltered.rbegin() != sFiltered.rend() )
+ {
+ if( * ( sFiltered.rbegin() ) == ' ' )
+ sFiltered.resize( sFiltered.length()-1 );
+ }
+ sString = sFiltered;
+}
+
+
+bool CATBase::hexToDec( string& sHex, unsigned int& iDec )
+{
+ LOG_LOW_FUNC_ENTRY("CATBase::hexToDec");
+ istringstream ss( sHex );
+ ss.setf( ios::hex, ios::basefield );
+ if( ( ss >> iDec ) )
+ return true;
+ return false;
+}
+
+bool CATBase::hexToDec( string& sHex, int& iDec )
+{
+ LOG_LOW_FUNC_ENTRY("CATBase::hexToDec");
+ istringstream ss( sHex );
+ ss.setf( ios::hex, ios::basefield );
+ if( ( ss >> iDec ) )
+ return true;
+ return false;
+}
+
+bool CATBase::hexToDec( string& sHex, unsigned long& ulDec )
+{
+ LOG_LOW_FUNC_ENTRY("CATBase::hexToDec");
+ istringstream ss( sHex );
+ ss.setf( ios::hex, ios::basefield );
+ if( ( ss >> ulDec ) )
+ return true;
+ return false;
+}
+
+bool CATBase::hexToDec( string& sHex, unsigned long long& ullDec )
+{
+ LOG_LOW_FUNC_ENTRY("CATBase::hexToDec");
+ istringstream ss( sHex );
+ ss.setf( ios::hex, ios::basefield );
+ if( ( ss >> ullDec ) )
+ return true;
+ return false;
+}
+
+/**
+* Used to create array of integer & hex value pairs.
+*/
+struct CHexMap
+{
+ char chr;
+ int value;
+};
+
+// -----------------------------------------------------------------------------
+// CATBase::_httoi
+// -----------------------------------------------------------------------------
+unsigned long CATBase::_httoi(const char *value)
+{
+ LOG_LOW_FUNC_ENTRY("CATBase::_httoi");
+ unsigned long l;
+ string s( value );
+ if ( CATBase::hexToDec( s, l ) )
+ return l;
+ return 0;
+}
+
+
+// -----------------------------------------------------------------------------
+// CATBase::NumberToHexString(int)
+// -----------------------------------------------------------------------------
+string CATBase::NumberToHexString( unsigned int i )
+{
+ LOG_LOW_FUNC_ENTRY("CATBase::IntToHexString");
+ stringstream ss;
+ ss << "0x" << hex << i;
+ string retval; retval = ss.str().c_str();
+ return retval;
+}
+// -----------------------------------------------------------------------------
+// CATBase::NumberToHexString(long)
+// -----------------------------------------------------------------------------
+string CATBase::NumberToHexString( unsigned long i )
+{
+ LOG_LOW_FUNC_ENTRY("CATBase::IntToHexString");
+ stringstream ss;
+ ss << "0x" << hex << i;
+ string retval; retval = ss.str().c_str();
+ return retval;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::IsHexCharacter
+// -----------------------------------------------------------------------------
+bool CATBase::IsHexCharacter(const TCHAR *value)
+{
+ LOG_LOW_FUNC_ENTRY("CATBase::IsHexCharacter");
+ const int HexMapL = 22;
+ CHexMap HexMap[HexMapL] =
+ {
+ {'0', 0}, {'1', 1},
+ {'2', 2}, {'3', 3},
+ {'4', 4}, {'5', 5},
+ {'6', 6}, {'7', 7},
+ {'8', 8}, {'9', 9},
+ {'A', 10}, {'B', 11},
+ {'C', 12}, {'D', 13},
+ {'E', 14}, {'F', 15},
+ {'a', 10}, {'b', 11},
+ {'c', 12}, {'d', 13},
+ {'e', 14}, {'f', 15}
+ };
+ bool found = false;
+ for (int i = 0; i < HexMapL; i++)
+ {
+ if(HexMap[i].chr == *value)
+ {
+ found = true;
+ break;
+ }
+ }
+ return found;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::IsAscii(const char*,const unsigned int)
+// -----------------------------------------------------------------------------
+bool CATBase::IsAscii( const char* pInput, const unsigned int iLength )
+{
+ LOG_LOW_FUNC_ENTRY("CATBase::IsAscii");
+ bool bRet = true;
+ const char* pPoint = pInput;
+ for( unsigned int i = 0 ; i < iLength ; i++)
+ {
+ if( !__isascii(*pPoint) )
+ {
+ bRet = false;
+ break;
+ }
+ pPoint++;
+ }
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+// CATBase::GetEpocRoot( string& sEpocRoot )
+// -----------------------------------------------------------------------------
+bool CATBase::GetEpocRoot( string& sEpocRoot )
+{
+ LOG_FUNC_ENTRY( "CATBase::GetEpocRoot" );
+ bool bRet = true;
+ //Find EPOCROOT from environment variable
+ char* pEpocRoot = getenv ("EPOCROOT");
+ if( pEpocRoot == NULL )
+ {
+ const char pDevicesPath[] = "C:\\Program Files\\Common Files\\Symbian\\devices.xml";
+ CATParseXML parser;
+ //Find EPOCROOT from devices
+ sEpocRoot = parser.GetEpocRootPathFromXML(pDevicesPath);
+ if( sEpocRoot.empty() )
+ {
+ printf("EPOCROOT not set to environment variables.\n");
+ bRet = false;
+ }
+ }
+ else
+ {
+ sEpocRoot.append( pEpocRoot );
+ LOG_STRING( "EpocRoot :" << sEpocRoot );
+ }
+ //Remove trailing slash
+ if ( sEpocRoot.size() > 1 && sEpocRoot[ sEpocRoot.length()-1 ] == '\\' )
+ sEpocRoot.resize( sEpocRoot.length()-1 );
+ return bRet;
+}
+//End of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/CATDatParser.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,1542 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Class responsible to parse data files
+*
+*/
+
+
+#include "../inc/CATDatParser.h"
+#include "../inc/CATProject.h"
+#include "../inc/CATModule2.h"
+#include "../inc/CATMemoryAddress.h"
+#include "../inc/catromsymbol.h"
+
+// -----------------------------------------------------------------------------
+// CATDatParser::CATDatParser
+// Constructor only for testing!
+// (No module vector defined so no locating codelines / call stacks)
+// -----------------------------------------------------------------------------
+CATDatParser::CATDatParser()
+{
+ LOG_FUNC_ENTRY("CATDatParser::CATDatParser");
+ Construct();
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::CATDatParser
+// Constructor
+// -----------------------------------------------------------------------------
+CATDatParser::CATDatParser(vector<CATModule2*>* pModules )
+{
+ LOG_FUNC_ENTRY("CATDatParser::CATDatParser");
+ Construct();
+ m_pModules = pModules;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::Construct
+// "Real" constructor
+// -----------------------------------------------------------------------------
+void CATDatParser::Construct()
+{
+ LOG_FUNC_ENTRY("CATDatParser::Construct");
+
+ m_iDataVersion = 1; // Default version of data.
+ m_bDllLoadFound = false;
+ m_bProcessStartFound = false;
+ m_bSubtestOnGoing = false;
+
+ m_DataSaver.InitXML();
+
+ m_eBuildType = -2;
+ m_eProcess_state = not_started;
+ m_eProjectBuildType = -1;
+
+ m_iCurrentProcessId = 0;
+ m_iLeakNumber = 0;
+ m_iLogLevel = 3;
+ m_iOffSet = 0;
+
+ m_iPinPointedLeaks = 0;
+ m_iPinPointedSubTestLeaks = 0;
+ m_iSubtestStartHandleCount = 0;
+ m_iSuccesfullRuns = 0;
+ m_iTotalNumberOfLeaks = 0;
+ m_iTotalRuns = 0;
+
+ m_pRomSymbol = 0;
+ m_pModules = 0;
+
+ m_sCurrentProcessName = "";
+ m_sInputFile = "";
+ m_sInputFileTemp = "";
+ m_sOutputFile = "";
+ m_sProjectPlatform = "";
+ m_vRomSymbolFiles.clear();
+ m_vDllLoadModList.clear();
+ m_vDllLoadModListSubTest.clear();
+ m_vHandleLeaks.clear();
+ m_vMemoryAddress.clear();
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::~CATDatParser
+// Destructor
+// -----------------------------------------------------------------------------
+CATDatParser::~CATDatParser()
+{
+ LOG_FUNC_ENTRY("CATDatParser::~CATDatParser");
+
+ if ( m_In.is_open() )
+ m_In.close();
+ // Delete temporary input file if any
+ if ( !m_sInputFileTemp.empty() )
+ {
+ if ( FileExists( m_sInputFileTemp.c_str() ) )
+ FileDelete( m_sInputFileTemp, false );
+ }
+ // Clean memory addresses if any
+ CleanMemoryAddresses();
+ // Delete rom symbol.
+ if ( m_pRomSymbol )
+ {
+ delete m_pRomSymbol;
+ m_pRomSymbol = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::Analyze
+// Analyze given data file
+// -----------------------------------------------------------------------------
+int CATDatParser::Analyze()
+{
+ LOG_FUNC_ENTRY("CATDatParser::Analyze");
+ // Return if input file not set
+ if ( m_sInputFile.empty() )
+ return AT_RETURN_CODE::INVALID_DATA_FILE;
+ // If open close first
+ if ( m_In.is_open() )
+ m_In.close();
+ // Open file
+ m_In.open( m_sInputFile.c_str() );
+ if ( ! m_In.good() )
+ return AT_RETURN_CODE::INVALID_DATA_FILE;
+ try {
+ // If rom symbol file specified.
+ if ( ! m_vRomSymbolFiles.empty() )
+ {
+ // Create new rom symbol file "parser".
+ m_pRomSymbol = new CATRomSymbol();
+ m_pRomSymbol->m_bShowProgressMessages = true;
+ // Set symbol files.
+ if ( ! m_pRomSymbol->SetSymbols( m_vRomSymbolFiles ) )
+ {
+ cout << AT_MSG << "Rom/Rofs symbols error: " << m_pRomSymbol->GetError() << endl;
+ // If file open fails we delete it and will not use it.
+ delete m_pRomSymbol;
+ m_pRomSymbol = NULL;
+ cout << AT_MSG << "Analyze aborted." << endl;
+ return AT_RETURN_CODE::SYMBOL_FILE_ERROR;
+ }
+ }
+ // Return code
+ int iRet = 0;
+ // Clear variables
+ ClearParsingVariables();
+ // If output defined disable printing
+ if ( ! m_sOutputFile.empty() )
+ m_DataSaver.SetPrintFlag( false );
+ // Header
+ Header();
+ // Parsing
+ iRet = Parse();
+ // Footer
+ if ( iRet == AT_RETURN_CODE::OK )
+ Footer();
+ // If output defined save xml
+ if ( ! m_sOutputFile.empty() )
+ m_DataSaver.SaveLinesToFile( m_sOutputFile.c_str(), XML_DATA );
+ // Return
+ return iRet;
+ } catch ( int i )
+ {
+ cout << AT_MSG << "Error, Analyze failed. : " << i << endl;
+ return AT_RETURN_CODE::UNHANDLED_EXCEPTION;
+ }
+}
+// -----------------------------------------------------------------------------
+// CATDatParser::Header
+// Print header of report
+// -----------------------------------------------------------------------------
+void CATDatParser::Header()
+{
+ LOG_FUNC_ENTRY("CATDatParser::Header");
+ // Analyze report header
+ m_DataSaver.AddString( "Atool.exe v." );
+ m_DataSaver.AddString( ATOOL_VERSION );
+ m_DataSaver.AddString( "\n" );
+ m_DataSaver.AddString( "Analyzing memory leaks..." );
+ m_DataSaver.AddLineToLast();
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::Footer
+// Print footer of report
+// -----------------------------------------------------------------------------
+void CATDatParser::Footer()
+{
+ LOG_FUNC_ENTRY("CATDatParser::Footer");
+ m_DataSaver.AddString( "\nTotal Runs: " );
+ m_DataSaver.AddInteger( m_iTotalRuns );
+ m_DataSaver.AddLineToLast();
+
+ int iFailedRuns = m_iTotalRuns - m_iSuccesfullRuns;
+ m_DataSaver.AddString( "Failed Runs: " );
+ m_DataSaver.AddInteger( iFailedRuns );
+ m_DataSaver.AddLineToLast();
+
+ char cTemp[128];
+ string sResult( itoa( m_iTotalRuns, cTemp, 10 ) );
+ sResult.append( ";" );
+ sResult.append( itoa( iFailedRuns, cTemp, 10 ) );
+ sResult.append( ";" );
+
+ m_DataSaver.SaveXML( sResult, RESULT );
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::ClearParsingVariables
+// Clear/Reset all member variables related to parsing data file
+// -----------------------------------------------------------------------------
+void CATDatParser::ClearParsingVariables()
+{
+ LOG_FUNC_ENTRY("CATDatParser::ClearParsingVariables");
+ // Clear variables related to analyze
+ m_eProcess_state = not_started;
+ m_bProcessStartFound = false;
+ m_bDllLoadFound = false;
+ m_iTotalNumberOfLeaks = 0;
+ m_iPinPointedLeaks = 0;
+ m_iLeakNumber = 0;
+ m_iTotalRuns = 0;
+ m_iSuccesfullRuns = 0;
+ m_bSubtestOnGoing = false;
+ m_iSubtestStartHandleCount = 0;
+ CleanMemoryAddresses();
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::Parse
+// Parses data file. Note! header and footer of the report are done in
+// separate functions.
+// -----------------------------------------------------------------------------
+int CATDatParser::Parse()
+{
+ LOG_FUNC_ENTRY("CATDatParser::Parse");
+ // Read all lines
+ char cLine[MAX_LINE_LENGTH];
+ do
+ {
+ string sLine;
+ try {
+ m_In.getline( cLine, MAX_LINE_LENGTH );
+ sLine = cLine ;
+ } catch(...)
+ {
+ LOG_STRING( AT_MSG << "Unexpected error, reading data file." );
+ continue;
+ }
+ if( sLine.find( LABEL_DATA_FILE_VERSION ) != string::npos )
+ {
+ // Check data file version
+ if( sLine.find( AT_DATA_FILE_VERSION ) == string::npos )
+ {
+ return AT_RETURN_CODE::WRONG_DATA_FILE_VERSION;
+ }
+ }
+ else if( sLine.find( LABEL_PROCESS_START ) != string::npos )
+ {
+ if ( ! ParseProcessStart( sLine ) )
+ return AT_RETURN_CODE::ANALYZE_ERROR;
+ }
+ else if( sLine.find( LABEL_DLL_LOAD ) != string::npos )
+ {
+ if ( ! ParseDllLoad( sLine ) )
+ return AT_RETURN_CODE::ANALYZE_ERROR;
+ }
+ else if( sLine.find( LABEL_DLL_UNLOAD ) != string::npos )
+ {
+ if ( ! ParseDllUnload( sLine ) )
+ return AT_RETURN_CODE::ANALYZE_ERROR;
+ }
+ else if( sLine.find( LABEL_MEM_LEAK ) != string::npos)
+ {
+ if ( ! ParseMemLeak( sLine ) )
+ return AT_RETURN_CODE::ANALYZE_ERROR;
+ }
+ else if( sLine.find( LABEL_PROCESS_END ) != string::npos )
+ {
+ if ( ! ParseProcessEnd( sLine ) )
+ return AT_RETURN_CODE::ANALYZE_ERROR;
+ }
+ else if( sLine.find( LABEL_ERROR_OCCURED ) != string::npos )
+ {
+ if ( ! ParseErrorOccured( sLine ) )
+ return AT_RETURN_CODE::ANALYZE_ERROR;
+ }
+ else if( sLine.find( LABEL_HANDLE_LEAK ) != string::npos )
+ {
+ if ( ! ParseHandleLeak( sLine ) )
+ return AT_RETURN_CODE::ANALYZE_ERROR;
+ }
+ else if( sLine.find( LABEL_TEST_START ) != string::npos )
+ {
+ if ( ! ParseTestStart( sLine ) )
+ return AT_RETURN_CODE::ANALYZE_ERROR;
+ }
+ else if( sLine.find( LABEL_TEST_END ) != string::npos )
+ {
+ if ( ! ParseTestEnd( sLine ) )
+ return AT_RETURN_CODE::ANALYZE_ERROR;
+ }
+ else if( sLine.find( LABEL_LOGGING_CANCELLED ) != string::npos )
+ {
+ if ( ! ParseLoggingCancelled( sLine ) )
+ return AT_RETURN_CODE::ANALYZE_ERROR;
+ }
+ }
+ while( m_In.good() );
+ // Message of failed run if process start was last line in data.
+ if ( m_eProcess_state == ongoing )
+ {
+ m_DataSaver.AddString( "Test run failed.\n" );
+ m_DataSaver.AddLineToLast();
+ }
+ return AT_RETURN_CODE::OK;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::ParseProcessStart
+// -----------------------------------------------------------------------------
+bool CATDatParser::ParseProcessStart( string& sLine)
+{
+ LOG_FUNC_ENTRY("CATDatParser::ParseProcessStart");
+ if ( m_eProcess_state == ongoing )
+ {
+ m_DataSaver.AddString( "Test run failed.\n" );
+ m_DataSaver.AddLineToLast();
+ }
+ m_eProcess_state = ongoing;
+ m_bProcessStartFound = true;
+
+ // Clear handle leaks
+ m_vHandleLeaks.clear();
+ // Increment runs
+ m_iTotalRuns++;
+ // Clean leak count
+ m_iTotalNumberOfLeaks = 0;
+ // Clean pin pointed leaks count.
+ m_iPinPointedLeaks = 0;
+ // Clean leak number
+ m_iLeakNumber = 0;
+
+ // Clean loaded mods
+ m_vDllLoadModList.clear();
+ m_vDllLoadModListSubTest.clear();
+
+ // Skip text PROCESS_START
+ GetStringUntilNextSpace( sLine );
+ // Get process name
+ m_sCurrentProcessName = GetStringUntilNextSpace( sLine );
+ // Get Pid
+ string sPid = GetStringUntilNextSpace( sLine );
+ m_iCurrentProcessId = _httoi( sPid.c_str() );
+
+ // Header for process tart
+ m_DataSaver.AddString( "\n--------------------------------\n" );
+ m_DataSaver.AddString( "Test Run start (" );
+ m_DataSaver.AddString( m_sCurrentProcessName.c_str() );
+ m_DataSaver.AddString( "): " );
+
+ // Get start time
+ string sTime = GetStringUntilNextSpace( sLine );
+ sTime = ConvertTimeToLocalTime( sTime );
+ m_DataSaver.AddString( sTime.c_str() );
+
+ // Create data for xml
+ string sData( sTime );
+ sData.append( ";" );
+
+ // Build mode UDEB/UREL.
+ string sBuildType = GetStringUntilNextSpace( sLine );
+
+ m_DataSaver.AddString( " Build target: " );
+ if( sBuildType.compare( "0" ) == 0 )
+ {
+ m_eBuildType = CATProject::UREL;
+ }
+ else if( sBuildType.compare( "1" ) == 0 )
+ {
+ m_eBuildType = CATProject::UDEB;
+ }
+ m_DataSaver.AddString( CATProject::GetBuildTypeString( m_eBuildType ).c_str() );
+
+ // Version.
+ string sVersion = GetStringUntilNextSpace( sLine );
+ unsigned int iVer = 0;
+ if ( hexToDec( sVersion, iVer ) && iVer != 0 )
+ m_iDataVersion = iVer;
+
+ // End line in data.
+ m_DataSaver.AddLineToLast();
+
+ // xml
+ sData.append( CATProject::GetBuildTypeString( m_eBuildType ) );
+ sData.append( ";" );
+ sData.append( m_sCurrentProcessName );
+ m_DataSaver.SaveXML( sData, RUN );
+
+ // If projects platform defined check that it is same in data. (future feature).
+ if ( ! m_sProjectPlatform.empty() )
+ {
+ // If platform info is added to data file do check here.
+ }
+ // If projects build type defined check that it is same in data.
+ if ( m_eProjectBuildType != -1 )
+ {
+ if ( m_eBuildType != m_eProjectBuildType )
+ {
+ string sError(AT_MSG);
+ sError.append( "Error, analyzed data has build type of " );
+ sError.append( CATProject::GetBuildTypeString( m_eBuildType ) );
+ sError.append( " and project has build type " );
+ sError.append( CATProject::GetBuildTypeString( m_eProjectBuildType ) );
+ sError.append( ". Pinpointed code lines are not valid." );
+ m_DataSaver.AddString( sError.c_str(), false );
+ m_DataSaver.AddLineToLast();
+ }
+ }
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::ParseProcessEnd
+// -----------------------------------------------------------------------------
+bool CATDatParser::ParseProcessEnd( string& sLine )
+{
+ LOG_FUNC_ENTRY("CATDatParser::ParseProcessEnd");
+ GetStringUntilNextSpace( sLine );
+
+ // Get process id
+ string sProcessID = GetStringUntilNextSpace( sLine );
+ unsigned long iProcessID = _httoi( sProcessID.c_str() );
+
+ // Get time
+ string sTime = GetStringUntilNextSpace( sLine );
+
+ // Convert leak time
+ sTime = ConvertTimeToLocalTime( sTime );
+
+ // Process started?
+ if( iProcessID == m_iCurrentProcessId )
+ {
+ m_iSuccesfullRuns++;
+ m_DataSaver.AddLineToLast();
+ m_DataSaver.AddString( "Test Run end (" );
+ m_DataSaver.AddString( m_sCurrentProcessName.c_str() );
+ m_DataSaver.AddString( "): " );
+ m_DataSaver.AddString( sTime.c_str() );
+ m_DataSaver.AddLineToLast();
+ m_DataSaver.AddString( "Build target: " );
+ m_DataSaver.AddString( CATProject::GetBuildTypeString( m_eBuildType ).c_str() );
+ m_DataSaver.AddLineToLast();
+
+ m_eProcess_state = stopped;
+ // Number of leaks
+ if ( m_iLogLevel == 1 || m_iLogLevel == 2 )
+ {
+ if ( m_iPinPointedLeaks > 0 )
+ {
+ m_DataSaver.AddInteger( m_iPinPointedLeaks );
+ m_DataSaver.AddString( " number of pinpointed memory leak(s)." );
+ m_DataSaver.AddLineToLast();
+ }
+ m_DataSaver.AddInteger( m_iLeakNumber );
+ m_DataSaver.AddString( " total number of memory leak(s)." );
+ m_DataSaver.AddLineToLast();
+ }
+ else
+ {
+ m_DataSaver.AddInteger( m_iTotalNumberOfLeaks );
+ m_DataSaver.AddString( " memory leak(s) found." );
+ m_DataSaver.AddLineToLast();
+ }
+
+ // xml
+ char cTemp[128];
+ m_DataSaver.SaveXML( itoa( m_iTotalNumberOfLeaks, cTemp, 10 ) , MEM_LEAKS );
+
+ // Print all modules which have leaks
+ for( size_t i = 0 ; i < m_vDllLoadModList.size() ; i++ )
+ {
+ if( m_vDllLoadModList.at(i).iLeaks > 0 )
+ {
+ m_DataSaver.AddInteger( m_vDllLoadModList.at(i).iLeaks );
+ m_DataSaver.AddString( " memory leak(s) in module: " );
+ m_DataSaver.AddString( m_vDllLoadModList.at(i).sModuleName.c_str() );
+ m_DataSaver.AddLineToLast();
+
+ // xml
+ string sModuleNameAndLeaks( m_vDllLoadModList[i].sModuleName );
+ sModuleNameAndLeaks.append(";");
+ sModuleNameAndLeaks.append( itoa( m_vDllLoadModList[i].iLeaks, cTemp, 10 ) );
+ m_DataSaver.SaveXML( sModuleNameAndLeaks , MEM_LEAK_MODULE );
+ }
+ }
+
+ if ( m_vHandleLeaks.size() > 0 )
+ {
+ // We have handle leaks
+ bool bHandLeaksFound = false;
+ int iTotalNrOfLeaks = 0;
+ // Print handle leaks
+ for( size_t i = 0 ; i < m_vHandleLeaks.size() ; i++ )
+ {
+ string sTempHandleLeak( m_vHandleLeaks[i] );
+ // Name.
+ string sHandleLeakModule( GetStringUntilNextSpace( sTempHandleLeak ) );
+ // Count.
+ string sNrOfLeaks( GetStringUntilNextSpace(sTempHandleLeak) );
+ unsigned long iNrOfLeaks = _httoi( sNrOfLeaks.c_str() );
+ iTotalNrOfLeaks += iNrOfLeaks;
+ if( iNrOfLeaks )
+ {
+ if( !bHandLeaksFound )
+ {
+ m_DataSaver.SaveXML( sNrOfLeaks , HANDLE_LEAKS );
+ }
+ bHandLeaksFound = true;
+ m_DataSaver.AddInteger( iNrOfLeaks );
+ // Just print out how many leaks found.
+ // Because its always unknown.
+ m_DataSaver.AddString( " handle leak(s) found." );
+ m_DataSaver.AddLineToLast();
+
+ // xml
+ string sXMLInfo( sHandleLeakModule );
+ sXMLInfo.append( ";" ); sXMLInfo.append( sNrOfLeaks );
+ m_DataSaver.SaveXML( sXMLInfo , HANDLE_LEAK_MODULE );
+ }
+ }
+ // Update number if handle leaks
+ m_DataSaver.SaveXML( itoa( iTotalNrOfLeaks, cTemp, 10 ) , HANDLE_LEAKS );
+ if( !bHandLeaksFound )
+ {
+ //m_DataSaver.AddLineToLast();
+ m_DataSaver.AddString( TEXT_NO_HANDLE_LEAKS );
+ m_DataSaver.AddLineToLast();
+ }
+ }
+ else
+ {
+ // No handle leaks
+ m_DataSaver.AddLineToLast();
+ m_DataSaver.AddString( TEXT_NO_HANDLE_LEAKS );
+ m_DataSaver.AddLineToLast();
+ }
+
+ // Process end to xml
+ m_DataSaver.SaveXML( sTime, RUN_END );
+ // Reset current process
+ m_iCurrentProcessId = 0;
+ }
+
+ // If no dll load or process start found
+ if ( ! m_bProcessStartFound || !m_bDllLoadFound )
+ {
+ m_DataSaver.AddLineToLast();
+ m_DataSaver.AddString( AT_ANALYZE_INSUFFICIENT_LOGGING_DATA );
+ m_DataSaver.AddLineToLast();
+ }
+
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::ParseDllLoad
+// -----------------------------------------------------------------------------
+bool CATDatParser::ParseDllLoad( string& sLine )
+{
+ LOG_FUNC_ENTRY("CATDatParser::ParseDllLoad");
+ //DLL_LOAD <DLL name> <Time stamp> <Memory start address> <Memory end address>
+ m_bDllLoadFound = true;
+ DLL_LOAD_INFO structDllInfo;
+ structDllInfo.iStartAddress = 0;
+ structDllInfo.iEndAddress = 0;
+ structDllInfo.iLeaks = 0;
+
+ // Skip "DLL_LOAD "
+ GetStringUntilNextSpace( sLine );
+
+ // Get module name
+ structDllInfo.sModuleName = GetStringUntilNextSpace( sLine );
+ ChangeToLower( structDllInfo.sModuleName );
+
+ // Create module from this if project platform emulator
+ if ( _stricmp( "winscw", m_sProjectPlatform.c_str() ) == 0 )
+ CreateWinscwModule( structDllInfo.sModuleName );
+
+ if ( m_iDataVersion >= AT_DLL_TIMESTAMP_DATA_VERSION )
+ {
+ // Pickup module loading time.
+ string sLoadTime = GetStringUntilNextSpace( sLine );
+ unsigned long long ull;
+ if ( hexToDec( sLoadTime, ull ) )
+ structDllInfo.iLoadTime = ull;
+ }
+
+ // Get dll start memory string address from line
+ // Convert string address to real memory address
+ structDllInfo.iStartAddress =
+ _httoi( GetStringUntilNextSpace( sLine ).c_str() );
+
+ // Get dll end memory string address from line
+ // Convert string address to real memory address
+ structDllInfo.iEndAddress =
+ _httoi(
+ GetStringUntilNextSpace( sLine ).c_str() );
+
+ // Is module already loaded, if not add it to list.
+ bool bFound = false;
+ for( vector<DLL_LOAD_INFO>::iterator it = m_vDllLoadModList.begin();
+ it != m_vDllLoadModList.end() ; it++ )
+ {
+ if( (*it).sModuleName.compare( structDllInfo.sModuleName ) == 0 )
+ {
+ bFound = true;
+ break;
+ }
+ }
+ if( ! bFound )
+ m_vDllLoadModList.push_back( structDllInfo );
+
+ // Sub test module list.
+ bFound = false;
+ for( vector<DLL_LOAD_INFO>::iterator it = m_vDllLoadModListSubTest.begin();
+ it != m_vDllLoadModListSubTest.end() ; it++ )
+ {
+ if( (*it).sModuleName.compare( structDllInfo.sModuleName ) == 0 )
+ {
+ bFound = true;
+ break;
+ }
+ }
+ if( ! bFound )
+ m_vDllLoadModListSubTest.push_back( structDllInfo );
+
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::ParseDllUnload
+// -----------------------------------------------------------------------------
+bool CATDatParser::ParseDllUnload( string& sLine )
+{
+ LOG_FUNC_ENTRY("CATDatParser::ParseDllUnload");
+
+ // Ignore unloads on older version because no timestamps.
+ if ( m_iDataVersion < AT_DLL_TIMESTAMP_DATA_VERSION )
+ {
+ return true;
+ }
+
+ // Skip "DLL_UNLOAD "
+ GetStringUntilNextSpace( sLine );
+
+ // Get module name
+ string sModuleName = GetStringUntilNextSpace( sLine );
+ ChangeToLower( sModuleName );
+
+ // Unload time
+ unsigned long long ull;
+ string sUnload = GetStringUntilNextSpace( sLine );
+ if ( ! hexToDec( sUnload, ull ) )
+ return true;
+
+ // Set module unload time.
+ vector<DLL_LOAD_INFO>::iterator it;
+ for( it = m_vDllLoadModList.begin() ; it != m_vDllLoadModList.end() ; it++ )
+ {
+ if ( sModuleName.compare( it->sModuleName ) == 0 )
+ {
+ (*it).iUnloadTime = ull;
+ break;
+ }
+ }
+ for( it = m_vDllLoadModListSubTest.begin() ; it != m_vDllLoadModListSubTest.end() ; it++ )
+ {
+ if ( sModuleName.compare( it->sModuleName ) == 0 )
+ {
+ (*it).iUnloadTime = ull;
+ break;
+ }
+ }
+ return true;
+}
+// -----------------------------------------------------------------------------
+// CATDatParser::ParseLoggingCancelled
+// -----------------------------------------------------------------------------
+bool CATDatParser::ParseLoggingCancelled( string& sLine )
+{
+ LOG_FUNC_ENTRY("CATDatParser::ParseLoggingCancelled");
+ // Skip text "LOGGING_CANCELLED"
+ GetStringUntilNextSpace( sLine );
+
+ // Get time
+ string sTime( GetStringUntilNextSpace( sLine ) );
+ sTime = ConvertTimeToLocalTime( sTime );
+ m_DataSaver.AddString( "Logging Cancelled." );
+ m_DataSaver.AddLineToLast();
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::ParseHandleLeak
+// -----------------------------------------------------------------------------
+bool CATDatParser::ParseHandleLeak( string& sLine )
+{
+ LOG_FUNC_ENTRY("CATDatParser::ParseHandleLeak");
+ // Skip text "HANDLE_LEAK"
+ GetStringUntilNextSpace( sLine );
+ m_vHandleLeaks.push_back( sLine );
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::ParseTestStart
+// -----------------------------------------------------------------------------
+bool CATDatParser::ParseTestStart( string& sLine )
+{
+ LOG_FUNC_ENTRY("CATDatParser::ParseTestStart");
+ m_bSubtestOnGoing = true;
+ m_iLeakNumber = 0;
+ m_iPinPointedSubTestLeaks = 0;
+
+ // Reset subtest leaked modules list
+ for( size_t i = 0 ; i < m_vDllLoadModListSubTest.size() ; i++ )
+ {
+ m_vDllLoadModListSubTest.at(i).iLeaks = 0;
+ }
+
+ // Skip text "TEST_START"
+ GetStringUntilNextSpace( sLine );
+ // Time
+ string sTime( GetStringUntilNextSpace( sLine ) );
+ sTime = ConvertTimeToLocalTime( sTime );
+ // Name
+ string sSubTestName( GetStringUntilNextSpace( sLine ) );
+ m_DataSaver.AddLineToLast();
+
+ // Get handle count in subtest start
+ string sSubTestStartHandleCount( GetStringUntilNextSpace( sLine ) );
+ m_iSubtestStartHandleCount = atoi( sSubTestStartHandleCount.c_str() );
+
+ // Add start to report
+ m_DataSaver.AddString( "\nSub test (" );
+ m_DataSaver.AddString( sSubTestName.c_str() );
+ m_DataSaver.AddString( ") start: " );
+ m_DataSaver.AddString( sTime.c_str() );
+
+ // m_DataSaver.AddLineToLast();
+
+ // Add start to xml
+ string sResult( sSubTestName );
+ sResult.append( ";" );
+ sResult.append( sTime );
+ sResult.append( ";" );
+ m_DataSaver.SaveXML( sResult, TEST_START );
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::ParseTestEnd
+// -----------------------------------------------------------------------------
+bool CATDatParser::ParseTestEnd( string& sLine )
+{
+ LOG_FUNC_ENTRY("CATDatParser::ParseTestEnd");
+ // Skip text "TEST_END"
+ GetStringUntilNextSpace( sLine );
+
+ // Time
+ string sTime( GetStringUntilNextSpace( sLine ) );
+ sTime = ConvertTimeToLocalTime( sTime );
+
+ // Name
+ string sSubTestName( GetStringUntilNextSpace( sLine ) );
+ m_DataSaver.AddLineToLast();
+
+ // Add test end info to report
+ m_DataSaver.AddString( "Sub test (" );
+ m_DataSaver.AddString( sSubTestName.c_str() );
+ m_DataSaver.AddString( ") end: " );
+ m_DataSaver.AddString( sTime.c_str() );
+ m_DataSaver.AddLineToLast();
+
+ // Leak count to report in subtest
+ if( m_iLeakNumber > 0 )
+ {
+ if ( m_iLogLevel == 1 || m_iLogLevel == 2 )
+ {
+ m_DataSaver.AddInteger( m_iPinPointedSubTestLeaks );
+ m_DataSaver.AddString( " number of pinpointed memory leaks." );
+ m_DataSaver.AddLineToLast();
+ m_DataSaver.AddInteger( m_iLeakNumber );
+ m_DataSaver.AddString( " memory leaks found." );
+ }
+ else
+ {
+ m_DataSaver.AddInteger( m_iLeakNumber );
+ m_DataSaver.AddString( " memory leaks found." );
+ }
+ }
+ else
+ {
+ m_DataSaver.AddString( "No memory leaks found." );
+ }
+ m_DataSaver.AddLineToLast();
+
+ // Use sTime to store info to xml
+ sTime.append(";");
+ char cTemp[128];
+ // Print all modules whitch have leaks
+ for( unsigned int i = 0 ; i < m_vDllLoadModListSubTest.size() ; i++ )
+ {
+ if( m_vDllLoadModListSubTest.at(i).iLeaks > 0 )
+ {
+ // Normal report
+ m_DataSaver.AddInteger( m_vDllLoadModListSubTest[i].iLeaks );
+ m_DataSaver.AddString( " memory leaks in module: " );
+ m_DataSaver.AddString( m_vDllLoadModListSubTest.at(i).sModuleName.c_str() );
+ m_DataSaver.AddLineToLast();
+ // xml
+ string sModuleNameAndLeaks( m_vDllLoadModListSubTest.at(i).sModuleName );
+ sModuleNameAndLeaks.append(";");
+ sModuleNameAndLeaks.append( itoa( m_vDllLoadModListSubTest.at(i).iLeaks, cTemp, 10 ) );
+ m_DataSaver.SaveXML( sModuleNameAndLeaks , SUBTEST_MEM_LEAK_MODULE );
+ }
+ }
+ // Handle count
+ int iEndHandleCount = atoi( GetStringUntilNextSpace( sLine ).c_str() );
+ // Is there handle leaks in subtest?
+ if( iEndHandleCount > m_iSubtestStartHandleCount )
+ {
+ // Print normal report
+ m_DataSaver.AddInteger( iEndHandleCount - m_iSubtestStartHandleCount );
+ m_DataSaver.AddString( " handle leaks in subtest: " );
+ m_DataSaver.AddString( sSubTestName.c_str() );
+ m_DataSaver.AddString( "." );
+ m_DataSaver.AddLineToLast();
+
+ // Print handle leaks to XML
+ string sNrOfHandleLeaks( itoa( iEndHandleCount - m_iSubtestStartHandleCount, cTemp, 10 ) );
+ sNrOfHandleLeaks.append( ";" );
+ m_DataSaver.SaveXML( sNrOfHandleLeaks, SUBTEST_HANDLE_LEAKS );
+ }
+ else
+ {
+ // No handle leaks
+ m_DataSaver.AddString( TEXT_NO_HANDLE_LEAKS );
+ m_DataSaver.AddLineToLast();
+ }
+ // Save xml
+ m_DataSaver.SaveXML( sTime, TEST_END );
+ // Back to normal leaks
+ m_bSubtestOnGoing = false;
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::ParseErrorOccured
+// -----------------------------------------------------------------------------
+bool CATDatParser::ParseErrorOccured( string& sLine )
+{
+ LOG_FUNC_ENTRY("CATDatParser::ParseErrorOccured");
+ string sTime,sError;
+
+ // Skip text "ERROR_OCCURED:"
+ GetStringUntilNextSpace( sLine );
+
+ // Get error
+ sError = GetStringUntilNextSpace( sLine );
+ // Get and convert error time
+ sTime = GetStringUntilNextSpace( sLine );
+ sTime = ConvertTimeToLocalTime( sTime );
+
+ // Print error line
+ m_DataSaver.AddLineToLast();
+ m_DataSaver.AddString( "Error occured on: " );
+ m_DataSaver.AddString( sTime.c_str() );
+ m_DataSaver.AddString( ". " );
+ m_DataSaver.AddString( "Symbian error code: " );
+ m_DataSaver.AddString( sError.c_str() );
+ m_DataSaver.AddString( "." );
+ m_DataSaver.AddLineToLast();
+
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::ParseMemLeak
+// -----------------------------------------------------------------------------
+bool CATDatParser::ParseMemLeak( string& sLine )
+{
+ LOG_FUNC_ENTRY("CATDatParser::ParseMemLeak");
+ // Increment leak count
+ if ( ! m_bSubtestOnGoing )
+ m_iTotalNumberOfLeaks++;
+
+ // Increase leak number
+ m_iLeakNumber++;
+
+ // Leak data variables
+ string sModuleName;
+ string sLeakSize;
+ string sTime;
+ unsigned long long iTime = 0;
+ string sLeakAddress;
+
+ // Skip text "MEM_LEAK"
+ GetStringUntilNextSpace( sLine );
+ // Get leak address
+ sLeakAddress = GetStringUntilNextSpace( sLine );
+ // Get time
+ sTime = GetStringUntilNextSpace( sLine );
+ // Convert time to decimal
+ hexToDec( sTime, iTime );
+ // Get memory reserve size
+ sLeakSize = GetStringUntilNextSpace( sLine );
+ // Convert leak time
+ sTime = ConvertTimeToLocalTime( sTime );
+
+ // Loop thru call stack and put memory addresses in vector
+ CleanMemoryAddresses(); // Clean memory address vector
+ CATMemoryAddress* pMemAddr = 0;
+ vector<string> vStrings = ParseStringToVector( sLine, ' ' );
+ for( size_t i = 0; i < vStrings.size() ; i++ )
+ {
+ pMemAddr = new CATMemoryAddress( vStrings.at(i), m_iOffSet );
+ // Set address time
+ pMemAddr->SetTime( iTime );
+ // Set address module name
+ if ( pMemAddr->FindSetModuleName( &m_vDllLoadModList ) )
+ {
+ // Increment leaks in module once
+ if ( sModuleName.empty() )
+ {
+ if ( m_bSubtestOnGoing )
+ m_vDllLoadModListSubTest.at( pMemAddr->GetDllLoadInfoIndex() ).iLeaks++;
+ else
+ m_vDllLoadModList.at( pMemAddr->GetDllLoadInfoIndex() ).iLeaks++;
+ // Set leak's module where it was located.
+ sModuleName = pMemAddr->GetModuleName();
+ }
+ }
+ // Add it to vector
+ m_vMemoryAddress.push_back( pMemAddr );
+ }
+ // If logging level is 0 Skip printing / locating code lines for call stack items.
+ if ( m_iLogLevel == 0 )
+ return true;
+ if ( m_pModules && vStrings.size() > 0 )
+ {
+ // Have we successfully located code line for memory address
+ bool bSuccesfullAddressToLine = false;
+ for( size_t x = 0; x < m_vMemoryAddress.size(); x++ )
+ {
+ int iIndexInDll = m_vMemoryAddress.at( x )->GetDllLoadInfoIndex();
+ if ( iIndexInDll != -1 )
+ {
+ // Dll module name from data file
+ string sDllName = m_vDllLoadModList.at( iIndexInDll ).sModuleName;
+ // Find module from project. These are read from makefiles.
+ for ( size_t y = 0; y < m_pModules->size() ; y++ )
+ {
+ // Module name from project data (makefiles)
+ string sModuleName = m_pModules->at( y )->GetBinaryName();
+ // If we find module from project ones, use it to located code line for memory address
+ // Note! dll names can be pretty messy i.e. DLL_LOAD 10281fc6.dll{000a0000}[10281fc6] 81d57b88 81e60a90
+ if ( sDllName.find( sModuleName ) != string::npos )
+ {
+ m_pModules->at( y )->AddressToLine( m_vMemoryAddress.at( x ) );
+ if ( ! bSuccesfullAddressToLine )
+ {
+ int iPPState = m_vMemoryAddress.at( x )->GetAddressToLineState();
+ if ( iPPState == CATMemoryAddress::EXACT || iPPState == CATMemoryAddress::FUNCTION )
+ {
+ bSuccesfullAddressToLine = true;
+ if ( m_bSubtestOnGoing )
+ m_iPinPointedSubTestLeaks++;
+ else
+ m_iPinPointedLeaks++;
+ }
+ }
+ }
+ }
+ }
+ }
+ // If rom/rofs specified we use it to try get binary and function names
+ // for addresses currently out of process range.
+ if ( m_pRomSymbol )
+ {
+ for( size_t x = 0; x < m_vMemoryAddress.size(); x++ )
+ {
+ if ( m_vMemoryAddress.at(x)->GetAddressToLineState() == CATMemoryAddress::OUT_OF_PROCESS
+ || m_vMemoryAddress.at(x)->GetAddressToLineState() == CATMemoryAddress::OUT_OF_RANGE )
+ {
+ m_pRomSymbol->AddressToLine( m_vMemoryAddress.at(x) );
+ }
+ }
+ }
+ }
+ // Print leak
+ PrintMemLeak( sTime, sLeakSize, sLeakAddress, sModuleName);
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::PrintMemLeak
+// -----------------------------------------------------------------------------
+void CATDatParser::PrintMemLeak(const string& sTime,
+ const string& sLeakSize,
+ const string& sLeakAddr,
+ const string& sModuleName)
+{
+ LOG_FUNC_ENTRY("CATDatParser::PrintMemLeak");
+ // Print header data of leak
+ m_DataSaver.AddString("\nMemory leak ");
+ m_DataSaver.AddInteger( m_iLeakNumber, true);
+
+ // Leak size
+ m_DataSaver.AddString( " (" );
+ m_DataSaver.AddInteger( _httoi( sLeakSize.c_str() ), true );
+ m_DataSaver.AddString( " bytes) " );
+
+ // Leak address
+ m_DataSaver.AddString("(0x");
+ m_DataSaver.AddString( sLeakAddr.c_str(), true );
+ m_DataSaver.AddString( ") " );
+
+ // Time
+ m_DataSaver.AddString( sTime.c_str(), true );
+ m_DataSaver.AddString( " " );
+
+ // Module name
+ m_DataSaver.AddString( sModuleName.c_str(), true );
+ m_DataSaver.SaveCarbideDataHeader();
+
+ // Add header line
+ m_DataSaver.AddLineToLast();
+
+ // Print the call stack items
+ for( size_t i = 0 ; i < m_vMemoryAddress.size() ; i++ )
+ {
+ // On log levels 1 & 2 we only print located code lines.
+ #ifndef ADDR2LINE
+ if(
+ ( m_iLogLevel == 1 || m_iLogLevel == 2 )
+ &&
+ ( m_vMemoryAddress.at(i)->GetAddressToLineState() != CATMemoryAddress::EXACT
+ && m_vMemoryAddress.at(i)->GetAddressToLineState() != CATMemoryAddress::FUNCTION )
+ )
+ {
+ // Skips to next
+ continue;
+ }
+ #endif
+ #ifdef ADDR2LINE
+ if( ( m_iLogLevel == 1 || m_iLogLevel == 2 )
+ && m_vMemoryAddress.at(i)->GetAddressToLineState() != CATMemoryAddress::EXACT )
+ {
+ // Skips to next
+ continue;
+ }
+ #endif
+ else if ( m_vMemoryAddress.at(i)->GetAddressToLineState() == CATMemoryAddress::OUT_OF_PROCESS )
+ {
+ // Is memory address out of modules range
+ string sTemp;
+ sTemp.append( m_vMemoryAddress.at(i)->GetAddressString() );
+ sTemp.append( " Address out of process memory.");
+ m_DataSaver.AddString( sTemp.c_str(), true );
+ m_DataSaver.AddLineToLast();
+ continue;
+ }
+
+ // Print memory address
+ m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetAddressString().c_str(), true );
+
+ // Space (only for console output)
+ m_DataSaver.AddString( " " );
+
+ m_DataSaver.AddCarbideData(
+ NumberToHexString( m_vMemoryAddress.at(i)->GetOffSetFromModuleStart() ) );
+
+ // Module name
+ m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetModuleName().c_str(), true );
+
+ // Print call stack memory address details depending on state of memory address
+ switch( m_vMemoryAddress.at(i)->GetAddressToLineState() )
+ {
+ // Address outside of known processes
+ case CATMemoryAddress::OUT_OF_PROCESS:
+ m_DataSaver.AddLineToLast();
+ break;
+ // Address located outside of known modules symbols
+ case CATMemoryAddress::OUT_OF_RANGE:
+ m_DataSaver.AddString( " " );
+ m_DataSaver.AddString( "???", true );
+ m_DataSaver.AddLineToLast();
+ break;
+ // Symbol state is currently used when using rom symbol file.
+ // From it we get module name & function name.
+ case CATMemoryAddress::SYMBOL:
+ m_DataSaver.AddString( " " );
+ m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFunctionName().c_str(), true );
+ if ( ! m_vMemoryAddress.at( i )->GetFileName().empty() )
+ {
+ m_DataSaver.AddString( " (" );
+ m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFileName().c_str(), true );
+ m_DataSaver.AddString( ")" );
+ }
+ m_DataSaver.AddLineToLast();
+ break;
+ // Lst & Map implementation
+ #ifndef ADDR2LINE
+ case CATMemoryAddress::FUNCTION:
+ case CATMemoryAddress::EXACT:
+ m_DataSaver.AddString( " " );
+ m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFunctionName().c_str(), true );
+ // Small difference displaying details depending on build urel/udeb
+ if ( m_eBuildType == CATProject::UREL )
+ {
+ // UREL
+ // Set build info to data saver
+ m_DataSaver.SetBuild( false );
+ // urel = functionname: linenumber (filename)
+ m_DataSaver.AddString( ": " );
+ if ( m_vMemoryAddress.at(i)->GetFunctionLineNumber() != -1 )
+ m_DataSaver.AddInteger( m_vMemoryAddress.at(i)->GetFunctionLineNumber(), true );
+ else if ( m_vMemoryAddress.at(i)->GetExactLineNumber() != -1 )
+ m_DataSaver.AddInteger( m_vMemoryAddress.at(i)->GetExactLineNumber(), true );
+ m_DataSaver.AddString( " (" );
+ m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFileName().c_str(), true );
+ m_DataSaver.AddString( ")" );
+ m_DataSaver.AddLineToLast();
+ }
+ else
+ {
+ // UDEB
+ // udeb = functionname: (filename:linenumber)
+ m_DataSaver.AddString( " (" );
+ m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFileName().c_str(), true );
+ m_DataSaver.AddString( ":" );
+ if( m_vMemoryAddress.at(i)->GetExactLineNumber() != -1 )
+ m_DataSaver.AddInteger( m_vMemoryAddress.at(i)->GetExactLineNumber(), true );
+ else
+ m_DataSaver.AddString( "???", true );
+ m_DataSaver.AddString( ")" );
+ m_DataSaver.AddLineToLast();
+ }
+ break;
+ #endif
+ // addr2line implementation (new).
+ #ifdef ADDR2LINE
+ case CATMemoryAddress::FUNCTION:
+ m_DataSaver.AddString( " " );
+ m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFunctionName().c_str(), true );
+ m_DataSaver.AddString( " (" );
+ m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFileName().c_str(), true );
+ m_DataSaver.AddString( ":" );
+ if( m_vMemoryAddress.at(i)->GetExactLineNumber() != -1 )
+ m_DataSaver.AddInteger( m_vMemoryAddress.at(i)->GetFunctionLineNumber(), true );
+ else
+ m_DataSaver.AddString( "???", true );
+ m_DataSaver.AddString( ")" );
+ m_DataSaver.AddLineToLast();
+ break;
+ case CATMemoryAddress::EXACT:
+ m_DataSaver.AddString( " " );
+ m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFunctionName().c_str(), true );
+ m_DataSaver.AddString( " (" );
+ m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFileName().c_str(), true );
+ m_DataSaver.AddString( ":" );
+ if( m_vMemoryAddress.at(i)->GetExactLineNumber() != -1 )
+ m_DataSaver.AddInteger( m_vMemoryAddress.at(i)->GetExactLineNumber(), true );
+ else
+ m_DataSaver.AddString( "???", true );
+ m_DataSaver.AddString( ")" );
+ m_DataSaver.AddLineToLast();
+ break;
+ #endif
+ } // End switch
+ // On logging level 1 we only print one located code line
+ #ifndef ADDR2LINE
+ if ( m_iLogLevel == 1 && ( m_vMemoryAddress.at(i)->GetAddressToLineState() == CATMemoryAddress::EXACT ||
+ m_vMemoryAddress.at(i)->GetAddressToLineState() == CATMemoryAddress::FUNCTION ) )
+ break;
+ #endif
+ #ifdef ADDR2LINE
+ if ( m_iLogLevel == 1 && m_vMemoryAddress.at(i)->GetAddressToLineState() == CATMemoryAddress::EXACT )
+ break;
+ #endif
+ } // End call stack items loop
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::SetInputFile
+// -----------------------------------------------------------------------------
+void CATDatParser::SetInputFile(const string& sInputFile)
+{
+ LOG_FUNC_ENTRY("CATDatParser::SetInputFile");
+ m_sInputFile = sInputFile;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::SetOutputFile
+// -----------------------------------------------------------------------------
+void CATDatParser::SetOutputFile(const string& sOutpuFile)
+{
+ LOG_FUNC_ENTRY("CATDatParser::SetOutputFile");
+ m_sOutputFile = sOutpuFile;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::SetRomSymbolFiles
+// -----------------------------------------------------------------------------
+void CATDatParser::SetRomSymbolFiles(const vector<string>& vRomSymbolFiles)
+{
+ LOG_FUNC_ENTRY("CATDatParser::SetRomSymbolFiles");
+ m_vRomSymbolFiles = vRomSymbolFiles;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::SetLogLevel
+// -----------------------------------------------------------------------------
+void CATDatParser::SetLogLevel(int iLogLevel)
+{
+ LOG_FUNC_ENTRY("CATDatParser::SetLogLevel");
+ m_iLogLevel = iLogLevel;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::GetLogLevel
+// -----------------------------------------------------------------------------
+int CATDatParser::GetLogLevel() const
+{
+ LOG_LOW_FUNC_ENTRY("CATDatParser::GetLogLevel");
+ return m_iLogLevel;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::CleanMemoryAddresses
+// -----------------------------------------------------------------------------
+void CATDatParser::CleanMemoryAddresses()
+{
+ LOG_LOW_FUNC_ENTRY("CATDatParser::CleanMemoryAddresses");
+ // Cleanup memory addressses.
+ for( vector<CATMemoryAddress*>::iterator it = m_vMemoryAddress.begin(); it != m_vMemoryAddress.end(); it++ )
+ {
+ delete *it;
+ }
+ m_vMemoryAddress.clear();
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::ConvertTimeToLocalTime
+// -----------------------------------------------------------------------------
+string CATDatParser::ConvertTimeToLocalTime( string sInputTime )
+{
+ LOG_LOW_FUNC_ENTRY("CATDatParser::ConvertTimeToLocalTime");
+ //Is process end abnormal?
+ if( sInputTime.compare( LABEL_ABNORMAL ) == 0 )
+ {
+ return string( AT_ANALYZE_ABNORMAL_EXIT );
+ }
+ else
+ // Check that input time is at least 32-bit
+ if( sInputTime.length() <= 8 )
+ {
+ sInputTime.clear();
+ return sInputTime;
+ }
+
+ string sTemp = sInputTime;
+ const char* pTemp = sTemp.c_str();
+
+ // Are all characters hex
+ for( unsigned int i = 0 ; i < sTemp.size() ; i++ )
+ {
+ if( !IsHexCharacter( (pTemp + i) ) )
+ {
+ return sInputTime;
+ }
+ }
+
+ // Get LSB bits
+ string sLsb;
+ sLsb.append( sInputTime.substr( sInputTime.length()-8, sInputTime.length() ) );
+ unsigned int iLsbTime = (unsigned int)_httoi( sLsb.c_str() );
+
+ // Get MSB bits
+ string sMsb;
+ sMsb.append( sInputTime.substr( 0, sInputTime.length()-8 ) );
+ unsigned int iMsbTime = (unsigned int)_httoi( sMsb.c_str() );
+
+ // Get time in microsecods
+ long long sdf = iMsbTime * 0x100000000 + iLsbTime;
+
+ // Get original time (starting at year 1970 )
+ long long llOrigTime = sdf;
+
+ // Get seconds
+ sdf = ( sdf )/1000000;
+
+ // Check that sdf contains some time value
+ if( sdf <= 0)
+ {
+ // Error in time calculation
+ // Return empty string
+ sInputTime.clear();
+ return sInputTime;
+ }
+
+ // Original time after year 1970 in seconds
+ long long llOrignTimeInSeconds = sdf;
+
+ // Calculate new time which does not include millisecods
+ long long llDiffTime = (llOrignTimeInSeconds * 1000000);
+
+ // Calculate time difference in milliseconds
+ int llDiffTimeInMilliSecods = (int)( llOrigTime - llDiffTime )/1000;
+
+ // Convert difference time to char
+ char cDiffInMilliSeconds[20];
+ _itoa( llDiffTimeInMilliSecods, cDiffInMilliSeconds, 10 );
+
+ // Time info structure
+ struct tm *timeinfo;
+
+ // Get local time
+ timeinfo = localtime ( (time_t*) &sdf );
+
+ // Create string and append memory leak time to it
+ string sTime;
+ sTime.append( asctime( timeinfo ) );
+
+ // Remove last char of locale time string which is \n
+ sTime.resize( (int)sTime.length()-1 );
+
+ // Get last space index
+ int iLastSpace = (int)sTime.find_last_of(" ");
+
+ // If last space index is valid
+ if( iLastSpace <= (int)sTime.length() && iLastSpace > 0)
+ {
+ string sTempTime;
+ // Append first part of original time string
+ sTempTime.append( sTime.substr( 0, iLastSpace ) );
+
+ // Append millisecods
+ sTempTime.append( "." );
+ sTempTime.append( cDiffInMilliSeconds );
+
+ // Append the rest of the original time string part
+ sTempTime.append( sTime.substr( iLastSpace, sTime.length()));
+
+ // Clear original and append new time string which includes millisecods
+ sTime.clear();
+ sTime.append( sTempTime );
+ }
+
+ // Return memory leak time
+ return sTime.c_str();
+}
+
+bool CATDatParser::CreateWinscwModule( const string& sBinaryName )
+{
+ LOG_FUNC_ENTRY( "CATDatParser::CreateWinscwModule" );
+ // Is module already created?
+ for( vector<CATModule2*>::iterator it = m_pModules->begin(); it != m_pModules->end(); it++ )
+ {
+ if ( _stricmp( sBinaryName.c_str(), (*it)->GetBinaryName().c_str() ) == 0 )
+ return true;
+ }
+ // No create new one and set its values.
+ CATModule2* mod = new CATModule2();
+ mod->SetTarget( RemovePathAndExt( sBinaryName, true ) );
+ mod->SetRequestedTargetExt( GetExtension( sBinaryName ) );
+ mod->SetReleasePath( string( "\\epoc32\\release" ) );
+ if ( m_eBuildType == CATProject::UDEB )
+ mod->SetFullVariantPath( string( "winscw\\udeb" ) );
+ else
+ mod->SetFullVariantPath( string( "winscw\\urel" ) );
+ mod->SetVariantPlatform( string( "winscw" ) );
+ m_pModules->push_back( mod );
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::FindModuleUsingAddress
+// Function finds module using given address.
+// -----------------------------------------------------------------------------
+int CATDatParser::FindModuleUsingAddress( unsigned long iAddress ) const
+{
+ LOG_LOW_FUNC_ENTRY("CATDatParser::FindModuleUsingAddress");
+ int iRet = -1;
+ for( unsigned int i = 0 ; i < m_vDllLoadModList.size() ; i++ )
+ {
+ // Is address between start and end address?
+ if( iAddress > m_vDllLoadModList[i].iStartAddress && iAddress < m_vDllLoadModList[i].iEndAddress )
+ {
+ iRet = i;
+ break;
+ }
+ }
+ return iRet;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::FindModuleUsingPID
+// Function finds module using module id.
+// -----------------------------------------------------------------------------
+/*
+int CATDatParser::FindModuleUsingPID( unsigned long iPID ) const
+{
+ LOG_FUNC_ENTRY("CATDatParser::FindModuleUsingPID");
+
+ int iRet = -1;
+
+ // Change module name characters to lowercase
+ for( unsigned int i = 0 ; i < m_vDllLoadModList.size() ; i++ )
+ {
+ if( m_vDllLoadModList[i].iPID == iPID )
+ {
+ iRet = i;
+ break;
+ }
+ }
+ return iRet;
+}
+*/
+// -----------------------------------------------------------------------------
+// CATDatParser::FindModuleUsingName
+// Function finds module using module name.
+// -----------------------------------------------------------------------------
+int CATDatParser::FindModuleUsingName( const char* pModName )
+{
+ LOG_LOW_FUNC_ENTRY("CATDatParser::FindModuleUsingName");
+
+ // Mod name empty?
+ if( pModName == NULL || *pModName == 0 )
+ return -1;
+
+ int iRet = -1;
+ string sModName( pModName );
+ // Change module name characters to lowercase
+ ChangeToLower( sModName );
+ // Remove variant marks (dots)
+ RemoveAllAfterDotIfTwoDots( sModName);
+ for( unsigned int i = 0 ; i < m_vDllLoadModList.size() ; i++ )
+ {
+ string sTemp( m_vDllLoadModList[i].sModuleName );
+ ChangeToLower( sTemp );
+ // Remove variant marks (dots)
+ RemoveAllAfterDotIfTwoDots( sTemp );
+ if( sTemp.find( sModName ) != string::npos )
+ {
+ iRet = i;
+ break;
+ }
+ }
+ return iRet;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::SetPrintFlag
+// -----------------------------------------------------------------------------
+void CATDatParser::SetPringFlag( bool bPrintFlag )
+{
+ LOG_FUNC_ENTRY("CATDatParser::SetPringFlag");
+ m_DataSaver.SetPrintFlag( bPrintFlag );
+}
+// -----------------------------------------------------------------------------
+// CATDatParser::SetOffSet
+// -----------------------------------------------------------------------------
+void CATDatParser::SetOffSet( int iOffSet )
+{
+ LOG_FUNC_ENTRY("CATDatParser::SetOffSet");
+ m_iOffSet = iOffSet;
+}
+
+// -----------------------------------------------------------------------------
+// CATDatParser::GetOffSet
+// -----------------------------------------------------------------------------
+int CATDatParser::GetOffSet( ) const
+{
+ LOG_LOW_FUNC_ENTRY("CATDatParser::GetOffSet");
+ return m_iOffSet;
+}
+
+// -----------------------------------------------------------------------------
+// Set project platform.
+// -----------------------------------------------------------------------------
+void CATDatParser::SetProjectPlatform( const string& sPlatform )
+{
+ LOG_FUNC_ENTRY("CATDatParser::SetProjectPlatform");
+ m_sProjectPlatform = sPlatform;
+
+ // Check that platform not empty before determing platform from it.
+ if ( sPlatform.empty() )
+ return;
+
+ // Set functions offset in mapfiles correct (depending on platform).
+ if ( _stricmp( sPlatform.c_str(), "armv5" ) == 0 )
+ {
+ m_iOffSet = FUNCTIONS_OFFSET_IN_MAP_FILE_ARMV5;
+ }
+ else if ( _stricmp( sPlatform.c_str(), "winscw" ) == 0 )
+ {
+ m_iOffSet = FUNCTIONS_OFFSET_IN_MAP_FILE_WINSCW;
+ }
+ else if ( _stricmp( sPlatform.c_str(), "gcce" ) == 0 )
+ {
+ m_iOffSet = FUNCTIONS_OFFSET_IN_GCCE;
+ }
+ else
+ {
+ LOG_STRING( AT_MSG << "Error, cannot set function's offset in map file, invalid platform: " << sPlatform );
+ }
+}
+
+// -----------------------------------------------------------------------------
+// Set projects build type. Use enumeration defined in CATProject.
+// -----------------------------------------------------------------------------
+void CATDatParser::SetProjectBuildType( int eBuildType )
+{
+ LOG_FUNC_ENTRY("CATDatParser::SetProjectBuildType");
+ m_eProjectBuildType = eBuildType;
+}
+
+//EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/CATDataSaver.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,873 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Definitions for the class CATDataSaver.
+*
+*/
+
+
+#include "../inc/catdatasaver.h"
+
+#include <xercesc/util/OutOfMemoryException.hpp>
+
+#if defined(XERCES_NEW_IOSTREAMS)
+#include <iostream>
+#else
+#include <iostream.h>
+#endif
+
+// Line feed char sequence used in XML report
+wchar_t AT_XML_LINEFEEDS[3] = L"\r\n";
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::CATDataSaver
+// Constructor.
+// -----------------------------------------------------------------------------
+CATDataSaver::CATDataSaver( void )
+{
+ LOG_FUNC_ENTRY("CATDataSaver::CATDataSaver");
+ m_iLoggingLevel = DEFAULT_LOGGING_LEVEL;
+ m_bPrintImmediately = true;
+ m_bXMLInitOk = false;
+ m_bUdebBuild = true;
+
+ m_iRunNumber = 1;
+
+ m_pDomDoc = NULL;
+ m_pRootElem = NULL;
+ m_Serializer = NULL;
+ m_pCurrentLeakElem = NULL;
+ m_pRunElement = NULL;
+ m_pMemoryLeaks = NULL;
+ m_pHandleLeaks = NULL;
+ m_pCurrentSubTestElem = NULL;
+ m_pSubtestMemoryLeaks = NULL;
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::~CATDataSaver
+// Destructor.
+// -----------------------------------------------------------------------------
+CATDataSaver::~CATDataSaver(void)
+{
+ LOG_FUNC_ENTRY("CATDataSaver::~CATDataSaver");
+ if( m_bXMLInitOk )
+ {
+ if( m_Serializer )
+ delete m_Serializer;
+
+ m_pDomDoc->release();
+ xercesc::XMLPlatformUtils::Terminate();
+ }
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::SaveLinesToFile
+// Gets logging level.
+// -----------------------------------------------------------------------------
+void CATDataSaver::SaveLinesToFile( const char* pFileName, int iDataToSave )
+{
+ LOG_FUNC_ENTRY("CATDataSaver::SaveLinesToFile");
+
+ // Nothing to print?
+ if( m_vLines.empty() )
+ {
+ printf( "No output data." );
+ return;
+ }
+ if( iDataToSave != XML_DATA )
+ {
+ ofstream out( pFileName );
+
+ if( !out.good() )
+ {
+ printf( "Can not open file: %s\n", pFileName );
+ return;
+ }
+ switch( iDataToSave )
+ {
+ case TEXT_DATA:
+ for( int i = 0 ; i < (int)m_vLines.size() ; i++ )
+ {
+ out << m_vLines[i].c_str();
+ }
+ break;
+ }
+ out.close();
+ }
+ else
+ {
+ if( m_bXMLInitOk )
+ {
+ xercesc::XMLFormatTarget* myFormTarget = NULL;
+ try
+ {
+ // Create format
+ myFormTarget = new xercesc::LocalFileFormatTarget( pFileName );
+
+ // Set line-feeds to dom writer
+ m_Serializer->setNewLine( AT_XML_LINEFEEDS );
+
+ // Set human-readable property. Note! Api already changed in >2.7
+ // so this will cause error/problems if linked to newer library.
+ m_Serializer->setFeature( xercesc::XMLUni::fgDOMWRTFormatPrettyPrint, true );
+
+ // Write document
+ m_Serializer->writeNode(myFormTarget, *m_pDomDoc);
+ }
+ catch(...)
+ {
+ printf( "Can not save output file: %s.", pFileName );
+ }
+ if( myFormTarget )
+ delete myFormTarget; //lint !e118
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::PrintLinesToScreen
+// Prints all saved lines to screen.
+// -----------------------------------------------------------------------------
+void CATDataSaver::PrintLinesToScreen( void )
+{
+ LOG_FUNC_ENTRY("CATDataSaver::PrintLinesToScreen");
+ // Nothing to print?
+ if( m_vLines.empty() )
+ {
+ printf( "No output data." );
+ return;
+ }
+ for( int i = 0 ; i < (int)m_vLines.size() ; i++ )
+ {
+ printf( m_vLines[i].c_str() );
+ }
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::AddLineToFirst
+// Adds saved line to first in database.
+// -----------------------------------------------------------------------------
+void CATDataSaver::AddLineToFirst( void )
+{
+ LOG_LOW_FUNC_ENTRY("CATDataSaver::AddLineToFirst");
+ m_sLine.append( "\n" );
+ m_vLines.insert( m_vLines.begin(), m_sLine );
+ m_sLine.clear();
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::AddLineToLast
+// Adds saved line to last in database.
+// -----------------------------------------------------------------------------
+void CATDataSaver::AddLineToLast()
+{
+ LOG_LOW_FUNC_ENTRY("CATDataSaver::AddLineToLast");
+ m_sLine.append( "\n" );
+
+ string sTempDataLine;
+
+ m_vLines.push_back( m_sLine );
+
+ SaveXML( m_sCarbideDataLine, ITEM );
+
+ if( m_bPrintImmediately )
+ {
+ printf( m_sLine.c_str() );
+ }
+
+ m_sCarbideDataLine.clear();
+ m_sLine.clear();
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::AddString
+// Adds string to current line.
+// -----------------------------------------------------------------------------
+void CATDataSaver::AddString( const char* pData, bool bSaveCarbideData )
+{
+ LOG_LOW_FUNC_ENTRY("CATDataSaver::AddString");
+ m_sLine.append( pData );
+
+ if( bSaveCarbideData )
+ {
+ m_sCarbideDataLine.append( pData );
+ m_sCarbideDataLine.append(";");
+ }
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::AddInteger
+// Converts integer to string and adds it to current line.
+// -----------------------------------------------------------------------------
+void CATDataSaver::AddInteger( int iValue, bool bSaveCarbideData )
+{
+ LOG_LOW_FUNC_ENTRY("CATDataSaver::AddInteger");
+ char cTemp[128];
+ string sValue( itoa( iValue, cTemp, 10 ) );
+ m_sLine.append( sValue );
+
+ if( bSaveCarbideData )
+ {
+ m_sCarbideDataLine.append( sValue );
+ m_sCarbideDataLine.append(";");
+ }
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::SetLoggingLevel
+// Sets logging level.
+// -----------------------------------------------------------------------------
+void CATDataSaver::SetLoggingLevel( int iLoggingLevel )
+{
+ LOG_FUNC_ENTRY("CATDataSaver::SetLoggingLevel");
+ // Check that new logging level is valid
+ // Acceptable values are between MIN_LOGGING_LEVEL and
+ // MAX_LOGGING_LEVEL including them
+ if( iLoggingLevel >= MIN_LOGGING_LEVEL && iLoggingLevel <= MAX_LOGGING_LEVEL )
+ {
+ m_iLoggingLevel = iLoggingLevel;
+ }
+ else
+ {
+ // New logging level value is invalid => set default logging level
+ m_iLoggingLevel = DEFAULT_LOGGING_LEVEL;
+ }
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::GetLoggingLevel
+// Gets logging level.
+// -----------------------------------------------------------------------------
+int CATDataSaver::GetLoggingLevel( void )
+{
+ LOG_LOW_FUNC_ENTRY("CATDataSaver::GetLoggingLevel");
+ return m_iLoggingLevel;
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::SetPrintFlag
+// Sets print immediately flag.
+// -----------------------------------------------------------------------------
+void CATDataSaver::SetPrintFlag( bool bPrintImmediately )
+{
+ LOG_FUNC_ENTRY("CATDataSaver::SetPrintFlag");
+ m_bPrintImmediately = bPrintImmediately;
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::SaveCarbideDataHeader
+// Sets data header for Carbide data.
+// -----------------------------------------------------------------------------
+void CATDataSaver::SaveCarbideDataHeader( void )
+{
+ LOG_FUNC_ENTRY("CATDataSaver::SaveCarbideDataHeader");
+ SaveXML( m_sCarbideDataLine, LEAK );
+ m_sCarbideDataLine.clear();
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::InitXML
+// Initializes xerces xml parser.
+// -----------------------------------------------------------------------------
+bool CATDataSaver::InitXML( void )
+{
+ LOG_FUNC_ENTRY("CATDataSaver::InitXML");
+ try
+ {
+ xercesc::XMLPlatformUtils::Initialize();
+ }
+ catch ( ... )//(const XMLException& toCatch)
+ {
+ // Do your failure processing here
+ printf("XML initialization failed.\n");
+ return false;
+ }
+ // Error code.
+ int errorCode = 0;
+ // getDomIMplementation returns null if source has none.
+ xercesc::DOMImplementation* impl = xercesc::DOMImplementationRegistry::getDOMImplementation(L"Core");
+ if (impl != NULL)
+ {
+ // Create new DOMWriter.
+ m_Serializer = ((xercesc::DOMImplementationLS*)impl)->createDOMWriter();
+ // New document.
+ try
+ {
+ m_pDomDoc = impl->createDocument(
+ 0, // Root element namespace URI.
+ L"results", // Root element name
+ 0); // Document type object (DTD).
+
+ m_pRootElem = m_pDomDoc->getDocumentElement();
+ }
+ catch (const xercesc::OutOfMemoryException&)
+ {
+ XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl;
+ errorCode = 5;
+ }
+ catch (const xercesc::DOMException& e)
+ {
+ XERCES_STD_QUALIFIER cerr << "DOMException code is: " << e.code << XERCES_STD_QUALIFIER endl;
+ errorCode = 2;
+ }
+ catch (...)
+ {
+ XERCES_STD_QUALIFIER cerr << "An error occurred creating the document" << XERCES_STD_QUALIFIER endl;
+ errorCode = 3;
+ }
+ } // (inpl != NULL)
+ else
+ {
+ XERCES_STD_QUALIFIER cerr << "Requested implementation is not supported" << XERCES_STD_QUALIFIER endl;
+ errorCode = 4;
+ }
+ if( !errorCode )
+ {
+ m_bXMLInitOk = true;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::WCharToChar
+// Converts wchar_t* -> char*.
+// -----------------------------------------------------------------------------
+void CATDataSaver::WCharToChar( string& sInput, const WCHAR* Source )
+{
+ LOG_LOW_FUNC_ENTRY("CATDataSaver::WCharToChar");
+ if( !Source )
+ return;
+ int i = 0;
+
+ while( Source[i] != '\0' )
+ {
+ char c = (CHAR)Source[i];
+ sInput.append( &c, 1 );
+ ++i;
+ }
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::CharToWChar
+// Converts char* -> wchar_t*.
+// -----------------------------------------------------------------------------
+LPWSTR CATDataSaver::CharToWChar( const char* str )
+{
+ LOG_LOW_FUNC_ENTRY("CATDataSaver::CharToWChar");
+ LPWSTR out = NULL;
+ if( str != NULL )
+ {
+ int in_len = (int)strlen( str );
+ int out_len = MultiByteToWideChar(CP_ACP, 0, str, in_len, NULL, 0) + 2;
+ out = new WCHAR[out_len];
+
+ if (out)
+ {
+ memset(out, 0x00, sizeof(WCHAR)*out_len);
+ MultiByteToWideChar(CP_ACP, 0, str, in_len, out, in_len);
+ }
+ }
+ return out;
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::SaveXML
+// Writes data to xml tree.
+// -----------------------------------------------------------------------------
+void CATDataSaver::SaveXML( string sInput, int iElementType )
+{
+ LOG_FUNC_ENTRY("CATDataSaver::SaveXML");
+ // Variables ok?
+ if( sInput.empty() || m_pDomDoc == NULL )
+ {
+ return;
+ }
+ try
+ {
+ switch( iElementType )
+ {
+ case RESULT:
+ {
+ // Print number of runs
+ string sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+ LPWSTR wTemp = CharToWChar( sTemp.c_str() );
+ m_pRootElem->setAttribute( L"runs", (const LPWSTR)wTemp );
+
+ // Print failed runs
+ sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+ if( wTemp )
+ delete[] wTemp;
+ wTemp = CharToWChar( sTemp.c_str() );
+ m_pRootElem->setAttribute( L"failed", (const LPWSTR)wTemp );
+ if( wTemp )
+ delete[] wTemp;
+ }
+ break;
+ case RUN:
+ {
+ if( m_pRootElem == NULL )
+ return;
+ xercesc::DOMElement* runElem = m_pDomDoc->createElement( L"run" );
+ m_pRootElem->appendChild( runElem );
+
+ // Reset handle leaks.
+ m_pHandleLeaks = NULL;
+
+ // Print start time
+ string sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+ LPWSTR wTemp = CharToWChar( sTemp.c_str() );
+ runElem->setAttribute( L"start_time", (const LPWSTR)wTemp );
+ runElem->setAttribute( L"end_time", NULL );
+ if( wTemp )
+ delete[] wTemp;
+
+ // Print build target
+ sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+ wTemp = CharToWChar( sTemp.c_str() );
+ runElem->setAttribute( L"build_target", (const LPWSTR)wTemp );
+ if( wTemp )
+ delete[] wTemp;
+
+ // Print process name
+ wTemp = CharToWChar( sInput.c_str() );
+ runElem->setAttribute( L"process_name", (const LPWSTR)wTemp );
+
+ m_pRunElement = runElem;
+
+ char cTemp[128];
+ if( wTemp )
+ delete[] wTemp;
+ wTemp = CharToWChar( itoa( m_iRunNumber, cTemp, 10 ) );
+ runElem->setAttribute( L"id", (const LPWSTR)wTemp );
+ m_iRunNumber++;
+ if( wTemp )
+ delete[] wTemp;
+ }
+ break;
+ case LEAK:
+ {
+ m_pCurrentLeakElem = m_pDomDoc->createElement( L"leak" );
+
+
+ if( m_pCurrentLeakElem == NULL || m_pRunElement == NULL )
+ return;
+
+ // Sub test?
+ if( m_pCurrentSubTestElem )
+ m_pCurrentSubTestElem->appendChild( m_pCurrentLeakElem );
+ else
+ m_pRunElement->appendChild( m_pCurrentLeakElem );
+
+ // Print leak ID
+ string sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+ LPWSTR wTemp = CharToWChar( sTemp.c_str() );
+ m_pCurrentLeakElem->setAttribute( L"id", (const LPWSTR)wTemp );
+
+ // Print leak size
+ sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+ if( wTemp )
+ delete[] wTemp;
+ wTemp = CharToWChar( sTemp.c_str() );
+ m_pCurrentLeakElem->setAttribute( L"size", (const LPWSTR)wTemp );
+
+ // Print leak address
+ sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+ if( wTemp )
+ delete[] wTemp;
+ wTemp = CharToWChar( sTemp.c_str() );
+ m_pCurrentLeakElem->setAttribute( L"memaddress", (const LPWSTR)wTemp );
+
+ // Print leak time
+ sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+ if( wTemp )
+ delete[] wTemp;
+ wTemp = CharToWChar( sTemp.c_str() );
+ m_pCurrentLeakElem->setAttribute( L"time", (const LPWSTR)wTemp );
+
+ // Print leak module
+ sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+ if( wTemp )
+ delete[] wTemp;
+ wTemp = CharToWChar( sTemp.c_str() );
+ m_pCurrentLeakElem->setAttribute( L"module", (const LPWSTR)wTemp );
+ if( wTemp )
+ delete[] wTemp;
+ }
+ break;
+ case ITEM:
+ {
+ xercesc::DOMNode* callstackNode = NULL;
+
+ xercesc::DOMElement* callstackElem = NULL;
+
+ if( m_pCurrentLeakElem == NULL )
+ return;
+
+ // Print module name
+ if( !m_pCurrentLeakElem->hasChildNodes() )
+ {
+ callstackElem = m_pDomDoc->createElement( L"callstack" );
+ m_pCurrentLeakElem->appendChild( callstackElem );
+ callstackNode = callstackElem;
+ }
+ else
+ {
+ callstackNode = m_pCurrentLeakElem->getFirstChild();
+ }
+
+ // Add callstack item
+ xercesc::DOMElement* itemElem = m_pDomDoc->createElement( L"item" );
+ callstackNode->appendChild( itemElem );
+
+ // Print memory address name
+ string sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+ LPWSTR wTemp = CharToWChar( sTemp.c_str() );
+
+ itemElem->setAttribute( L"memaddress", (const LPWSTR)wTemp );
+
+ // Print calculated memory address
+ sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+ if( wTemp )
+ delete[] wTemp;
+ wTemp = CharToWChar( sTemp.c_str() );
+
+ itemElem->setAttribute( L"calc_addr", (const LPWSTR)wTemp );
+
+ // Print module name
+ sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+ if( wTemp )
+ delete[] wTemp;
+ wTemp = CharToWChar( sTemp.c_str() );
+
+ itemElem->setAttribute( L"module", (const LPWSTR)wTemp );
+
+ // Print function name
+ sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+ if( wTemp )
+ delete[] wTemp;
+ wTemp = CharToWChar( sTemp.c_str() );
+
+ itemElem->setAttribute( L"function", (const LPWSTR)wTemp );
+
+ sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+
+ // Print function line from urel build
+ if( !m_bUdebBuild )
+ {
+ if( wTemp )
+ delete[] wTemp;
+ wTemp = CharToWChar( sTemp.c_str() );
+ itemElem->setAttribute( L"function_line", (const LPWSTR)wTemp );
+ sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+ }
+
+ // Print file name
+ if( wTemp )
+ delete[] wTemp;
+ // Erase if path found from sTemp.
+ if ( sTemp.rfind( "/" ) != string::npos )
+ {
+ sTemp.erase(0, sTemp.rfind( "/" )+1 );
+ }
+ if ( sTemp.rfind( "\\" ) != string::npos )
+ {
+ sTemp.erase(0, sTemp.rfind( "\\" )+1 );
+ }
+ wTemp = CharToWChar( sTemp.c_str() );
+
+ itemElem->setAttribute( L"file", (const LPWSTR)wTemp );
+
+ // Print line of file
+ sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+ if( wTemp )
+ delete[] wTemp;
+ wTemp = CharToWChar( sTemp.c_str() );
+
+ if( m_bUdebBuild )
+ itemElem->setAttribute( L"line", (const LPWSTR)wTemp );
+ if( wTemp )
+ delete[] wTemp;
+ }
+ break;
+ case RUN_END:
+ {
+ if( m_pRunElement == NULL )
+ return;
+ const LPWSTR wTemp = CharToWChar( sInput.c_str() );
+ m_pRunElement->setAttribute( L"end_time", wTemp );
+ if( wTemp )
+ delete[] wTemp;
+ }
+ break;
+ case ERROR_IN_RUN:
+ {
+ if( m_pRunElement == NULL )
+ return;
+ // Add error item
+ xercesc::DOMElement* errorElem = m_pDomDoc->createElement( L"error" );
+ m_pRunElement->appendChild( errorElem );
+
+ // Print error code
+ string sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+ LPWSTR wTemp = CharToWChar( sTemp.c_str() );
+ errorElem->setAttribute( L"code", (const LPWSTR)wTemp );
+
+ // Print error time
+ sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+ if( wTemp )
+ delete[] wTemp;
+ wTemp = CharToWChar( sTemp.c_str() );
+ errorElem->setAttribute( L"time", (const LPWSTR)wTemp );
+ if( wTemp )
+ delete[] wTemp;
+ }
+ break;
+ case MEM_LEAKS:
+ {
+ if( m_pRunElement == NULL )
+ return;
+ xercesc::DOMElement* memoryLeaksElement = m_pDomDoc->createElement( L"mem_leaks" );
+ m_pRunElement->appendChild( memoryLeaksElement );
+ m_pMemoryLeaks = memoryLeaksElement;
+
+ // Print number of leaks
+ LPWSTR wTemp = CharToWChar( sInput.c_str() );
+ memoryLeaksElement->setAttribute( L"count", (const LPWSTR)wTemp );
+ if( wTemp )
+ delete[] wTemp;
+ }
+ break;
+ case MEM_LEAK_MODULE:
+ {
+ if( m_pMemoryLeaks == NULL )
+ return;
+ xercesc::DOMElement* moduleElement = m_pDomDoc->createElement( L"module" );
+ m_pMemoryLeaks->appendChild( moduleElement );
+
+ // Print module name
+ string sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+ LPWSTR wTemp = CharToWChar( sTemp.c_str() );
+ moduleElement->setAttribute( L"name", (const LPWSTR)wTemp );
+
+ if( wTemp )
+ delete[] wTemp;
+ // Print number of memory leaks
+ wTemp = CharToWChar( sInput.c_str() );
+ moduleElement->setAttribute( L"leaks", (const LPWSTR)wTemp );
+ if( wTemp )
+ delete[] wTemp;
+ }
+ break;
+ case HANDLE_LEAKS:
+ {
+ if( m_pRunElement == NULL )
+ return;
+ if( m_pHandleLeaks )
+ {
+ // Update number of leaks
+ LPWSTR wTemp = CharToWChar( sInput.c_str() );
+ m_pHandleLeaks->setAttribute( L"count", (const LPWSTR)wTemp );
+ if( wTemp )
+ delete[] wTemp;
+ }
+ else
+ {
+ xercesc::DOMElement* handleLeaksElement = m_pDomDoc->createElement( L"handle_leaks" );
+ m_pRunElement->appendChild( handleLeaksElement );
+ m_pHandleLeaks = handleLeaksElement;
+
+ // Print number of leaks
+ LPWSTR wTemp = CharToWChar( sInput.c_str() );
+ handleLeaksElement->setAttribute( L"count", (const LPWSTR)wTemp );
+ if( wTemp )
+ delete[] wTemp;
+ }
+ }
+ break;
+ case HANDLE_LEAK_MODULE:
+ {
+ if( m_pHandleLeaks == NULL )
+ return;
+ xercesc::DOMElement* moduleElement = m_pDomDoc->createElement( L"module" );
+ m_pHandleLeaks->appendChild( moduleElement );
+
+ // Print module name
+ string sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+ LPWSTR wTemp = CharToWChar( sTemp.c_str() );
+ moduleElement->setAttribute( L"name", (const LPWSTR)wTemp );
+ if( wTemp )
+ delete[] wTemp;
+
+ // Print number of memory leaks
+ wTemp = CharToWChar( sInput.c_str() );
+ moduleElement->setAttribute( L"leaks", (const LPWSTR)wTemp );
+ if( wTemp )
+ delete[] wTemp;
+ }
+ break;
+ case TEST_START:
+ {
+ m_pCurrentSubTestElem = m_pDomDoc->createElement( L"subtest" );
+
+ if( m_pCurrentSubTestElem == NULL || m_pRunElement == NULL )
+ return;
+
+ m_pRunElement->appendChild( m_pCurrentSubTestElem );
+
+ // Print sub test name
+ string sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+ LPWSTR wTemp = CharToWChar( sTemp.c_str() );
+ m_pCurrentSubTestElem->setAttribute( L"name", (const LPWSTR)wTemp );
+ if( wTemp )
+ {
+ delete[] wTemp;
+ wTemp = NULL;
+ }
+
+ // Print sub test time
+ sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+ wTemp = CharToWChar( sTemp.c_str() );
+ m_pCurrentSubTestElem->setAttribute( L"start_time", (const LPWSTR)wTemp );
+ if( wTemp )
+ delete[] wTemp;
+ break;
+ }
+ case TEST_END:
+ {
+ if( m_pCurrentSubTestElem == NULL )
+ return;
+ // Print end time
+ string sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+ LPWSTR wTemp = CharToWChar( sTemp.c_str() );
+ m_pCurrentSubTestElem->setAttribute( L"end_time", (const LPWSTR)wTemp );
+ m_pCurrentSubTestElem = NULL;
+ if( wTemp )
+ delete[] wTemp;
+ break;
+ }
+ case SUBTEST_MEM_LEAKS:
+ {
+ if( m_pCurrentSubTestElem == NULL )
+ return;
+ xercesc::DOMElement* memoryLeaksElement = m_pDomDoc->createElement( L"mem_leaks" );
+ m_pCurrentSubTestElem->appendChild( memoryLeaksElement );
+ m_pSubtestMemoryLeaks = memoryLeaksElement;
+
+ // Print number of leaks
+ LPWSTR wTemp = CharToWChar( sInput.c_str() );
+ memoryLeaksElement->setAttribute( L"count", (const LPWSTR)wTemp );
+ if( wTemp )
+ delete[] wTemp;
+ break;
+ }
+ case SUBTEST_MEM_LEAK_MODULE:
+ {
+ if( m_pSubtestMemoryLeaks == NULL )
+ return;
+ xercesc::DOMElement* moduleElement = m_pDomDoc->createElement( L"module" );
+ m_pSubtestMemoryLeaks->appendChild( moduleElement );
+
+ // Print module name
+ string sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+ LPWSTR wTemp = CharToWChar( sTemp.c_str() );
+ moduleElement->setAttribute( L"name", (const LPWSTR)wTemp );
+
+ if( wTemp )
+ delete[] wTemp;
+ // Print number of memory leaks
+ wTemp = CharToWChar( sInput.c_str() );
+ moduleElement->setAttribute( L"leaks", (const LPWSTR)wTemp );
+ if( wTemp )
+ delete[] wTemp;
+ break;
+ }
+ case SUBTEST_HANDLE_LEAKS:
+ {
+ if( m_pCurrentSubTestElem == NULL )
+ return;
+ xercesc::DOMElement* handleLeaksElement = m_pDomDoc->createElement( L"handle_leaks" );
+ m_pCurrentSubTestElem->appendChild( handleLeaksElement );
+
+ //Print number of handle leaks
+ string sTemp = GetStringUntilNextGivenChar( sInput, ';' );
+ LPWSTR wTemp = CharToWChar( sTemp.c_str() );
+ handleLeaksElement->setAttribute( L"count", (const LPWSTR)wTemp );
+ if( wTemp )
+ delete[] wTemp;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ catch( ... )
+ {
+ printf( "Error when writing data to XML file." );
+ }
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::GetStringUntilNextGivenChar
+// Function returns string from begin of given string until next given char,
+// characters until given char are removed from sInput string.
+// -----------------------------------------------------------------------------
+string CATDataSaver::GetStringUntilNextGivenChar( string& sInput, char cCharacter )
+{
+ LOG_LOW_FUNC_ENTRY("CATDataSaver::GetStringUntilNextGivenChar");
+ string sRet;
+ size_t iPos = sInput.find( cCharacter );
+ if( sInput.size() > 1 && iPos != string::npos )
+ {
+ sRet = sInput.substr( 0, iPos );
+ sInput.erase( 0, (iPos + 1) );
+ }
+ return sRet;
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::SetBuild
+// Function sets build target info.
+// -----------------------------------------------------------------------------
+void CATDataSaver::SetBuild( bool bUdebBuild )
+{
+ LOG_FUNC_ENTRY("CATDataSaver::SetBuild");
+ m_bUdebBuild = bUdebBuild;
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::AddCarbideData
+// Function adds string to Carbide data.
+// -----------------------------------------------------------------------------
+void CATDataSaver::AddCarbideData( const string& sInput )
+{
+ LOG_LOW_FUNC_ENTRY("CATDataSaver::AddCarbideData");
+ m_sCarbideDataLine.append( sInput );
+ m_sCarbideDataLine.append(";");
+}
+
+// -----------------------------------------------------------------------------
+// CATDataSaver::IntegerToString
+// Converts integer to string.
+// -----------------------------------------------------------------------------
+string CATDataSaver::IntegerToString( int iValueToConvert )
+{
+ LOG_LOW_FUNC_ENTRY("CATDataSaver::IntegerToString");
+ char cTemp[128];
+ string sValue( itoa( iValueToConvert, cTemp, 10 ) );
+ return sValue;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/CATMemoryAddress.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,307 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Class representing a memory address and its details.
+*
+*/
+
+
+#include "../inc/CATMemoryAddress.h"
+#include "../inc/CATBase.h"
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::CATMemoryAddress
+// Constructor
+// -----------------------------------------------------------------------------
+CATMemoryAddress::CATMemoryAddress(string& sAddress, unsigned long iOffSet)
+{
+ LOG_LOW_FUNC_ENTRY("CATMemoryAddress::CATMemoryAddress");
+ m_sAddress = sAddress;
+ m_sFileName = "";
+ m_sFunctionName = "";
+ m_sModuleName = "";
+ m_iAddress = CATBase::_httoi( sAddress.c_str() );
+ m_iDllLoadinfoIndex = -1;
+ m_iModuleStartAddress = 0;
+ m_iOffSetFromModuleStart = 0;
+ m_iExactLineNumber = -1;
+ m_iFunctionLineNumber = -1;
+ m_ePinPointState = OUT_OF_PROCESS;
+ m_iOffSet = iOffSet;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::~CATMemoryAddress
+// Destructor.
+// -----------------------------------------------------------------------------
+CATMemoryAddress::~CATMemoryAddress()
+{
+ LOG_LOW_FUNC_ENTRY("CATMemoryAddress::~CATMemoryAddress");
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::FindSetModuleName
+// Find which binary this address belongs to.
+// Sets also the offsetfrommodulestart.
+// -----------------------------------------------------------------------------
+bool CATMemoryAddress::FindSetModuleName(vector<DLL_LOAD_INFO>* vDlls)
+{
+ LOG_LOW_FUNC_ENTRY("CATMemoryAddress::FindSetModuleName");
+ vector<DLL_LOAD_INFO>::iterator it;
+ for ( it = vDlls->begin() ;
+ it != vDlls->end(); it++ )
+ {
+ // Is modules load time defined?
+ if ( (*it).iLoadTime > 0 )
+ {
+ // Check that load time is earlier or same as allocation
+ if ( m_iTime >= (*it).iLoadTime
+ && m_iAddress >= (*it).iStartAddress
+ && m_iAddress < (*it).iEndAddress )
+ {
+ // Module is loaded until process end.
+ if ( (*it).iUnloadTime == 0 )
+ break;
+ // Check is allocation done before module was unloaded.
+ else if ( (*it).iUnloadTime >= m_iTime )
+ break;
+ }
+ }
+ // Module has no time defined use only code segments.
+ else
+ {
+ if ( m_iAddress >= (*it).iStartAddress
+ && m_iAddress < (*it).iEndAddress )
+ break;
+ }
+ }
+
+ // Did we not find module where address is?
+ if ( it == vDlls->end() )
+ return false;
+
+ m_ePinPointState = OUT_OF_RANGE;
+ m_sModuleName = (*it).sModuleName;
+ m_iModuleStartAddress = (*it).iStartAddress;
+ m_iOffSetFromModuleStart = m_iAddress - m_iModuleStartAddress;
+ m_iOffSetFromModuleStart += m_iOffSet;
+ m_iDllLoadinfoIndex = distance( vDlls->begin(), it ) ;
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::SetModuleStartAddress
+// Set start address of the binary in which address resides.
+// Note, this also sets the offset from start value.
+// -----------------------------------------------------------------------------
+void CATMemoryAddress::SetModuleStartAddress(unsigned long iAddress)
+{
+ LOG_LOW_FUNC_ENTRY("CATMemoryAddress::SetModuleStartAddress");
+ m_iModuleStartAddress = iAddress;
+ m_iOffSetFromModuleStart = m_iAddress - m_iModuleStartAddress;
+ m_iOffSetFromModuleStart += m_iOffSet;
+}
+
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::GetOffSetFromModuleStart
+// Note return value includes the set offset.
+// So this value is not binary start - address.
+// Instead it is.
+// memory address - binary start address + offset
+// -----------------------------------------------------------------------------
+unsigned long CATMemoryAddress::GetOffSetFromModuleStart()
+{
+ LOG_LOW_FUNC_ENTRY("CATMemoryAddress::GetOffSetFromModuleStart");
+ return m_iOffSetFromModuleStart;
+}
+
+int CATMemoryAddress::GetDllLoadInfoIndex()
+{
+ LOG_LOW_FUNC_ENTRY("CATMemoryAddress::GetDllLoadInfo");
+ return m_iDllLoadinfoIndex;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::SetTime
+// -----------------------------------------------------------------------------
+void CATMemoryAddress::SetTime( unsigned long long& ullTime )
+{
+ LOG_LOW_FUNC_ENTRY("CATMemoryAddress::SetTime");
+ m_iTime = ullTime;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::GetTIme
+// -----------------------------------------------------------------------------
+unsigned long long CATMemoryAddress::GetTime()
+{
+ LOG_LOW_FUNC_ENTRY("CATMemoryAddress::GetTime");
+ return m_iTime;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::SetAddress
+// -----------------------------------------------------------------------------
+void CATMemoryAddress::SetAddress(string& sAddress)
+{
+ LOG_LOW_FUNC_ENTRY("CATMemoryAddress::SetAddress");
+ m_sAddress = sAddress;
+ m_iAddress = CATBase::_httoi( sAddress.c_str() );
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::GetAddressString
+// -----------------------------------------------------------------------------
+string CATMemoryAddress::GetAddressString()
+{
+ LOG_LOW_FUNC_ENTRY("CATMemoryAddress::GetAddressString");
+ return m_sAddress;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::SetAddress
+// -----------------------------------------------------------------------------
+void CATMemoryAddress::SetAddress(unsigned long iAddress)
+{
+ LOG_LOW_FUNC_ENTRY("CATMemoryAddress::SetAddress");
+ m_iAddress = iAddress;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::GetAddress
+// -----------------------------------------------------------------------------
+unsigned long CATMemoryAddress::GetAddress()
+{
+ LOG_LOW_FUNC_ENTRY("CATMemoryAddress::GetAddress");
+ return m_iAddress;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::SetModuleName
+// -----------------------------------------------------------------------------
+void CATMemoryAddress::SetModuleName(string& sModuleName)
+{
+ LOG_LOW_FUNC_ENTRY("CATMemoryAddress::SetModuleName");
+ m_sModuleName = sModuleName;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::GetModuleName
+// -----------------------------------------------------------------------------
+string CATMemoryAddress::GetModuleName()
+{
+ LOG_LOW_FUNC_ENTRY("CATMemoryAddress::GetModuleName");
+ return m_sModuleName;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::SetAddressToLineState
+// -----------------------------------------------------------------------------
+void CATMemoryAddress::SetAddressToLineState( ADDRESS_TO_LINE_STATE eState )
+{
+ LOG_LOW_FUNC_ENTRY("CATMemoryAddress::SetAddressToLineState");
+ m_ePinPointState = eState;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::GetAddressToLineState
+// -----------------------------------------------------------------------------
+int CATMemoryAddress::GetAddressToLineState()
+{
+ LOG_LOW_FUNC_ENTRY("CATMemoryAddress::GetAddressToLineState");
+ return m_ePinPointState;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::SetFileName
+// -----------------------------------------------------------------------------
+void CATMemoryAddress::SetFileName(string& sFileName)
+{
+ LOG_LOW_FUNC_ENTRY("CATMemoryAddress::SetFileName");
+ m_sFileName = sFileName;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::GetFileName
+// -----------------------------------------------------------------------------
+string CATMemoryAddress::GetFileName()
+{
+ LOG_LOW_FUNC_ENTRY("CATMemoryAddress::GetFileName");
+ return m_sFileName;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::SetFunctionName
+// -----------------------------------------------------------------------------
+void CATMemoryAddress::SetFunctionName(string& sFunctionName)
+{
+ LOG_LOW_FUNC_ENTRY("CATMemoryAddress::SetFunctionName");
+ m_sFunctionName = sFunctionName;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::GetFunctionName
+// -----------------------------------------------------------------------------
+string CATMemoryAddress::GetFunctionName()
+{
+ LOG_LOW_FUNC_ENTRY("CATMemoryAddress::GetFunctionName");
+ return m_sFunctionName;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::SetFunctionLineNumber
+// -----------------------------------------------------------------------------
+void CATMemoryAddress::SetFunctionLineNumber(int iFunctionLineNumber)
+{
+ LOG_LOW_FUNC_ENTRY("CATMemoryAddress::SetFunctionLineNumber");
+ m_iFunctionLineNumber = iFunctionLineNumber;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::GetFunctionLineNumber
+// -----------------------------------------------------------------------------
+int CATMemoryAddress::GetFunctionLineNumber()
+{
+ LOG_LOW_FUNC_ENTRY("CATMemoryAddress::GetFunctionLineNumber");
+ return m_iFunctionLineNumber;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::SetExactLineNumber
+// -----------------------------------------------------------------------------
+void CATMemoryAddress::SetExactLineNumber(int iExactLineNumber)
+{
+ LOG_LOW_FUNC_ENTRY("CATMemoryAddress::SetExactLineNumber");
+ m_iExactLineNumber = iExactLineNumber;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::GetExactLineNumber
+// -----------------------------------------------------------------------------
+int CATMemoryAddress::GetExactLineNumber()
+{
+ LOG_LOW_FUNC_ENTRY("CATMemoryAddress::GetExactLineNumber");
+ return m_iExactLineNumber;
+}
+
+// -----------------------------------------------------------------------------
+// CATMemoryAddress::GetModuleStartAddress
+// -----------------------------------------------------------------------------
+unsigned long CATMemoryAddress::GetModuleStartAddress() const
+{
+ LOG_LOW_FUNC_ENTRY("CATMemoryAddress::GetModuleStartAddress");
+ return m_iModuleStartAddress;
+}
+
+//EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/CATMmp.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,396 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Class responsible of handling mmp files.
+*
+*/
+
+
+#include "../inc/CATMmp.h"
+
+CATMmp::CATMmp()
+{
+ LOG_FUNC_ENTRY("CATMmp::CATMmp");
+}
+
+CATMmp::~CATMmp()
+{
+ LOG_FUNC_ENTRY("CATMmp::~CATMmp");
+}
+
+// -----------------------------------------------------------------------------
+// CATMmp::IsMmpEdited
+// Checks is the file edited by AT
+// -----------------------------------------------------------------------------
+bool CATMmp::IsMmpEdited( bool bBackup)
+{
+ LOG_FUNC_ENTRY("CATMmp::IsMmpEdited");
+ // Stream to read file
+ ifstream in;
+ // Temp char array to read line
+ char cTemp[MAX_LINE_LENGTH];
+ // Open file
+ if ( bBackup )
+ in.open( CreateMmpBackupPath().c_str() );
+ else
+ in.open( m_sMmpFile.c_str() );
+ // Is file open ok
+ if( ! in.good() )
+ {
+ cout << AT_MSG << "Error, can not open file "
+ << m_sMmpFile << endl;
+ in.close();
+ return false;
+ }
+ // Search edit start line
+ bool bEdited=false;
+ const char* cFind = MMPFILECHANGES[0].c_str();
+ while( ! bEdited && in.good() )
+ {
+ // Get line
+ in.getline( cTemp, MAX_LINE_LENGTH );
+ // Compare to first line in changes
+ if ( strstr( cTemp, cFind) )
+ {
+ bEdited = true;
+ // Stop looking any further
+ break;
+ }
+ }
+ // Close file and return result
+ in.close();
+ return bEdited;
+}
+
+// -----------------------------------------------------------------------------
+// CATMmp::EditMmpFile
+// Makes AnalyzeTool changes to given mmp file
+// -----------------------------------------------------------------------------
+bool CATMmp::EditMmpFile(const string& sTargetType, const string& sId)
+{
+ LOG_FUNC_ENTRY("CATMmp::EditMmpFile");
+
+ if ( ! RemoveWriteProtections() )
+ return false;
+
+ // Stream where to add changes
+ ofstream out;
+
+ // Open mmp file for editing (append changes to the end)
+ out.open( m_sMmpFile.c_str(), ios::out | ios::app );
+
+ // File open ok?
+ if( !out.good() )
+ {
+ cout << AT_MSG << "Error, can not open file "
+ << m_sMmpFile;
+ out.close();
+ return false;
+ }
+
+ // Write lines to mmp file
+ if ( sTargetType.compare( "dll" ) == 0 || sTargetType.compare( "lib" ) == 0 )
+ {
+ // DLL changes
+ int size = sizeof( MMPFILECHANGES_DLL ) / sizeof( string );
+ for( int i = 0; i < size; i++ )
+ {
+ out << endl << MMPFILECHANGES_DLL[i];
+ }
+ out << endl;
+ }
+ else
+ {
+ // Other than DLL changes
+ int size = sizeof( MMPFILECHANGES ) / sizeof( string );
+ for( int i = 0; i < size; i++ )
+ {
+ // After second line of changes add also source statement
+ out << endl << MMPFILECHANGES[i];
+ if ( i == 1 )
+ {
+ out << endl
+ << "SOURCE "
+ << AT_TEMP_CPP_LOWER_START
+ << sId
+ << AT_TEMP_CPP_LOWER_END;
+ }
+ }
+ out << endl;
+ }
+ // Close stream
+ out.close();
+
+ cout << AT_MSG << "Mmp file : " << m_sMmpFile << " edited." << endl;
+
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATMmp::BackupMmpFile
+// Backups the mmp file to path/atool_temp/filename.mmp.tmp
+// Calling this function results always to
+// - none edited mmp
+// - none edited backup
+// - If mmp is write protected. Create writable copy from it. Backup the write
+// procted one.
+// -----------------------------------------------------------------------------
+bool CATMmp::BackupMmpFile( )
+{
+ LOG_FUNC_ENTRY("CATMmp::BackupMmpFile");
+
+ if ( ! RemoveWriteProtections() )
+ return false;
+
+ // Backup path+filename
+ string sBackup = CreateMmpBackupPath();
+
+ // Backup mmp.
+ if ( CopyFile( m_sMmpFile.c_str() , sBackup.c_str(), false ) == 0 )
+ {
+ // Log and return false if failed to copy file
+ LOG_STRING( "error copyfile " << m_sMmpFile << " to " << sBackup );
+ return false;
+ }
+
+ // If backup now edited remove changes from it.
+ if ( IsMmpEdited( true ) )
+ {
+ if ( ! RemoveMmpFileChanges( true ) )
+ return false;
+ }
+
+ return true;
+}
+// -----------------------------------------------------------------------------
+// CATMmp::RestoreMmpFile
+// Restores the mmp file from backup
+// -----------------------------------------------------------------------------
+bool CATMmp::RestoreMmpFile()
+{
+ LOG_FUNC_ENTRY("CATMmp::RestoreMmpFile");
+
+ if ( ! RemoveWriteProtections() )
+ return false;
+
+ if ( CopyFile( CreateMmpBackupPath().c_str() , m_sMmpFile.c_str(), false ) == 0 )
+ {
+ // Log and return false if failed to copy file
+ LOG_STRING("error copyfile " << CreateMmpBackupPath() << " to " << m_sMmpFile );
+ return false;
+ }
+ else
+ cout << AT_MSG << "Mmp file : " << m_sMmpFile << " restored." << endl;
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATMmp::RemoveMmpFileChanges
+// Removes AT changes from given mmp file
+// -----------------------------------------------------------------------------
+bool CATMmp::RemoveMmpFileChanges(bool bBackup)
+{
+ LOG_FUNC_ENTRY("CATMmp::RemoveMmpFileChanges");
+
+ if ( ! RemoveWriteProtections() )
+ return false;
+
+ // File reading stream
+ ifstream in;
+ // Vector to hold file data
+ vector<string> vLines;
+ // Open file
+ if ( bBackup )
+ in.open( CreateMmpBackupPath().c_str(), ios::in );
+ else
+ in.open( m_sMmpFile.c_str(), ios::in );
+ // Check file open ok
+ if ( ! in.good() )
+ {
+ cout << AT_MSG << "Error, opening file";
+ if ( bBackup )
+ cout << CreateMmpBackupPath();
+ else
+ cout << m_sMmpFile;
+ cout << endl;
+ return false;
+ }
+ // Read file to temporary stream except AT changes
+ char cLine[MAX_LINE_LENGTH];
+ // Boolean to know read or not
+ bool bRead = true;
+ // Integer to confirm that AT changes were succefully found and
+ // not read even if they are found multiple times
+ int iSuccessfull = 0;
+ // Number of 'lines' in mmp changes
+ int iChangesSize = sizeof( MMPFILECHANGES ) / sizeof( string );
+ // First mmp changes line
+ string sFirstLine = MMPFILECHANGES[0];
+ // Last mmp changes line
+ string sLastLine = MMPFILECHANGES[iChangesSize-1];
+ while( in.good() )
+ {
+ in.getline( cLine, MAX_LINE_LENGTH );
+ // Check start of AT changes
+ if( strstr( cLine, sFirstLine.c_str() ) != 0 )
+ {
+ // Remove last linefeed
+ vector<string>::iterator it = vLines.end();
+ it--;
+ if ( it->size() == 0 )
+ vLines.erase( vLines.end()-1, vLines.end() );
+ // Stop reading
+ bRead = false;
+ iSuccessfull+=3;
+ }
+ // Read lines outside AT changes
+ if ( bRead )
+ {
+ // Gather all other lines except the AT edits
+ vLines.push_back( string(cLine) );
+ }
+ // Check end of AT changes
+ if( strstr( cLine, sLastLine.c_str() ) != 0 )
+ {
+ // Get empty line
+ in.getline( cLine, MAX_LINE_LENGTH );
+ // Continue reading
+ bRead = true;
+ iSuccessfull-=1;
+ }
+ }
+ // Close reading file stream
+ in.close();
+ // To check all went ok iSuccesfull%2 = 0
+ if ( iSuccessfull%2 != 0 && iSuccessfull >= 2 )
+ {
+ cout << AT_MSG << "Error, removing mmp changes from ";
+ if ( bBackup )
+ cout << CreateMmpBackupPath();
+ else
+ cout << m_sMmpFile;
+ cout << endl;
+ return false;
+ }
+ // Overwrite current mmp file
+ ofstream out;
+ // Open file (truncates old data)
+ if ( bBackup )
+ out.open( CreateMmpBackupPath().c_str(), ios::trunc );
+ else
+ out.open( m_sMmpFile.c_str(), ios::trunc );
+ // Is open ok
+ if( ! out.good() )
+ {
+ cout << AT_MSG << "Error, opening file ";
+ if ( bBackup )
+ cout << CreateMmpBackupPath();
+ else
+ cout << m_sMmpFile;
+ cout << endl;
+ }
+ // Write lines to file
+ for( vector<string>::iterator it = vLines.begin() ; it != vLines.end() ; it++ )
+ {
+ out << *it << endl;
+ }
+ // Close
+ out.close();
+ // Return true
+ return true;
+}
+// -----------------------------------------------------------------------------
+// CATMmp::VerifyAndRecover
+// Wont change mmp if it is not edited
+// Replaces mmp file using backup if it exists and it is
+// not edited otherwise removes changes from mmp file.
+// -----------------------------------------------------------------------------
+bool CATMmp::VerifyAndRecover()
+{
+ LOG_FUNC_ENTRY("CATMmp::VerifyAndRecover");
+ // Is it edited
+ if ( IsMmpEdited() )
+ {
+ string sBackup = CreateMmpBackupPath();
+ if ( FileExists( sBackup.c_str() ) )
+ {
+ // Is backup edited
+ if ( ! IsMmpEdited( true ) )
+ {
+ // Replace original with backup
+ return RestoreMmpFile();
+ }
+ }
+ // Remove changes from original
+ return RemoveMmpFileChanges();
+ }
+ // Non edited original
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATMmp::CreateMmpBackupPath
+// Creates string containing full path to backup mmp file
+// -----------------------------------------------------------------------------
+string CATMmp::CreateMmpBackupPath()
+{
+ LOG_FUNC_ENTRY("CATMmp::CreateMmpBackupPath");
+ // backup path+filename
+ string sBackup;
+ sBackup.append( GetPathOrFileName( false, m_sMmpFile ) );
+ sBackup.append( AT_TEMP_DIR );
+ sBackup.append( "\\" );
+ // Add mmp file name to it and .tmp
+ sBackup.append( GetPathOrFileName( true, m_sMmpFile ) );
+ // Add .tmp
+ sBackup.append( ".tmp" );
+ // Return it
+ return sBackup;
+}
+
+// -----------------------------------------------------------------------------
+// CATMmp::RemoveWriteProtections
+// Removes write protection of mmp file and backup if exists.
+// -----------------------------------------------------------------------------
+bool CATMmp::RemoveWriteProtections()
+{
+ LOG_LOW_FUNC_ENTRY("CATMmp::RemoveWriteProtections");
+
+ // Backup path+filename
+ string sBackup = CreateMmpBackupPath();
+
+ // Check is mmp read-only
+ if ( IsFileReadOnly( m_sMmpFile.c_str() ) )
+ {
+ if( ! SetFileWritable( m_sMmpFile.c_str() ) )
+ {
+ LOG_STRING( "error setting mmp file writable" << m_sMmpFile );
+ return false;
+ }
+ }
+
+ // Check is there a backup if is remove any write protection from it.
+ if ( FileExists( sBackup.c_str() ) )
+ {
+ if ( IsFileReadOnly( sBackup.c_str() ) )
+ {
+ if( ! SetFileWritable( sBackup.c_str() ) )
+ {
+ LOG_STRING( "error setting mmp file writable" << sBackup );
+ return false;
+ }
+ }
+ }
+ return true;
+}
+// End of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/CATModule2.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,1634 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Class representing a module in project (sbs2)
+*
+*/
+
+
+#include "../inc/CATModule2.h"
+#include "../inc/CATProject.h"
+#include "../inc/CATDatParser.h"
+#include "../inc/CATMemoryAddress.h"
+#include "../inc/catdbghelper.h"
+#include "../inc/cataddr2line.h"
+
+CATModule2::CATModule2(void)
+{
+ LOG_FUNC_ENTRY("CATModule2::CATModule2");
+ m_bAddressToLineInitialized = false;
+ m_pAddressToLine = 0;
+ m_sErrors = "";
+ m_sMakeFile = "";
+ m_eBuildSystem = CATProject::SBS_V1;
+ m_sCompileInfoText = "";
+}
+
+CATModule2::~CATModule2(void)
+{
+ LOG_FUNC_ENTRY("CATModule2::~CATModule2");
+ if ( m_pAddressToLine )
+ m_pAddressToLine->Close();
+ delete m_pAddressToLine;
+}
+
+bool CATModule2::AddressToLine( CATMemoryAddress* pMemoryAddress )
+{
+ LOG_FUNC_ENTRY("CATModule2::AddressToLine");
+ if ( _stricmp( m_sVariantPlatform.c_str(), "winscw" ) == 0 )
+ {
+ return AddressToLineWinscw( pMemoryAddress );
+ }
+ else if ( _stricmp( m_sVariantPlatform.c_str(), "armv5" ) == 0 )
+ {
+ // addr2line exe.
+ #ifdef ADDR2LINE
+ return AddressToLineAddr2lineExe( pMemoryAddress );
+ #endif
+ // lst and map files.
+ #ifndef ADDR2LINE
+ return AddressToLineArmv5( pMemoryAddress );
+ #endif
+ }
+ else if ( _stricmp( m_sVariantPlatform.c_str(), "gcce" ) == 0 )
+ {
+ return AddressToLineAddr2lineExe( pMemoryAddress );
+ }
+ return false;
+}
+
+bool CATModule2::AddressToLineWinscw( CATMemoryAddress* pMemoryAddress )
+{
+ LOG_FUNC_ENTRY("CATModule2::AddressToLineWinscw( CATMemoryAddress* pMemoryAddress )");
+ if ( m_pAddressToLine == 0 && ! m_bAddressToLineInitialized )
+ {
+ // Use debug helper to locate codelines on winscw platform.
+ m_pAddressToLine = new CATDbgHelper();
+
+ // Create full path to binary which we open using CATDbgHelper.
+ string sFullPathToBinary = GetBinaryFile();
+
+ // If opening of binary not succesfull set return value to false.
+ if ( ! m_pAddressToLine->Open( sFullPathToBinary, pMemoryAddress->GetModuleStartAddress() ) )
+ {
+ LOG_STRING("Error, m_pAddressToLine->Open()");
+ return false;
+ }
+ m_bAddressToLineInitialized = true;
+ }
+ // Check pointer before calling.
+ if ( m_pAddressToLine == 0 )
+ return false;
+ m_pAddressToLine->AddressToLine( pMemoryAddress );
+ return true;
+}
+
+bool CATModule2::AddressToLineArmv5( CATMemoryAddress* pMemoryAddress )
+{
+ LOG_FUNC_ENTRY("CATModule2::AddressToLine( CATMemoryAddress* pMemoryAddress )");
+ if ( ! m_bAddressToLineInitialized )
+ return false;
+ // Find from map file
+ int iMapIndex = GetSymbolIndexUsingAddress( pMemoryAddress->GetOffSetFromModuleStart() );
+ if ( iMapIndex == -1 )
+ {
+ pMemoryAddress->SetAddressToLineState( CATMemoryAddress::OUT_OF_RANGE );
+ return true;
+ }
+ // Set symbol name
+ string sSymbolName = m_vMapFileFuncList.at( iMapIndex ).sFunctionName;
+
+ // Remove (... from symbol name
+ string sSymbolNameRefined( sSymbolName );
+ size_t iPos = sSymbolNameRefined.find( "(" );
+ if ( iPos != string::npos )
+ sSymbolNameRefined.resize( iPos );
+
+ // Set symbol name as function name for memory address
+ pMemoryAddress->SetFunctionName( sSymbolNameRefined );
+
+ // Set state to symbol
+ pMemoryAddress->SetAddressToLineState( CATMemoryAddress::SYMBOL );
+
+ // Offset from function start addr
+ int iOffSetFromFuncStart = pMemoryAddress->GetOffSetFromModuleStart()
+ - m_vMapFileFuncList.at( iMapIndex ).iAddress;
+
+ // Find from lst list
+ int iLstIndex = GetLineInFileIndexUsingSymbolName( sSymbolName );
+ if ( iLstIndex == -1 )
+ return true;
+
+ // Set pinpointing
+ int iFuncLineNumber = m_vLineInFile.at( iLstIndex ).iLine;
+ string sFileName = m_vLineInFile.at( iLstIndex ).sFileName;
+ string sLstFileName = m_vLineInFile.at( iLstIndex ).sLstName;
+
+ pMemoryAddress->SetFunctionLineNumber( iFuncLineNumber );
+ pMemoryAddress->SetFileName( sFileName );
+
+ pMemoryAddress->SetAddressToLineState( CATMemoryAddress::FUNCTION );
+
+ // In urel mode don't get exact code line
+ if ( ! IsUDEB() )
+ return true;
+
+ // Next calculate the code line inside function
+ int iExactLineNumber = FindLeakCodeLine( sLstFileName, iFuncLineNumber, iOffSetFromFuncStart );
+ pMemoryAddress->SetExactLineNumber( iExactLineNumber );
+
+ // State is now exact
+ pMemoryAddress->SetAddressToLineState( CATMemoryAddress::EXACT );
+ return true;
+}
+
+bool CATModule2::AddressToLineAddr2lineExe( CATMemoryAddress* pMemoryAddress )
+{
+ LOG_FUNC_ENTRY("CATModule2::AddressToLineAddr2lineExe( CATMemoryAddress* pMemoryAddress )");
+ if ( m_pAddressToLine == 0 && ! m_bAddressToLineInitialized )
+ {
+ // Use addr2line.exe to locate codelines on armv5 and gcce platform.
+ m_pAddressToLine = new CATAddr2line();
+
+ // Create full path to binary .sym file which we open using addr2line.exe.
+ string sFullPathToBinary = GetBinaryFile();
+
+ // If opening of binary not succesfull set return value to false.
+ if ( ! m_pAddressToLine->Open( sFullPathToBinary, pMemoryAddress->GetModuleStartAddress() ) )
+ {
+ LOG_STRING("Error, m_pAddressToLine->Open()");
+ return false;
+ }
+ m_bAddressToLineInitialized = true;
+ }
+ // Check pointer before calling.
+ if ( m_pAddressToLine == 0 )
+ return false;
+
+ m_pAddressToLine->AddressToLine( pMemoryAddress );
+ return true;
+}
+
+// Find symbol of given address
+int CATModule2::GetSymbolIndexUsingAddress( unsigned long iAddress ) const
+{
+ LOG_LOW_FUNC_ENTRY("CATModule2::GetSymbolIndexUsingAddress");
+ for( size_t i = 0; i < m_vMapFileFuncList.size(); i++ )
+ {
+ unsigned long iStart = m_vMapFileFuncList.at( i ).iAddress;
+ unsigned long iEnd = ( m_vMapFileFuncList.at( i ).iAddress
+ + m_vMapFileFuncList.at( i ).iFuncLength );
+
+ if ( iAddress >= iStart && iAddress < iEnd )
+ return (int) i;
+ }
+ return -1;
+}
+
+// Find index of function line in file vector of given symbolname
+int CATModule2::GetLineInFileIndexUsingSymbolName( const string& sSymbolName ) const
+{
+ LOG_LOW_FUNC_ENTRY("CATModule2::GetLineInFileIndexUsingSymbolName");
+ for( size_t i = 0; i < m_vLineInFile.size(); i++ )
+ {
+ string sLineInFileName = m_vLineInFile.at( i ).sFunction;
+ if( sLineInFileName.find( sSymbolName ) != string::npos )
+ {
+ return (int) i;
+ }
+ }
+ return -1;
+}
+
+
+// Check does modules symbol file(s) exist.
+bool CATModule2::SymbolFileExist( void )
+{
+ LOG_FUNC_ENTRY("CATModule2::SymbolFileExist");
+ string sFullPathToSym = GetSymbolFile();
+ if ( !FileExists( sFullPathToSym.c_str() ) )
+ {
+ // Add missing symbol file to error string.
+ m_sErrors.append( "Missing symbol file: " );
+ m_sErrors.append( sFullPathToSym );
+ m_sErrors.append( "\n" );
+ return false;
+ }
+ return true;
+}
+
+// Check does modules map file(s) exists.
+bool CATModule2::MapFileExist( void )
+{
+ LOG_FUNC_ENTRY("CATModule2::MapFileExist");
+ string sFullPathToMap = GetMapFile();
+ if ( !FileExists( sFullPathToMap.c_str() ) )
+ {
+ // Add missing symbol file to error string.
+ m_sErrors.append( "Missing map file: " );
+ m_sErrors.append( sFullPathToMap );
+ m_sErrors.append( "\n" );
+ return false;
+ }
+ return true;
+}
+
+//Check does modules binary file(s) exist.
+bool CATModule2::BinaryFileExist( void )
+{
+ LOG_FUNC_ENTRY("CATModule2::BinaryFileExist");
+ string sFullPathToBinary = GetBinaryFile();
+ if ( ! FileExists( sFullPathToBinary.c_str() ) )
+ {
+ // Add missing binary to error string.
+ m_sErrors.append( "Missing binary file: " );
+ m_sErrors.append( sFullPathToBinary );
+ m_sErrors.append( "\n" );
+ return false;
+ }
+ return true;
+}
+
+void CATModule2::AddSource(const string &sSourceFile, const string& sLstFile)
+{
+ LOG_LOW_FUNC_ENTRY("CATModule2::AddSource");
+ // Parse sources which are separated by spaces
+ if( sSourceFile.length() < 1 || sLstFile.length() < 1 )
+ return;
+
+ // Skip if its temporary cpp.
+ if ( sSourceFile.find( AT_TEMP_CPP_LOWER_START) != string::npos )
+ return;
+
+ // Source structure
+ SOURCE sNew;
+ sNew.sCpp = sSourceFile;
+ sNew.sLst = sLstFile;
+
+ // Verify paths.
+ ConvertUnixPathToWin( sNew.sCpp );
+ ConvertUnixPathToWin( sNew.sLst );
+
+ // Lower case them.
+ ChangeToLower( sNew.sCpp );
+ ChangeToLower( sNew.sLst );
+
+ // Add it
+ m_vSources.push_back( sNew );
+}
+
+void CATModule2::AddSources(string& sSource)
+{
+ LOG_LOW_FUNC_ENTRY("CATModule2::AddSources");
+ // Parse sources which are separated by spaces
+ if( sSource.length() < 1 )
+ return;
+ // Source structure
+ SOURCE sNew;
+ size_t iSpot = string::npos;
+ iSpot = sSource.find( " " );
+ while( iSpot != string::npos )
+ {
+ // Pickup source
+ sNew.sCpp = sSource.substr(0, iSpot);
+ // Convert path from Unix to Win
+ ConvertUnixPathToWin( sNew.sCpp );
+ // Lowercase it
+ ChangeToLower( sNew.sCpp );
+ // If its temp skip this
+ if ( sNew.sCpp.find( AT_TEMP_CPP_LOWER_START ) == string::npos )
+ {
+ // Get corresponding lst file for source
+ sNew.sLst = GetLstNameOfSource( sNew.sCpp );
+ m_vSources.push_back( sNew );
+ // Remove it from sSource
+ sSource.erase(0,iSpot+1);
+ // Find new one
+ }
+ iSpot = sSource.find( " " );
+ }
+ // Pickup last or only one source
+ sNew.sCpp = sSource;
+ // Convert path from unix to win
+ ConvertUnixPathToWin( sNew.sCpp );
+ // Lowercase it
+ ChangeToLower( sNew.sCpp );
+ // Lst name
+ sNew.sLst = GetLstNameOfSource( sNew.sCpp );
+ if ( sNew.sCpp.find( AT_TEMP_CPP_LOWER_START ) == string::npos )
+ {
+ // Get corresponding lst file for source
+ sNew.sLst = GetLstNameOfSource( sNew.sCpp );
+ m_vSources.push_back( sNew );
+ }
+}
+bool CATModule2::CreateTempCpp(const string& sS60FileName
+ , int eLoggingMode
+ , int eBuildType
+ , int iAllocCallStackSize
+ , int iFreeCallStackSize )
+{
+ LOG_FUNC_ENTRY("CATModule2::CreateTemporaryCpp");
+ // S60 filename
+ m_sS60FileName = sS60FileName;
+ // Make s60 filename target.type.dat if its empty and logging mode is file
+ if ( eLoggingMode == CATProject::FILE
+ && m_sS60FileName.empty() )
+ {
+ m_sS60FileName = m_sTarget;
+ m_sS60FileName.append(".");
+ m_sS60FileName.append( m_sTargetType );
+ m_sS60FileName.append(".dat");
+ }
+ return CreateTemporaryCpp( GetUniqueId(), m_sTempPath,
+ m_sS60FileName, eLoggingMode, eBuildType, iAllocCallStackSize, iFreeCallStackSize );
+}
+
+bool CATModule2::ModifyMmp()
+{
+ LOG_FUNC_ENTRY("CATModule2::ModifyMmp");
+ // Create backup
+ if ( ! m_Mmp.BackupMmpFile() )
+ return false;
+ // Hook
+ return m_Mmp.EditMmpFile( m_sTargetType, GetUniqueId() );
+}
+
+bool CATModule2::RestoreMmp()
+{
+ LOG_FUNC_ENTRY("CATModule2::RestoreMmp");
+ // Restore mmp from backup
+ return m_Mmp.RestoreMmpFile();
+}
+
+bool CATModule2::VerifyAndRecoverMmp()
+{
+ LOG_FUNC_ENTRY("CATModule2::VerifyAndRecoverMmp");
+ // Verify mmp
+ return m_Mmp.VerifyAndRecover();
+}
+
+// ----------------------------------------------------------------------------
+// Releasables Handling methos
+// ----------------------------------------------------------------------------
+bool CATModule2::CopyReleasables()
+{
+ LOG_FUNC_ENTRY("CATModule2::CopyReleasables");
+ bool bRet = true;
+ if ( ! CopyLstFilesToTemp() )
+ bRet = false;
+ if ( ! CopyMapFileToTemp() )
+ bRet = false;
+ return bRet;
+}
+
+bool CATModule2::CopyLstFilesToDir( const string& sDir )
+{
+ LOG_FUNC_ENTRY("CATModule2::CopyLstFilesToDir");
+ bool bRet = true;
+ // Copy lst files to given directory.
+ vector<SOURCE>::const_iterator source;
+ for( source = m_vSources.begin(); source != m_vSources.end() ; source++ )
+ {
+ if ( ! FileCopyToPath( source->sLst, sDir ) )
+ {
+ if ( !FileExists( source->sLst.c_str() ) )
+ {
+ m_sErrors.append( "Missing listing file: " );
+ m_sErrors.append( source->sLst );
+ m_sErrors.append( "\n" );
+ }
+ if ( !DirectoryExists( sDir.c_str() ) )
+ {
+ m_sErrors.append( "Missing folder: " );
+ m_sErrors.append( sDir );
+ m_sErrors.append( "\n" );
+ }
+ bRet = false;
+ }
+ }
+ // Return.
+ return bRet;
+}
+
+bool CATModule2::CopyLstFilesToTemp()
+{
+ LOG_FUNC_ENTRY("CATModule2::CopyLstFilesToTemp");
+ // Return boolean
+ bool bRet = true;
+ // Move all lst files except tmp cpp
+ vector<SOURCE>::iterator it = m_vSources.begin();
+ while ( it != m_vSources.end() )
+ {
+ if ( !FileCopyToPath( it->sLst, m_sTempPath ) )
+ {
+ if ( !FileExists( it->sLst.c_str() ) )
+ {
+ m_sErrors.append( "Missing listing file: " );
+ m_sErrors.append( it->sLst );
+ m_sErrors.append( "\n" );
+ }
+ if ( !DirectoryExists( m_sTempPath.c_str() ) )
+ {
+ m_sErrors.append( "Missing folder: " );
+ m_sErrors.append( m_sTempPath );
+ m_sErrors.append( "\n" );
+ }
+ bRet = false;
+ }
+ it++;
+ }
+ return bRet;
+}
+
+bool CATModule2::DeleteLstFilesFromSrc( void )
+{
+ LOG_FUNC_ENTRY("CATModule2::DeleteLstFilesFromSrc");
+ vector<SOURCE>::iterator it = m_vSources.begin();
+ bool bRet = true;
+ // Delete lst files
+ while ( it != m_vSources.end() )
+ {
+ if ( ! FileDelete( it->sLst, true ) )
+ bRet = false;
+ it++;
+ }
+ return bRet;
+}
+
+bool CATModule2::CopyMapFileToTemp()
+{
+ LOG_FUNC_ENTRY("CATModule2::CopyMapFileToTemp");
+ // Return boolean
+ bool bRet = true;
+ // Map File to copy
+ string sMapFile = GetMapFile();
+ if ( !FileCopyToPath( sMapFile, m_sTempPath ) )
+ {
+ bRet = false;
+ if ( !FileExists( sMapFile.c_str() ) )
+ {
+ // Add missing map file to error string.
+ m_sErrors.append( "Missing map file: " );
+ m_sErrors.append( sMapFile );
+ m_sErrors.append( "\n" );
+ }
+ if ( !DirectoryExists( m_sTempPath.c_str() ) )
+ {
+ // Add missing temporary folder
+ m_sErrors.append( "Missing folder: " );
+ m_sErrors.append( m_sTempPath );
+ m_sErrors.append( "\n" );
+ }
+ }
+ return bRet;
+}
+
+bool CATModule2::CleanTemporaryDir()
+{
+ LOG_FUNC_ENTRY("CATModule2::CleanTemporaryDir");
+ bool bRet = true;
+ // Verify mmp
+ if ( ! m_Mmp.VerifyAndRecover() )
+ bRet = false;
+ // Clean temporary dir
+ vector<string> vFileList = DirList( m_sTempPath, false , true );
+ vector<string>::iterator it = vFileList.begin();
+ // Size of constant table
+ int iCount = sizeof( TEMP_EXTENSION_NO_DELETE ) / sizeof( string );
+ while ( it != vFileList.end() )
+ {
+ // Get extension and compare it to list
+ bool bDelete = true;
+ string sExtension = GetExtension( *it );
+ ChangeToLower( sExtension );
+ for ( int i = 0 ; i < iCount ; i++ )
+ {
+ if( sExtension.compare( TEMP_EXTENSION_NO_DELETE[i] ) == 0 )
+ {
+ bDelete = false;
+ break;
+ }
+ }
+ if ( bDelete )
+ {
+ // Delete file
+ if ( ! FileDelete( *it, true ) )
+ bRet = false;
+ }
+ // Increment
+ it++;
+ }
+ return bRet;
+}
+
+bool CATModule2::DeleteTemporaryDir()
+{
+ LOG_FUNC_ENTRY("CATModule2::DeleteTemporaryDir");
+ bool bRet = true;
+ // Verify mmp
+ if ( ! m_Mmp.VerifyAndRecover() )
+ bRet = false;
+ // Delete temp dir
+ if ( !DirDelete( m_sTempPath, true ) )
+ bRet = false;
+ return bRet;
+}
+
+bool CATModule2::IsUDEB() const
+{
+ LOG_LOW_FUNC_ENTRY("CATModule2::IsUDEB");
+ // Determine from variant is this udeb
+ if ( m_sVariantType.find( "udeb" ) != string::npos )
+ return true;
+ return false;
+}
+// ----------------------------------------------------------------------------
+// Private AddressToLine related methods
+// ----------------------------------------------------------------------------
+bool CATModule2::InitializeAddressToLine()
+{
+ LOG_FUNC_ENTRY("CATModule2::InitializeAddressToLine");
+ bool bRet = true;
+ // Read in different way depending on platform
+ if ( m_sVariantPlatform.compare("armv5") == 0 )
+ {
+ // Add static library lst files to source vector,
+ // before reading them.
+ vector<string> vFiles = DirList( AT_TEMP_LST_DIR, false, true );
+ for(vector<string>::iterator it = vFiles.begin() ; it != vFiles.end() ; it ++ )
+ {
+ SOURCE source;
+ source.bStatic = true;
+ source.sLst = *it;
+ source.sCpp = *it;
+ source.sCpp = CATBase::RemovePathAndExt( source.sCpp, false );
+ source.sCpp.append( ".cpp" );
+ m_vSources.push_back( source );
+ }
+
+ if ( ! ReadListingFilesArmv5() )
+ bRet = false;
+ if ( ! ReadMapFileArmv5() )
+ bRet = false;
+
+ if ( bRet )
+ m_bAddressToLineInitialized = true;
+ }
+ return bRet;
+}
+
+
+bool CATModule2::ReadListingFilesArmv5()
+{
+ LOG_FUNC_ENTRY("CATModule2::ReadListingFilesArmv5");
+ char cTemp[MAX_LINE_LENGTH];
+ vector<SOURCE>::iterator viFileIter = m_vSources.begin();
+ int iNumberOfLstFiles = (int)m_vSources.size();
+ vector<string> vTempLines;
+ string sFileName;
+
+ // Open all .lst files
+ while( iNumberOfLstFiles > 0 )
+ {
+ // Make .lst file name
+ sFileName.clear();
+
+ // If lst file is not from static library make path to modules temporary directory.
+ if ( viFileIter->bStatic != true )
+ {
+ // Remove path
+ if( viFileIter->sLst.find("\\") != string::npos )
+ sFileName.append(
+ viFileIter->sLst.substr( viFileIter->sLst.find_last_of( "\\" ) + 1
+ , viFileIter->sLst.size() ) );
+ else
+ sFileName.append( viFileIter->sLst );
+
+ // Add temporary dir
+ sFileName.insert( 0, m_sTempPath );
+ }
+ else
+ {
+ // Lst from static library don't change path.
+ sFileName = viFileIter->sLst;
+ }
+ // Open lst file
+ ifstream in( sFileName.c_str() );
+
+ // If file can not be opened, try to open next file
+ if( !in.good() )
+ {
+ viFileIter++;
+ iNumberOfLstFiles--;
+ continue;
+ }
+
+ string sTemp;
+ // Clear temporary lines
+ vTempLines.clear();
+ // Add all lines to temp list
+ do
+ {
+ in.getline( cTemp, MAX_LINE_LENGTH );
+ sTemp.clear();
+ sTemp.append( cTemp );
+ vTempLines.push_back( sTemp );
+ }
+ while( in.good() );
+
+ LINE_IN_FILE structLineInFile;
+
+ bool bFindENDP = false;
+ vector<string>::iterator viLinesIter = vTempLines.begin();
+
+ // Loop throw all lines in .lst file
+ while( viLinesIter != vTempLines.end() )
+ {
+ // Find ";;;"
+ if( !bFindENDP && strstr(viLinesIter->c_str(), ";;;") != NULL )
+ {
+ bFindENDP = true;
+
+ vector<string>::iterator viLineTempIter = viLinesIter;
+
+ // Find top line of function definition
+ while( viLineTempIter->size() > 0 )
+ {
+ viLineTempIter--;
+ }
+ viLineTempIter++;
+ structLineInFile.sFunction.clear();
+ structLineInFile.sFunction.append( viLineTempIter->c_str() );
+
+ viLinesIter++;
+ // Get Line
+ sTemp.clear();
+ sTemp.append( viLinesIter->c_str() );
+ sTemp.erase(0,3);
+ size_t iSize = sTemp.find_first_of(' ');
+ if( iSize != string::npos )
+ sTemp.resize(iSize);
+ structLineInFile.iLine = atoi( sTemp.c_str() );
+
+ structLineInFile.sFileName.clear();
+ structLineInFile.sFileName.append( viFileIter->sCpp.c_str() );
+ structLineInFile.sLstName = sFileName;
+ m_vLineInFile.push_back( structLineInFile );
+ }
+ else if( strstr(viLinesIter->c_str(), "ENDP") != NULL )
+ bFindENDP = false;
+ viLinesIter++;
+ }
+ viFileIter++;
+ iNumberOfLstFiles--;
+ }
+ if( m_vLineInFile.size() > 0 )
+ return true;
+ return false;
+}
+
+bool CATModule2::ReadMapFileArmv5()
+{
+ LOG_FUNC_ENTRY("CATModule2::ReadMapFileArmv5");
+ // Map file name
+ string sMapFileName = GetMapFile();
+ // Remove path
+ if ( sMapFileName.find("\\") != string::npos )
+ sMapFileName.erase(0, sMapFileName.find_last_of('\\')+1 );
+ // Add temp path
+ sMapFileName.insert(0, m_sTempPath );
+
+ // Open .map file
+ ifstream in( sMapFileName.c_str() );
+
+ // File open ok?
+ if( ! in.good() )
+ {
+ in.close();
+ return false;
+ }
+ char cTemp[MAX_LINE_LENGTH];
+ bool bFirstFuncFound = false;
+ // Get all lines where is "Thumb"
+ do
+ {
+ // Load one line from .map file
+ in.getline( cTemp, MAX_LINE_LENGTH );
+ // Find _E32Startup
+ if( !bFirstFuncFound && ( strstr( cTemp, "_E32Startup" ) != NULL) )
+ {
+ bFirstFuncFound = true;
+ }
+ else if( !bFirstFuncFound && ( strstr( cTemp, "_E32Dll" ) != NULL) )
+ {
+ bFirstFuncFound = true;
+ }
+ else if( !bFirstFuncFound )
+ // Skip if _E32Startup not found
+ continue;
+
+ if( strstr( cTemp, "Thumb Code" ) != NULL || strstr( cTemp, "ARM Code" ) != NULL)
+ {
+ MAP_FUNC_INFO structMapFileLineInfo;
+ structMapFileLineInfo.sWholeLine.append( cTemp );
+
+ // Get memory string address from line
+ char* pStart = strstr( cTemp, "0x" );
+ // Check did strstr return null.
+ if( pStart == NULL )
+ continue;
+ char* pTemp = pStart;
+ char TempString[MAX_LINE_LENGTH];
+ TempString[0] = 0;
+ size_t iLength = 0;
+ while( *pTemp != ' ' )
+ {
+ TempString[iLength] = *pTemp;
+ pTemp++;
+ iLength++;
+ }
+ TempString[iLength] = 0;
+
+ structMapFileLineInfo.iAddress = CATDatParser::_httoi( TempString );
+
+ pTemp = cTemp;
+ TempString[0] = 0;
+
+ // Get function name
+
+ // Skip spaces
+ while( *pTemp == ' ' )
+ {
+ pTemp++;
+ }
+ iLength = 0;
+ // Find end of function name
+ string sTemp( pTemp );
+
+ // Location of character ')'
+ iLength = sTemp.find_first_of(')');
+
+ // Location of character ' '
+ size_t iLength2 = sTemp.find_first_of(' ');
+
+ // If ')' character is the last char and
+ // character ' ' is closer than ')' use location of ' '
+ if( ( iLength + 1 ) == sTemp.length() && iLength2 < iLength )
+ iLength = iLength2 - 1;
+
+ if( iLength != string::npos )
+ sTemp.resize( (iLength + 1) );
+
+ structMapFileLineInfo.sFunctionName.append( sTemp.c_str() );
+
+ bool bARM = false;
+ // Find function length
+ pStart = strstr( cTemp, "Thumb Code" );
+ if( pStart == NULL )
+ {
+ pStart = strstr( cTemp, "ARM Code" );
+ bARM = true;
+ }
+ if( pStart != NULL )
+ {
+ if( bARM )
+ pStart += 8;
+ else
+ pStart += 10;
+ while(*pStart == ' ')
+ {
+ pStart++;
+ }
+ sTemp.clear();
+ sTemp.append( pStart );
+ size_t iSize = sTemp.find_first_of(' ');
+ if( iSize != string::npos )
+ sTemp.resize( iSize );
+ }
+
+ structMapFileLineInfo.iFuncLength = atoi( sTemp.c_str() );
+ if( bFirstFuncFound && structMapFileLineInfo.iFuncLength > 0 )
+ // Save to list
+ m_vMapFileFuncList.push_back( structMapFileLineInfo );
+ }
+ }
+ while( in.good() );
+ in.close();
+ return true;
+}
+
+int CATModule2::FindLeakCodeLine( string& sFileName, int iLine, unsigned long iFromFuncAddress ) const
+{
+ LOG_LOW_FUNC_ENTRY("CATModule2::FindLeakCodeLine");
+ if ( sFileName.empty() )
+ return -1;
+ char cLineFromFile[MAX_LINE_LENGTH];
+ vector<string> vTempLines;
+ string sTemp;
+ char* pTemp = NULL;
+ char* pTempEnd = NULL;
+ int iFoundLine = -1;
+ int iRet = -1;
+
+ // Open lst file
+ ifstream in( sFileName.c_str() );
+
+ bool bLineFound = false;
+ bool bFirstAddressInFuncFound = false;
+ unsigned long iFirstAddressInFunc = 0;
+ while( in.good() )
+ {
+ in.getline( cLineFromFile, MAX_LINE_LENGTH );
+
+ if( bLineFound )
+ {
+ vTempLines.push_back( cLineFromFile );
+ // Is first character digit
+ if( isdigit( cLineFromFile[0] ) )
+ {
+ if( !bFirstAddressInFuncFound )
+ {
+ bFirstAddressInFuncFound = true;
+ sTemp.clear();
+ sTemp.append( cLineFromFile );
+ // Get value until next space
+ sTemp.resize( sTemp.find_first_of(' ') );
+
+ iFirstAddressInFunc = CATDatParser::_httoi( sTemp.c_str() );
+
+ // Return function start line if margin 0
+ if( iFromFuncAddress == 0 )
+ {
+ iRet = iLine;
+ return iRet;
+ }
+ }
+ else
+ {
+ // Find correct line using iFromFuncAddress variable
+ sTemp.clear();
+ sTemp.append( cLineFromFile );
+ // Get value until next space
+ sTemp.resize( sTemp.find_first_of(' ') );
+
+ unsigned long iValue = CATDatParser::_httoi( sTemp.c_str() );
+
+ if( ( iValue - iFirstAddressInFunc ) >= iFromFuncAddress )
+ {
+ // If there is data in function, code line can not be found
+ if( strstr( cLineFromFile , "DCB" ) != NULL )
+ {
+ iRet = -1;
+ return iRet;
+ }
+ pTemp = strstr( cLineFromFile, ";" );
+ // Get line number
+ bool bStringNumber = true;
+ if( pTemp != NULL )
+ {
+ string sTempLine( pTemp + 1 );
+ // Are all characters numbers?
+ for( unsigned int i = 0 ; i < sTempLine .size() ; i++ )
+ {
+ if( !isdigit(sTempLine[i]) )
+ {
+ bStringNumber = false;
+ break;
+ }
+ }
+ }
+ else
+ bStringNumber = false;
+ if( bStringNumber )
+ {
+ pTemp++;
+ // Get line number
+ iRet = atoi( pTemp );
+ }
+ else
+ {
+ vector<string>::iterator sTempIter = vTempLines.end();
+
+ sTempIter--;
+
+ // Find last code line
+ while( sTempIter != vTempLines.begin() )
+ {
+ if( strstr( sTempIter->c_str() , "DCB" ) != NULL )
+ {
+ iRet = -1;
+ return iRet;
+ }
+ if( strstr( sTempIter->c_str() , ";;;" ) == NULL )
+ sTempIter--;
+ else
+ break;
+ }
+ if(sTempIter == vTempLines.begin() && strstr( sTempIter->c_str() , ";;;" ) == NULL)
+ {
+ iRet = -1;
+ return iRet;
+ }
+ sTempIter->erase( 0, 3 );
+ sTempIter->resize( sTempIter->find(' ') );
+
+ // Leak line
+ iRet = atoi( sTempIter->c_str() );
+ }
+ return iRet;
+ }
+ }
+ }
+ }
+ else // Line in file not found
+ {
+ // Find line of function
+ if( strstr( cLineFromFile, ";;;" ) != NULL )
+ {
+ pTemp = &cLineFromFile[0];
+ // Skip characters ";;;"
+ pTemp += 3;
+ pTempEnd = pTemp;
+ // Find end of line number
+ while( *pTempEnd != ' ' )
+ {
+ pTempEnd++;
+ }
+ *pTempEnd = 0;
+ iFoundLine = atoi( pTemp );
+ *pTempEnd = ' ';
+ if( iLine == iFoundLine )
+ {
+ bLineFound = true;
+ }
+ }
+ }
+ }
+ return iRet;
+}
+
+bool CATModule2::IsMakeSuccessfull()
+{
+ LOG_FUNC_ENTRY("CATModule2::IsMakeSuccessfull");
+ m_sErrors.clear();
+
+ string sSearch;
+ bool bMakeSuccess = true;
+
+ // Lst files checked only with armv5 platform.
+ if ( IsPlatformArmv5() )
+ {
+ sSearch.append( m_sTempPath );
+ sSearch.append( "*.lst" );
+ if( !SearchFileWithExtension( sSearch.c_str(), false, m_sErrors ) )
+ bMakeSuccess = false;
+
+ // Map
+ sSearch.clear();
+ sSearch.append( m_sTempPath );
+ sSearch.append( "*.map" );
+ if( !SearchFileWithExtension( sSearch.c_str(), false, m_sErrors ) )
+ bMakeSuccess = false;
+ }
+
+ // .tmp
+ sSearch.clear();
+ sSearch.append( m_sTempPath );
+ sSearch.append( "*.tmp" );
+ if( !SearchFileWithExtension( sSearch.c_str(), false, m_sErrors ) )
+ bMakeSuccess = false;
+
+ return bMakeSuccess;
+}
+
+bool CATModule2::CreateBuildCompleteFile()
+{
+ LOG_FUNC_ENTRY("CATModule2::CreateBuildCompleteFile");
+ // Don't create file if temp path not set cause might be anywhere
+ if ( m_sTempPath.empty() )
+ return false;
+ // Create empty file indicating this module is build
+ string sFile = m_sTempPath;
+ if( sFile.at( sFile.length() - 1 ) != '\\' )
+ sFile.append("\\");
+ sFile.append( "BuildComplete" );
+ ofstream out( sFile.c_str() );
+ out << m_sVariantPlatform << endl;
+ out << m_sVariantType << endl;
+ out.close();
+ return true;
+}
+
+bool CATModule2::ReadMakeFileFromTemp()
+{
+ LOG_FUNC_ENTRY("CATModule2::ReadMakeFileFromTemp");
+ // Set makefile to point to temporary directory.
+ string sMakeFile = m_sTempPath;
+ sMakeFile.append( RemovePathAndExt( m_Mmp.m_sMmpFile, true ) );
+ sMakeFile.append( "." );
+ sMakeFile.append( AT_LEVEL_2_MAKEFILE_EXT );
+ m_sMakeFile = sMakeFile;
+ return ReadMakeFilePrivate();
+}
+
+bool CATModule2::ReadMakeFile()
+{
+ LOG_FUNC_ENTRY("CATModule2::ReadMakeFile");
+ // Read makefile
+ if ( ReadMakeFilePrivate() )
+ {
+ // Copy makefile to temporary directory.
+ string sMakeFile = m_sTempPath;
+ sMakeFile.append( RemovePathAndExt( m_Mmp.m_sMmpFile, true ) );
+ sMakeFile.append( "." );
+ sMakeFile.append( AT_LEVEL_2_MAKEFILE_EXT );
+ FileCopyToPath( m_sMakeFile, sMakeFile );
+ return true;
+ }
+ return false;
+}
+
+bool CATModule2::ReadMakeFilePrivate()
+{
+ LOG_FUNC_ENTRY("CATModule2::ReadMakeFilePrivate");
+
+ if ( m_sMakeFile.empty() )
+ return false;
+
+ LOG_STRING( "using makefile :" << m_sMakeFile );
+
+ // Stream object to read files
+ ifstream in;
+ // Char array to read line from file
+ char cLine[MAX_LINE_LENGTH];
+ // String to use as buffer from file
+ string sLine;
+ // Open file
+ in.open( m_sMakeFile.c_str(), ios_base::in );
+ // Check that its open
+ if ( ! in.good() )
+ {
+ // Cannot open file
+ cout << AT_MSG << "Error, can not open file: " << m_sMakeFile << endl;
+ return false;
+ }
+ // Check is it wrapper makefile (starts with "%:")
+ in.getline( cLine, MAX_LINE_LENGTH );
+ if ( cLine[0] == '%' && cLine[1] == ':' )
+ {
+ LOG_STRING("Found wrapper makefile");
+ in.close();
+ // Use ".default" makefile
+ string sDefaultMakeFile = m_sMakeFile.substr( 0, m_sMakeFile.find_last_of( "." ) );
+ sDefaultMakeFile.append( ".DEFAULT" );
+ LOG_STRING( "using makefile :" << m_sMakeFile );
+ // Does default exists. If not we need to run "wrapper make"
+ if ( ! FileExists( sDefaultMakeFile.c_str() ) )
+ {
+ // Run the wrapper make to create "real" makefile
+ string sMakeFileCmd;
+ sMakeFileCmd.append("make -f \"");
+ sMakeFileCmd.append( m_sMakeFile );
+ sMakeFileCmd.append( "\"" );
+ LOG_STRING( "using makefile :" << m_sMakeFile );
+ cout << AT_MSG_SYSTEM_CALL << sMakeFileCmd << endl;
+ int iRet = (int)system( sMakeFileCmd.c_str() );
+ if ( iRet )
+ {
+ cout << MAKE_ERROR;
+ return false;
+ }
+ }
+ m_sMakeFile = sDefaultMakeFile;
+ // Open new file
+ in.open( m_sMakeFile.c_str(), ios_base::in );
+ // Check that it's open
+ if ( ! in.good() )
+ {
+ // Cannot open file
+ cout << AT_MSG << "Error, can not open makefile: " << m_sMakeFile << endl;
+ return false;
+ }
+ }
+ in.seekg( ios_base::beg );
+
+ // Number of lines to read at max for basic module information.
+ int iReadLineCount = 20;
+ // Extension from target line. to be compared with targettype.
+ string sTargetExtension;
+ // Read line at a time. Loop until we find it or eof
+ do {
+ // Read line from file to array
+ in.getline( cLine, MAX_LINE_LENGTH );
+ iReadLineCount--;
+
+ sLine.clear();
+ // Put that to string
+ sLine.append( cLine );
+ // Search target
+ if ( sLine.find( MAKEFILE_TARGET_STRING ) != string::npos )
+ {
+ // Found it. Now remove other than type from line
+ sLine.erase( 0, strlen( MAKEFILE_TARGET_STRING ) );
+ ChangeToLower( sLine );
+ sTargetExtension.clear();
+ sTargetExtension = GetExtension( sLine );
+ m_sTarget = RemovePathAndExt( sLine, true);
+ LOG_STRING("found target: " << sLine );
+ }
+ // Search targettype
+ else if ( sLine.find( MAKEFILE_TARGETTYPE_STRING ) != string::npos )
+ {
+ // Found it. Now remove other than type from line
+ sLine.erase( 0, strlen( MAKEFILE_TARGETTYPE_STRING ) );
+ ChangeToLower( sLine );
+ m_sTargetType = sLine;
+ LOG_STRING("found target type: " << m_sTargetType );
+ }
+ else if ( sLine.find( MAKEFILE_BASIC_TARGETTYPE_STRING ) != string::npos )
+ {
+ sLine.erase( 0, strlen( MAKEFILE_BASIC_TARGETTYPE_STRING ) );
+ ChangeToLower( sLine );
+ m_sRequestedTargetExt = sLine;
+ // Compare with the extension in target line if not same use target lines if its "valid".
+ if ( m_sRequestedTargetExt.compare( sTargetExtension ) != 0 && sTargetExtension.size() > 0 )
+ m_sRequestedTargetExt = sTargetExtension;
+ LOG_STRING("found requested target extension: " << m_sTargetType );
+ }
+ // Feature variant details
+ else if ( sLine.find( MAKEFILE_FEATURE_VARIANT_NAME ) != string::npos )
+ {
+ sLine.erase( 0, strlen( MAKEFILE_FEATURE_VARIANT_NAME ) );
+ m_sFeatureVariantName = sLine;
+ LOG_STRING("found feature variant name: " << sLine );
+ }
+ else if ( sLine.find( MAKEFILE_FEATURE_VARIANT_UREL_LABEL ) != string::npos )
+ {
+ sLine.erase( 0, strlen( MAKEFILE_FEATURE_VARIANT_UREL_LABEL ) );
+ LOG_STRING("found feature variant urel label: " << sLine );
+ if ( sLine.compare("INVARIANT") != 0 )
+ m_sFeatureVariantURELLabel = sLine;
+ }
+ else if ( sLine.find( MAKEFILE_FEATURE_VARIANT_UDEB_LABEL ) != string::npos )
+ {
+ sLine.erase( 0, strlen( MAKEFILE_FEATURE_VARIANT_UDEB_LABEL ) );
+ LOG_STRING("found feature variant udeb label: " << sLine );
+ if ( sLine.compare("INVARIANT") != 0 )
+ m_sFeatureVariantUDEBLabel = sLine;
+ }
+ } while( in.good() && iReadLineCount > 0 );
+
+ // Search compile definitions
+ // CWDEFS CCDEFS ARMCCDEFS
+ do
+ {
+ in.getline( cLine, MAX_LINE_LENGTH );
+ sLine.clear();
+ sLine.append( cLine );
+ if ( sLine.substr( 0 , 6 ).compare( string("CWDEFS") ) == 0
+ || sLine.substr( 0 , 6 ).compare( string("CCDEFS") ) == 0 )
+ {
+ sLine.erase( 0, 8 );
+ m_sCompileDefinitions = sLine;
+ break;
+ }
+ else if( sLine.substr( 0 , 9 ).compare( string("ARMCCDEFS") ) == 0 )
+ {
+ sLine.erase( 0, 11 );
+ m_sCompileDefinitions = sLine;
+ break;
+ }
+ } while( in.good() );
+ // Move reading back to start if we could not find compile flags.
+ in.seekg( ios_base::beg );
+
+ // Search listing information (modules source files).
+ int iFindItem = 1; //1 = Source, 2 = LISTINGUDEB/UREL, 3 = lst file
+ string sCdefs;
+ string sSource;
+ string sLst;
+ do
+ {
+ in.getline( cLine, MAX_LINE_LENGTH );
+ sLine.clear();
+ sLine.append( cLine );
+
+ switch( iFindItem )
+ {
+ case 1:
+ if( sLine.find( "# Source " ) != string::npos )
+ {
+ iFindItem = 2;
+ // Remove text "# Source "
+ sLine.erase( 0, 9 );
+ sSource = sLine;
+ }
+ break;
+ case 2:
+ if( IsUDEB() )
+ {
+ if( sLine.find( "LISTINGUDEB" ) != string::npos )
+ {
+ iFindItem = 3;
+ }
+ }
+ else
+ {
+ if( sLine.find( "LISTINGUREL" ) != string::npos )
+ {
+ iFindItem = 3;
+ }
+ }
+ break;
+ case 3:
+ if( sLine.find( "perl -S ecopyfile.pl" ) != string::npos )
+ {
+ // Save lst file to list
+ sLine.erase( 0, ( sLine.find_first_of( "\\" ) ) );
+ // remove last char if '"'
+ if ( sLine.at( sLine.size()-1 ) == '"' )
+ sLine.erase( sLine.size()-1, sLine.size() );
+ sLst = sLine;
+ AddSource( sSource, sLst );
+ iFindItem = 1;
+ sSource.clear(); sLst.clear();
+
+ }
+ break;
+ }
+ }
+ while( in.good() );
+ // close and return
+ in.close();
+ return true;
+}
+
+// ----------------------------------------------------------------------------
+// Get & Sets
+// ----------------------------------------------------------------------------
+string CATModule2::GetErrors() const
+{
+ LOG_LOW_FUNC_ENTRY("CATModule2::GetErrors");
+ return m_sErrors;
+}
+
+string CATModule2::GetS60FileName() const
+{
+ LOG_LOW_FUNC_ENTRY("CATModule2::GetS60FileName");
+ if ( m_sS60FileName.empty() )
+ {
+ string sGeneratedDatName = m_sTarget;
+ sGeneratedDatName.append(".");
+ sGeneratedDatName.append( m_sTargetType );
+ sGeneratedDatName.append(".dat");
+ return sGeneratedDatName;
+ }
+ return m_sS60FileName;
+}
+
+string CATModule2::GetLstNameOfSource(string sSource) const
+{
+ LOG_LOW_FUNC_ENTRY("CATModule2::GetLstNameOfSource");
+ // Find . before xtension
+ size_t iSpot = sSource.find_last_of( "." );
+ // Get sub string to there
+ string sLst = sSource.substr(0, iSpot+1);
+ if ( m_sVariantPlatform.compare( "winscw" ) != 0 )
+ {
+ // Add variant platform (i.e. armv5)
+ sLst.append( m_sVariantPlatform );
+ sLst.append( "." );
+ // Add variant type (i.e. build type liek urel)
+ sLst.append( m_sVariantType );
+ sLst.append( "." );
+ // Add target binary name
+ sLst.append( m_sTarget );
+ sLst.append( "." );
+ // Add target requested binary extension
+ sLst.append( m_sRequestedTargetExt );
+ sLst.append( "." );
+ // Add lst extension
+ sLst.append( "lst" );
+ }
+ else
+ {
+ sLst.append( "WINSCW.lst" );
+ }
+ return sLst;
+}
+
+bool CATModule2::IsPlatformArmv5() const
+{
+ LOG_LOW_FUNC_ENTRY("CATModule2::IsPlatformArmv5");
+ if ( _stricmp( m_sVariantPlatform.c_str(), "armv5" ) == 0 )
+ return true;
+ return false;
+}
+
+string CATModule2::GetMapFile() const
+{
+ LOG_LOW_FUNC_ENTRY("CATModule2::GetMapFile");
+ // Map file with path using variables
+ string sMapFile( m_sReleasePath );
+ if ( ! sMapFile.empty() )
+ sMapFile.append( "\\" );
+ sMapFile.append( m_sFullVariantPath );
+ if ( ! m_sFullVariantPath.empty() )
+ sMapFile.append( "\\" );
+ sMapFile.append( m_sTarget );
+ sMapFile.append( "." );
+ // Possible feature variant. Note debug might not be defined
+ // when release has got one.
+ if ( IsUDEB() && !m_sFeatureVariantUDEBLabel.empty() )
+ {
+ sMapFile.append( m_sFeatureVariantUDEBLabel );
+ sMapFile.append( "." );
+ }
+
+ if ( !IsUDEB() && !m_sFeatureVariantURELLabel.empty() )
+ {
+ sMapFile.append( m_sFeatureVariantURELLabel );
+ sMapFile.append( "." );
+ }
+ sMapFile.append( m_sRequestedTargetExt );
+ sMapFile.append( ".map" );
+ return sMapFile;
+}
+
+string CATModule2::GetSymbolFile() const
+{
+ LOG_LOW_FUNC_ENTRY("CATModule2::GetSymbolFile");
+ // Symbol file with path using variables
+ string sSymbolFile( m_sReleasePath );
+ sSymbolFile.append( "\\" );
+ sSymbolFile.append( m_sFullVariantPath );
+ sSymbolFile.append( "\\" );
+ sSymbolFile.append( m_sTarget );
+ sSymbolFile.append( "." );
+ // Possible feature variant.
+ if ( ! m_sFeatureVariantUDEBLabel.empty() || ! m_sFeatureVariantURELLabel.empty() )
+ {
+ if ( IsUDEB() )
+ sSymbolFile.append( m_sFeatureVariantUDEBLabel );
+ else
+ sSymbolFile.append( m_sFeatureVariantURELLabel );
+ sSymbolFile.append( "." );
+ }
+
+ if ( m_eBuildSystem == CATProject::SBS_V1 )
+ {
+ sSymbolFile.append( "sym" );
+ return sSymbolFile;
+ }
+ sSymbolFile.append( m_sRequestedTargetExt );
+ sSymbolFile.append( ".sym" );
+ return sSymbolFile;
+}
+
+string CATModule2::GetBinaryFile() const
+{
+ LOG_LOW_FUNC_ENTRY("CATModule2::GetBinaryFile");
+ // Binary file with path using variables
+ string sBinaryFile( m_sReleasePath );
+ if ( ! sBinaryFile.empty() )
+ sBinaryFile.append( "\\" );
+ sBinaryFile.append( m_sFullVariantPath );
+ if ( ! m_sFullVariantPath.empty() )
+ sBinaryFile.append( "\\" );
+ sBinaryFile.append( m_sTarget );
+ sBinaryFile.append( "." );
+ // Possible feature variant.
+ if ( ! m_sFeatureVariantUDEBLabel.empty() || ! m_sFeatureVariantURELLabel.empty() )
+ {
+ if ( IsUDEB() )
+ sBinaryFile.append( m_sFeatureVariantUDEBLabel );
+ else
+ sBinaryFile.append( m_sFeatureVariantURELLabel );
+ sBinaryFile.append( "." );
+ }
+ sBinaryFile.append( m_sRequestedTargetExt );
+ return sBinaryFile;
+}
+
+bool CATModule2::SetMmpFile(const string& sMmpFile)
+{
+ LOG_FUNC_ENTRY("CATModule2::SetMmpFile");
+ // Set mmp file
+ m_Mmp.m_sMmpFile = sMmpFile;
+ // Change to lower
+ ChangeToLower( m_Mmp.m_sMmpFile );
+ // Convert
+ ConvertUnixPathToWin( m_Mmp.m_sMmpFile );
+ // Set the temporary path.
+ m_sTempPath.clear();
+ m_sTempPath = CreateTempPath( m_Mmp.m_sMmpFile );
+ return true;
+}
+
+bool CATModule2::CreateTemporaryDirectory()
+{
+ LOG_FUNC_ENTRY("CATModule2::CreateTemporaryDirectory");
+ if ( m_sTempPath.empty() )
+ {
+ LOG_STRING("Temporary path is not set.");
+ return false;
+ }
+ // Create temp dir if not exists
+ if ( ! DirectoryExists( m_sTempPath.c_str() ) )
+ {
+ if ( !CreateDirectory( m_sTempPath.c_str(), NULL ) )
+ {
+ cout << AT_MSG << "Error, can not create directory: "
+ << m_sTempPath << endl;
+ return false;
+ }
+ cout << AT_MSG << "Directory created: " << m_sTempPath << endl;
+ }
+ return true;
+}
+
+void CATModule2::SetMakeFile( const string& sMakeFile )
+{
+ LOG_FUNC_ENTRY("CATModule2::SetMakeFile");
+ m_sMakeFile = sMakeFile;
+}
+string CATModule2::GetMakeFile() const
+{
+ LOG_LOW_FUNC_ENTRY("CATModule2::GetMakeFile");
+ return m_sMakeFile;
+}
+string CATModule2::GetMmpFile() const
+{
+ LOG_LOW_FUNC_ENTRY("CATModule2::GetMmpFile");
+ return m_Mmp.m_sMmpFile;
+}
+string CATModule2::GetTempPath() const
+{
+ LOG_LOW_FUNC_ENTRY("CATModule2::GetTempPath");
+ return m_sTempPath;
+}
+void CATModule2::SetTarget(const string& sTarget)
+{
+ LOG_FUNC_ENTRY("CATModule2::SetTarget");
+ m_sTarget = sTarget;
+ ChangeToLower( m_sTarget );
+}
+string CATModule2::GetTarget() const
+{
+ LOG_LOW_FUNC_ENTRY("CATModule2::GetTarget");
+ return m_sTarget;
+}
+string CATModule2::GetBinaryName() const
+{
+ LOG_LOW_FUNC_ENTRY("CATModule2::GetBinaryName");
+ string sBinaryName;
+ sBinaryName.append( m_sTarget );
+ sBinaryName.append( "." );
+ sBinaryName.append( m_sRequestedTargetExt );
+ return sBinaryName;
+}
+
+void CATModule2::SetTargetType(const string& sTargetType)
+{
+ LOG_FUNC_ENTRY("CATModule2::SetTargetType");
+ m_sTargetType = sTargetType;
+ ChangeToLower( m_sTargetType );
+}
+string CATModule2::GetTargetType() const
+{
+ LOG_LOW_FUNC_ENTRY("CATModule2::GetTargetType");
+ return m_sTargetType;
+}
+void CATModule2::SetRequestedTargetExt( const string& sRequestedTargetExt )
+{
+ LOG_FUNC_ENTRY("CATModule2::SetRequestedTargetExt");
+ m_sRequestedTargetExt = sRequestedTargetExt;
+ ChangeToLower( m_sRequestedTargetExt );
+}
+
+string CATModule2::GetRequestedTargetExt() const
+{
+ LOG_LOW_FUNC_ENTRY("CATmodule2::GetRequestedTargetExt");
+ return m_sRequestedTargetExt;
+}
+
+void CATModule2::SetVariantPlatform(const string& sVariantPlatform)
+{
+ LOG_FUNC_ENTRY("CATModule2::SetVariantPlatform");
+ m_sVariantPlatform = sVariantPlatform;
+ ChangeToLower( m_sVariantPlatform );
+}
+string CATModule2::GetVariantPlatform() const
+{
+ LOG_LOW_FUNC_ENTRY("CATModule2::GetVariantPlatform");
+ return m_sVariantPlatform;
+}
+void CATModule2::SetVariantType(const string& sVariantType)
+{
+ LOG_FUNC_ENTRY("CATModule2::SetVariantType");
+ m_sVariantType = sVariantType;
+ ChangeToLower( m_sVariantType );
+}
+string CATModule2::GetVariantType() const
+{
+ LOG_LOW_FUNC_ENTRY("CATModule2::GetVariantType");
+ return m_sVariantType;
+}
+void CATModule2::SetFeatureVariant(const string& sFeatureVariant)
+{
+ LOG_FUNC_ENTRY("CATModule2::SetFeatureVariant");
+ m_sFeatureVariant = sFeatureVariant;
+ ChangeToLower( m_sFeatureVariant );
+}
+string CATModule2::GetFeatureVariant() const
+{
+ LOG_LOW_FUNC_ENTRY("CATModule2::GetFeatureVariant");
+ return m_sFeatureVariant;
+}
+void CATModule2::SetFeatureVariantName(const string& sFeatureVariantName)
+{
+ LOG_FUNC_ENTRY("CATModule2::SetFeatureVariantName");
+ m_sFeatureVariantName = sFeatureVariantName;
+ ChangeToLower( m_sFeatureVariantName );
+}
+string CATModule2::GetFeatureVariantName() const
+{
+ LOG_LOW_FUNC_ENTRY("CATModule2::GetFeatureVariantName");
+ return m_sFeatureVariantName;
+}
+void CATModule2::SetReleasePath(const string& sReleasePath)
+{
+ LOG_FUNC_ENTRY("CATModule2::SetReleasePath");
+ m_sReleasePath = sReleasePath;
+ ChangeToLower( m_sReleasePath );
+ ConvertUnixPathToWin( m_sReleasePath );
+
+}
+string CATModule2::GetReleasePath() const
+{
+ LOG_LOW_FUNC_ENTRY("CATModule2::GetReleasePath");
+ return m_sReleasePath;
+}
+void CATModule2::SetFullVariantPath(const string& sFullVariantPath)
+{
+ LOG_FUNC_ENTRY("CATModule2::SetFullVariantPath");
+ m_sFullVariantPath = sFullVariantPath;
+ ChangeToLower( m_sFullVariantPath );
+ ConvertUnixPathToWin( m_sFullVariantPath );
+}
+string CATModule2::GetFullVariantPath() const
+{
+ LOG_LOW_FUNC_ENTRY("CATModule2::GetFullVariantPath");
+ return m_sFullVariantPath;
+}
+string CATModule2::GetUniqueId() const
+{
+ LOG_LOW_FUNC_ENTRY("CATModule2::GetUniqueId");
+ return FilterString( m_sTarget );
+}
+void CATModule2::SetBuildSystem( int eBuildSystem )
+{
+ LOG_FUNC_ENTRY("CATModule2::SetBuildSystem");
+ m_eBuildSystem = eBuildSystem;
+}
+
+int CATModule2::GetBuildSystem() const
+{
+ LOG_LOW_FUNC_ENTRY("CATModule2::GetBuildSystem");
+ return m_eBuildSystem;
+}
+
+void CATModule2::SetCompileDefinitions( const string& sCompileDefinitions )
+{
+ LOG_LOW_FUNC_ENTRY( "CATModule2::SetCompileDefinitions" );
+ m_sCompileDefinitions = sCompileDefinitions;
+}
+
+string CATModule2::GetCompileDefinitions() const
+{
+ LOG_LOW_FUNC_ENTRY( "CATModule2::GetCompileDefinitions" );
+ return m_sCompileDefinitions;
+}
+
+void CATModule2::SetCompileInfoText( string sCompileInfoText )
+{
+ LOG_LOW_FUNC_ENTRY( "CATModule2::SetCompileInfoText" );
+ m_sCompileInfoText = sCompileInfoText;
+}
+string CATModule2::GetCompileInfoText() const
+{
+ LOG_LOW_FUNC_ENTRY( "CATModule2::GetCompileInfoText" );
+ return m_sCompileInfoText;
+}
+//EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/CATParseTraceFile.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,585 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Definitions for the class CATParseTraceFile.
+*
+*/
+
+
+#include "../inc/ATCommonDefines.h"
+#include "../inc/CATParseTraceFile.h"
+#include "../inc/catdatasaver.h"
+#include "../inc/CATDatParser.h"
+
+#include <time.h>
+
+#define MAIN_ID "PCSS"
+#define ALLOC_ID "ALLOC" // < V.1.6 allocation.
+#define ALLOCH_ID "ALLOCH" // Header of multi message allocation.
+#define ALLOCF_ID "ALLOCF" // Fragment of multi message allocation.
+#define FREE_ID "FREE"
+#define FREEH_ID "FREEH" // Header of multi message free.
+#define FREEF_ID "FREEF" // Fragment of multi message free.
+#define HANDLE_LEAK_ID "HANDLE_LEAK"
+
+const string ERROR_OCCURED = "ERROR_OCCURED"; // Error messages.
+const string INCORRECT_ATOOL_VERSION = "INCORRECT_ATOOL_VERSION";
+/**
+* Invalid characters in trace file line content.
+* These will be filtered out before actuall parsing of line.
+10 = LF
+13 = CR
+124 = |
+*/
+const char cINVALID_TRACE_FILE_CHARS[] = { 10, 13, 124 };
+
+// -----------------------------------------------------------------------------
+// CATParseTraceFile::CATParseTraceFile
+// Constructor.
+// -----------------------------------------------------------------------------
+CATParseTraceFile::CATParseTraceFile()
+{
+ LOG_FUNC_ENTRY("CATParseTraceFile::CATParseTraceFile");
+ m_DataSaver.SetPrintFlag( false );
+}
+
+// -----------------------------------------------------------------------------
+// CATParseTraceFile::StartParse
+// Main function to start trace parsing.
+// -----------------------------------------------------------------------------
+bool CATParseTraceFile::StartParse( const char* pFileName, const char* pOutputFileName )
+{
+ LOG_FUNC_ENTRY("CATParseTraceFile::StartParse");
+
+ // Return value, will be changed to true if process start found.
+ bool bRet = false;
+
+ // Check pointers
+ if ( pFileName == NULL )
+ return bRet;
+
+ if( pOutputFileName == NULL )
+ return bRet;
+
+ if ( ! FileExists( pFileName ) )
+ {
+ cout << AT_MSG << "Error, input file \""
+ << pFileName
+ << "\" does not exist." << endl;
+ return bRet;
+ }
+
+ // Open data file
+ ifstream in( pFileName );
+
+ // Check file opened ok
+ if ( !in.good() )
+ return false;
+
+ // Get stream size
+ size_t streamPos = in.tellg();
+ in.seekg( 0, ios::end);
+ size_t streamEnd = in.tellg();
+ in.seekg( 0, ios::beg);
+
+ //Origianl characters (not filtered).
+ char cOriginalLineFromFile[MAX_LINE_LENGTH];
+
+ vector<CProcessData> vProcessList;
+ int iProcessIDinList = -1;
+
+ bool bFileVersionSaved = false;
+ // Read lines
+ while( streamPos < streamEnd )
+ {
+ // Get one line. Don't use stream flags to determinate end of file
+ // it can be found too early because trace can contain "anything".
+ in.getline( cOriginalLineFromFile, MAX_LINE_LENGTH );
+
+ // Refresh position
+ streamPos = in.tellg();
+
+ // Check has bad bit flag raised. (i.e. device problems reading data)
+ if( in.bad() )
+ {
+ cout << AT_MSG << "Integrity error reading the trace file, reading aborted." << endl;
+ return false;
+ }
+ //Filtered characters.
+ char cLineFromFile[MAX_LINE_LENGTH];
+ char* pFiltered = cLineFromFile;
+
+ //Loop thru all characters in original line.
+ for( size_t i = 0 ; cOriginalLineFromFile[i] != 0 ; i++ )
+ {
+ //If character in line is not in invalid character array append it
+ //to filtered line.
+ if ( strchr( cINVALID_TRACE_FILE_CHARS, cOriginalLineFromFile[i] ) == 0 )
+ *pFiltered++ = cOriginalLineFromFile[i];
+ }
+ *pFiltered++ = 0; //Add null termination to filtered line.
+
+ if( !bFileVersionSaved && *cLineFromFile != 0 )
+ {
+ bFileVersionSaved = true;
+ m_DataSaver.AddString( AT_DATA_FILE_VERSION );
+ m_DataSaver.AddLineToLast();
+ }
+
+ // Is there main ID?
+ if( strstr( cLineFromFile, MAIN_ID ) != NULL )
+ {
+ string sRestOfLine( cLineFromFile );
+ string sTemp;
+
+ // Delete all characters before main ID
+ sRestOfLine.erase( 0, sRestOfLine.find( MAIN_ID ) );
+
+ // Get main ID
+ sTemp = GetStringUntilNextSpace( sRestOfLine );
+
+ // Is there more data in line?
+ if( sRestOfLine.empty() )
+ {
+ continue;
+ }
+
+ // Get next argument
+ sTemp = GetStringUntilNextSpace( sRestOfLine );
+ // This might be process id or error message
+ if ( sTemp.compare( ERROR_OCCURED ) == 0 )
+ {
+ // Api mismatch between s60 side and atool.exe
+ if ( sRestOfLine.find( INCORRECT_ATOOL_VERSION ) != string::npos )
+ {
+ cout << "Test run failed because version conflict between device binaries\nand the atool.exe version used to build the application." << endl;
+ size_t pS = sRestOfLine.find_first_of('[');
+ size_t pE = sRestOfLine.find_first_of(']');
+ size_t pSL = sRestOfLine.find_last_of('[');
+ size_t pEL = sRestOfLine.find_last_of(']');
+ if ( pS != string::npos && pE != string::npos && pSL != string::npos && pEL != string::npos )
+ {
+ string deviceVer = sRestOfLine.substr( pS+1, pE-pS-1 );
+ string atoolVer = sRestOfLine.substr( pSL+1, pEL-pSL-1 );
+ cout << "\tdevice: " << deviceVer << endl
+ << "\tatool.exe: " << atoolVer << endl;
+ }
+ }
+ else
+ cout << sRestOfLine << endl;
+ continue;
+ }
+ unsigned long iProcessID = _httoi( sTemp.c_str() );
+
+ iProcessIDinList = -1;
+ // Find process from list
+ for( unsigned int i = 0 ; i < vProcessList.size() ; i++ )
+ {
+ if( vProcessList[i].iProcessID == iProcessID )
+ {
+ iProcessIDinList = i;
+ break;
+ }
+ }
+ // Is Process ID found from list?
+ if( iProcessIDinList == -1 )
+ {
+ CProcessData ProcessData;
+ ProcessData.bProcessOnGoing = false;
+ ProcessData.iProcessID = iProcessID;
+ vProcessList.push_back( ProcessData );
+ iProcessIDinList = (int)vProcessList.size() - 1;
+ }
+
+ // Remove spaces from end of line
+ while( sRestOfLine[sRestOfLine.size()-1] == ' ' )
+ {
+ sRestOfLine.resize( sRestOfLine.size()-1 );
+ }
+
+ string sWholeTempLine( sRestOfLine );
+
+ // Get command
+ sTemp = GetStringUntilNextSpace( sRestOfLine );
+
+ // Use c style string for easy comparisong of command.
+ const char* pCommand = sTemp.c_str();
+
+ // Process start.
+ if( ! _stricmp( pCommand, LABEL_PROCESS_START ) )
+ {
+ bRet = true; // Set return value true we found start.
+ vProcessList[iProcessIDinList].vData.push_back( sWholeTempLine );
+ vProcessList[iProcessIDinList].bProcessOnGoing = true;
+ continue;
+ }
+
+ // Check is process ongoing if not skip other tags.
+ if( vProcessList[iProcessIDinList].bProcessOnGoing == false )
+ continue;
+
+ // "Old style" allocation (< v.1.6)
+ if( ! _stricmp( pCommand, ALLOC_ID ) )
+ {
+ // Add alloc
+ vProcessList[iProcessIDinList].Alloc( sRestOfLine );
+
+ // Subtests running?
+ vector<CSubTestData>::iterator viSubTestIter = vProcessList[iProcessIDinList].vSubTests.begin();
+ while( viSubTestIter != vProcessList[iProcessIDinList].vSubTests.end() )
+ {
+ if( viSubTestIter->bRunning )
+ {
+ // Save alloc also to sub test
+ viSubTestIter->Alloc( sRestOfLine );
+ }
+ viSubTestIter++;
+ }
+ }
+ else if ( ! _stricmp( pCommand, ALLOCH_ID ) )
+ {
+ // Add alloc
+ vProcessList[iProcessIDinList].AllocH( sRestOfLine );
+
+ // Subtests running?
+ vector<CSubTestData>::iterator viSubTestIter = vProcessList[iProcessIDinList].vSubTests.begin();
+ while( viSubTestIter != vProcessList[iProcessIDinList].vSubTests.end() )
+ {
+ if( viSubTestIter->bRunning )
+ {
+ // Save alloc also to sub test
+ viSubTestIter->AllocH( sRestOfLine );
+ }
+ viSubTestIter++;
+ }
+ }
+ // Allocation fragment (call stack).
+ else if ( ! _stricmp( pCommand, ALLOCF_ID ) )
+ {
+ // Add alloc fragment
+ vProcessList[iProcessIDinList].AllocF( sRestOfLine );
+
+ // Subtests running?
+ vector<CSubTestData>::iterator viSubTestIter = vProcessList[iProcessIDinList].vSubTests.begin();
+ while( viSubTestIter != vProcessList[iProcessIDinList].vSubTests.end() )
+ {
+ if( viSubTestIter->bRunning )
+ {
+ // Save alloc fragment also to sub test
+ viSubTestIter->AllocF( sRestOfLine );
+ }
+ viSubTestIter++;
+ }
+ }
+ // Command free
+ else if( ! _stricmp( pCommand, FREE_ID ) )
+ {
+ // Send free
+ vProcessList[iProcessIDinList].Free( sRestOfLine );
+
+ // Subtests running?
+ vector<CSubTestData>::iterator viSubTestIter = vProcessList[iProcessIDinList].vSubTests.begin();
+ while( viSubTestIter != vProcessList[iProcessIDinList].vSubTests.end() )
+ {
+ if( viSubTestIter->bRunning )
+ {
+ // Send free to subtest
+ viSubTestIter->Free( sRestOfLine );
+ }
+ viSubTestIter++;
+ }
+ }
+ // Header free.
+ else if( ! _stricmp( pCommand, FREEH_ID ) )
+ {
+ // Send free
+ vProcessList[iProcessIDinList].FreeH( sRestOfLine );
+
+ // Subtests running?
+ vector<CSubTestData>::iterator viSubTestIter = vProcessList[iProcessIDinList].vSubTests.begin();
+ while( viSubTestIter != vProcessList[iProcessIDinList].vSubTests.end() )
+ {
+ if( viSubTestIter->bRunning )
+ {
+ // Send free to subtest
+ viSubTestIter->FreeH( sRestOfLine );
+ }
+ viSubTestIter++;
+ }
+
+ }
+ else if( ! _stricmp( pCommand, FREEF_ID ) )
+ {
+ // Not used currently.
+ }
+ // Command process end
+ else if( ! _stricmp( pCommand, LABEL_PROCESS_END ) )
+ {
+ // Set process has ended.
+ vProcessList[iProcessIDinList].bProcessOnGoing = false;
+
+ // Save leaks
+ vector<string> vLeaks;
+ vector<string>::iterator viLeaks;
+ vProcessList[iProcessIDinList].GetLeakList( vLeaks );
+ for ( viLeaks = vLeaks.begin(); viLeaks != vLeaks.end(); viLeaks++ )
+ {
+ sTemp.clear();
+ sTemp.append( LABEL_MEM_LEAK );
+ sTemp.append( " " );
+ sTemp.append( *viLeaks );
+ vProcessList[iProcessIDinList].vData.push_back( sTemp );
+ }
+ vProcessList[iProcessIDinList].ClearAllocs();
+
+ vector<string>::iterator viHandleIter = vProcessList[iProcessIDinList].vHandleLeaks.begin();
+ // Print handle leaks
+ while( viHandleIter != vProcessList[iProcessIDinList].vHandleLeaks.end() )
+ {
+ sTemp.clear();
+ sTemp.append( viHandleIter->c_str() );
+ vProcessList[iProcessIDinList].vData.push_back( sTemp );
+ viHandleIter++;
+ }
+ // Clear handle leaks from list
+ vProcessList[iProcessIDinList].vHandleLeaks.clear();
+
+ vector<CSubTestData>::iterator viSubTestIter = vProcessList[iProcessIDinList].vSubTests.begin();
+ // Print sub test leaks
+ while( viSubTestIter != vProcessList[iProcessIDinList].vSubTests.end() )
+ {
+ // Print sub test start
+ string sLine( LABEL_TEST_START ); sLine.append( " " );
+ sLine.append( viSubTestIter->sStartTime ); sLine.append( " " );
+ sLine.append( viSubTestIter->sSubTestName ); sLine.append( " " );
+ sLine.append( viSubTestIter->sSubTestStartHandleCount );
+ vProcessList[iProcessIDinList].vData.push_back( sLine );
+ sLine.clear();
+
+ // DLL Loads.
+ for( vector<string>::iterator it = viSubTestIter->vData.begin();
+ it != viSubTestIter->vData.end(); it++ )
+ {
+ vProcessList[iProcessIDinList].vData.push_back( (*it) );
+ }
+
+ // Subtest leaks.
+ vector<string> vSubLeaks;
+ vector<string>::iterator viSubLeaks;
+ viSubTestIter->GetLeakList( vSubLeaks );
+ for ( viSubLeaks = vSubLeaks.begin(); viSubLeaks != vSubLeaks.end(); viSubLeaks++ )
+ {
+ sLine.append( LABEL_MEM_LEAK );
+ sLine.append( " " );
+ sLine.append( *viSubLeaks );
+ vProcessList[iProcessIDinList].vData.push_back( sLine );
+ sLine.clear();
+ }
+ viSubTestIter->ClearAllocs();
+
+ if( !viSubTestIter->sEndTime.empty() )
+ {
+ // Print sub test end
+ sLine.append( LABEL_TEST_END ); sLine.append( " " );
+ sLine.append( viSubTestIter->sEndTime ); sLine.append( " " );
+ sLine.append( viSubTestIter->sSubTestName ); sLine.append( " " );
+ sLine.append( viSubTestIter->sSubTestEndHandleCount );
+ vProcessList[iProcessIDinList].vData.push_back( sLine );
+ }
+ viSubTestIter++;
+ }
+
+ // Clear sub tests from list
+ vProcessList[iProcessIDinList].vSubTests.clear();
+ vProcessList[iProcessIDinList].vData.push_back( sWholeTempLine );
+ }
+ else if( ! _stricmp( pCommand, LABEL_HANDLE_LEAK ) )
+ {
+ // Make whole line
+ sTemp.append( " " );
+ sTemp.append( sRestOfLine );
+ vProcessList[iProcessIDinList].vHandleLeaks.push_back( sTemp );
+ }
+ else if( ! _stricmp( pCommand, LABEL_DLL_LOAD ) )
+ {
+ // Add module load to process data.
+ vProcessList[iProcessIDinList].vData.push_back( sWholeTempLine );
+ // Add module load to subtest data if test running.
+ for( vector<CSubTestData>::iterator it = vProcessList[iProcessIDinList].vSubTests.begin();
+ it != vProcessList[iProcessIDinList].vSubTests.end(); it++ )
+ {
+ if( it->bRunning )
+ it->vData.push_back( sWholeTempLine );
+ }
+
+ }
+ else if( ! _stricmp( pCommand, LABEL_DLL_UNLOAD ) )
+ {
+ // Add module load to process data.
+ vProcessList[iProcessIDinList].vData.push_back( sWholeTempLine );
+ // Add module unload to subtest data if test running.
+ for( vector<CSubTestData>::iterator it = vProcessList[iProcessIDinList].vSubTests.begin();
+ it != vProcessList[iProcessIDinList].vSubTests.end(); it++ )
+ {
+ if( it->bRunning )
+ it->vData.push_back( sWholeTempLine );
+ }
+ }
+ else if( sTemp.find( LABEL_LOGGING_CANCELLED ) != string::npos ||
+ sTemp.find( LABEL_PROCESS_END ) != string::npos || sTemp.find( LABEL_ERROR_OCCURED ) != string::npos ||
+ sTemp.find( LABEL_HANDLE_LEAK ) != string::npos )
+ {
+ vProcessList[iProcessIDinList].vData.push_back( sWholeTempLine );
+ }
+ else if( ! _stricmp( pCommand, LABEL_TEST_START ) )
+ {
+ bRet = true; // Set return value true we found start.
+ // Get sub test time
+ string sSubTestTime = GetStringUntilNextSpace( sRestOfLine );
+ // Get sub test name
+ string sSubTestName = GetStringUntilNextSpace( sRestOfLine );
+ // Get sub test start handle count
+ string sSubTestStartHandleCount = GetStringUntilNextSpace( sRestOfLine );
+
+ CSubTestData SubTestData;
+ SubTestData.bRunning = true;
+ SubTestData.sStartTime = sSubTestTime;
+ SubTestData.sSubTestName = sSubTestName;
+ SubTestData.sSubTestStartHandleCount = sSubTestStartHandleCount.c_str();
+
+ vProcessList[iProcessIDinList].vSubTests.push_back( SubTestData );
+ }
+ else if( ! _stricmp( pCommand, LABEL_TEST_END ) )
+ {
+ // Get sub test time
+ string sSubTestEnd = GetStringUntilNextSpace( sRestOfLine );
+ // Get sub test name
+ string sSubTestName = GetStringUntilNextSpace( sRestOfLine );
+ // Get sub test end handle count
+ string sSubTestEndHandleCount = GetStringUntilNextSpace( sRestOfLine );
+
+ // Find subtest
+ vector<CSubTestData>::iterator viSubTestIter = vProcessList[iProcessIDinList].vSubTests.begin();
+ while( viSubTestIter != vProcessList[iProcessIDinList].vSubTests.end() )
+ {
+ if( viSubTestIter->sSubTestName == sSubTestName && viSubTestIter->sEndTime.empty() )
+ {
+ viSubTestIter->sEndTime = sSubTestEnd;
+ viSubTestIter->bRunning = false;
+ viSubTestIter->sSubTestEndHandleCount = sSubTestEndHandleCount.c_str();
+ }
+ viSubTestIter++;
+ }
+ }
+ }
+ }
+
+ // Print all saved data from processes
+ for( unsigned int i = 0 ; i < vProcessList.size() ; i++ )
+ {
+ // Print saved lines
+ for( unsigned int iDataCounter = 0 ; iDataCounter < vProcessList[i].vData.size() ; iDataCounter++ )
+ {
+ m_DataSaver.AddString( vProcessList[i].vData[iDataCounter].c_str() );
+ m_DataSaver.AddLineToLast();
+ }
+
+ string sTemp;
+
+ // Save leaks
+ vector<string> vLeaks;
+ vector<string>::iterator viLeaks;
+ vProcessList[i].GetLeakList( vLeaks );
+ for ( viLeaks = vLeaks.begin(); viLeaks != vLeaks.end(); viLeaks++ )
+ {
+ sTemp.clear();
+ sTemp.append( LABEL_MEM_LEAK );
+ sTemp.append( " " );
+ sTemp.append( *viLeaks );
+ m_DataSaver.AddString( sTemp.c_str() );
+ m_DataSaver.AddLineToLast();
+ }
+
+ vector<string>::iterator viHandleIter = vProcessList[i].vHandleLeaks.begin();
+ // Print handle leaks, if there is data left, there was no process end.
+ while( viHandleIter != vProcessList[i].vHandleLeaks.end() )
+ {
+ sTemp.clear();
+ sTemp.append( viHandleIter->c_str() );
+ m_DataSaver.AddString( sTemp.c_str() );
+ m_DataSaver.AddLineToLast();
+ viHandleIter++;
+ }
+ vector<CSubTestData>::iterator viSubTestIter = vProcessList[i].vSubTests.begin();
+ // Print sub test data, if there is data left, there was no process end.
+ while( viSubTestIter != vProcessList[i].vSubTests.end() )
+ {
+ // Print sub test start
+ string sLine( LABEL_TEST_START ); sLine.append( " " );
+ sLine.append( viSubTestIter->sStartTime ); sLine.append( " " );
+ sLine.append( viSubTestIter->sSubTestName ); sLine.append( " " );
+ sLine.append( viSubTestIter->sSubTestStartHandleCount );
+ m_DataSaver.AddString( sLine.c_str() );
+ m_DataSaver.AddLineToLast();
+ sLine.clear();
+
+ // DLL Loads.
+ for( vector<string>::iterator it = viSubTestIter->vData.begin();
+ it != viSubTestIter->vData.end(); it++ )
+ {
+ m_DataSaver.AddString( (*it).c_str() );
+ m_DataSaver.AddLineToLast();
+ }
+
+ // Subtest leaks.
+ vector<string> vSubLeaks;
+ vector<string>::iterator viSubLeaks;
+ viSubTestIter->GetLeakList( vSubLeaks );
+ for ( viSubLeaks = vSubLeaks.begin(); viSubLeaks != vSubLeaks.end(); viSubLeaks++ )
+ {
+ sLine.append( LABEL_MEM_LEAK );
+ sLine.append( " " );
+ sLine.append( *viSubLeaks );
+ m_DataSaver.AddString( sLine.c_str() );
+ m_DataSaver.AddLineToLast();
+ sLine.clear();
+ }
+
+ // Print sub test end
+ sLine.append( LABEL_TEST_END ); sLine.append( " " );
+ sLine.append( viSubTestIter->sEndTime ); sLine.append( " " );
+ sLine.append( viSubTestIter->sSubTestName ); sLine.append( " " );
+ sLine.append( viSubTestIter->sSubTestEndHandleCount );
+ m_DataSaver.AddString( sLine.c_str() );
+ m_DataSaver.AddLineToLast();
+
+ viSubTestIter++;
+ }
+ }
+ // Save lines to file.
+ m_DataSaver.SaveLinesToFile( pOutputFileName, TEXT_DATA );
+ // Close file.
+ in.close();
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+// CATParseTraceFile::GetDataSaver
+// Gets data saver object.
+// -----------------------------------------------------------------------------
+CATDataSaver* CATParseTraceFile::GetDataSaver(void)
+{
+ LOG_LOW_FUNC_ENTRY("CATParseTraceFile::GetDataSaver");
+ return &m_DataSaver;
+}
+//EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/CATParseXML.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,148 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Definitions for the class CATParseXML.
+*
+*/
+
+
+#include "../inc/CATParseXML.h"
+#include "../inc/catdatasaver.h"
+#include "../inc/CATBase.h"
+
+#include <xercesc/parsers/XercesDOMParser.hpp>
+
+const char cCanNotFindEpocroot[] = "Can not find EPOCROOT from devices.xml.\n";
+const char cErrorInDeviceXml[] = "Error in devices.xml!\n";
+const char cCanNotFind[] = "Can not find file: %s.\n";
+
+CATParseXML::CATParseXML(void)
+{
+ LOG_FUNC_ENTRY("CATParseXML::CATParseXML");
+ try
+ {
+ xercesc::XMLPlatformUtils::Initialize();
+ }
+ catch ( ... )
+ {
+ //Print error
+ printf("XML initialization failed.\n");
+ }
+}
+
+CATParseXML::~CATParseXML(void)
+{
+ LOG_FUNC_ENTRY("CATParseXML::~CATParseXML");
+}
+
+// -----------------------------------------------------------------------------
+// CATParseXML::GetEpocRootPathFromXML
+// Find epocroot path in xml file
+// -----------------------------------------------------------------------------
+string CATParseXML::GetEpocRootPathFromXML(const char* pSourcePath)
+{
+ LOG_FUNC_ENTRY("CATParseXML::GetEpocRootPathFromXML");
+ string sEpocRootPath;
+ // Check that source exists
+ if ( ! CATBase::FileExists( pSourcePath ) )
+ {
+ LOG_STRING( "Source xml not found." );
+ return sEpocRootPath;
+ }
+ try
+ {
+ xercesc::XercesDOMParser* parser = new xercesc::XercesDOMParser();
+ xercesc::DOMDocument* pDomDoc;
+
+ // Get devices.xml document
+ parser->parse( pSourcePath );
+ pDomDoc = parser->getDocument();
+
+ // Get root element
+ xercesc::DOMElement* pRootElem = pDomDoc->getDocumentElement();
+
+ if( pRootElem )
+ {
+ // Get all "device" elements
+ LPWSTR wTemp = CATDataSaver::CharToWChar( "device" );
+ xercesc::DOMNodeList* pDeviceNodeList = pRootElem->getElementsByTagName( wTemp );
+ if( wTemp )
+ delete[] wTemp;
+
+ // Find default SDK
+
+ bool bEpocRootFound = false;
+ int iLength = pDeviceNodeList->getLength();
+ for( int i = 0 ; i < iLength ; i++ )
+ {
+ xercesc::DOMNode* pDeviceNode = pDeviceNodeList->item(i);
+
+ xercesc::DOMNamedNodeMap* pAttributeList = pDeviceNode->getAttributes();
+
+ // Find attribute "default"
+
+ int iAttribListLength = pAttributeList->getLength();
+ for( int x = 0 ; x < iAttribListLength ; x++ )
+ {
+ xercesc::DOMNode* pAttribNode = pAttributeList->item(x);
+ const LPWSTR pNodeName = (const LPWSTR)pAttribNode->getNodeName();
+
+ if( wcscmp( pNodeName, L"default" ) == 0 )
+ {
+ const LPWSTR pNodeValue = (const LPWSTR)pAttribNode->getNodeValue();
+
+ // Find node value 'yes'
+ if( wcscmp( pNodeValue, L"yes" ) == 0 )
+ {
+ // Find <epocroot> node
+ xercesc::DOMNode* pChildNode = pDeviceNode->getFirstChild();
+ if( !pChildNode )
+ break;
+ while( !bEpocRootFound )
+ {
+ if( wcscmp( pChildNode->getNodeName() , L"epocroot" ) == 0 )
+ {
+ bEpocRootFound = true;
+
+ // Node value is child text node
+ xercesc::DOMNode* pTempTextNode = pChildNode->getFirstChild();
+ const LPWSTR pPathNodeValue = (const LPWSTR)pTempTextNode->getNodeValue();
+
+ CATDataSaver::WCharToChar( sEpocRootPath, pPathNodeValue );
+
+ break;
+ }
+ pChildNode = pChildNode->getNextSibling();
+ if( !pChildNode )
+ break;
+ }
+ } // If node value yes
+ } // If node name default
+ if( bEpocRootFound )
+ break;
+ } // for x
+ if( bEpocRootFound )
+ break;
+ } // for i
+ }
+ if(parser)
+ delete parser; //lint !e118
+ xercesc::XMLPlatformUtils::Terminate();
+ }
+ catch (...)
+ {
+ printf("XML parsing failed.");
+ }
+ return sEpocRootPath;
+}
+// End of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/CATProject.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,2413 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Class representing a project.
+*
+*/
+
+
+#include "../inc/CATProject.h"
+#include "../inc/CATModule2.h"
+#include "../inc/CATParseTraceFile.h"
+#include "../inc/CATDatParser.h"
+
+//dbghelp.dll version function.
+extern int showDbgHelpVersionInfo( bool showVersion );
+
+// ----------------------------------------------------------------------------
+// CATProject::CATProject()
+// ----------------------------------------------------------------------------
+CATProject::CATProject()
+{
+ LOG_FUNC_ENTRY("CATProject::CATProject");
+
+ m_bUninstrumented = true;
+ m_bAbldTest = false;
+
+ // Use windows api to acquire current directory info.
+ GetCurrentDirectory( MAX_LINE_LENGTH, m_cCurrentDir );
+
+ m_eBuildSystem = SBS_V1;
+ m_eBuildType = UDEB;
+ m_eLoggingMode = TRACE;
+ m_eMode = NOT_DEFINED;
+
+ m_iLoggingLevel = 3;
+
+ m_pAnalyzer = 0;
+
+ m_sBinaryTarget = "";
+ m_sBuildCommand = "";
+ m_sDataFile = "";
+ m_sDataFileOutput = "";
+ m_sDataFileTemp = "";
+ m_sEpocRoot = "\\";
+ m_sMakeFile = "";
+ m_sPlatform = "";
+ m_sS60FileName = "";
+ m_sTargetModule = "";
+ m_sVariant = "";
+
+ m_vRomSymbolFiles.clear();
+ m_vModules.clear();
+ m_vStaticLibraries.clear();
+ m_vTargetModules.clear();
+ m_vUnsupportedModules.clear();
+}
+
+// ----------------------------------------------------------------------------
+// CATProject::~CATProject()
+// ----------------------------------------------------------------------------
+CATProject::~CATProject()
+{
+ LOG_FUNC_ENTRY("CATProject::~CATProject");
+
+ CleanModuleVectors();
+
+ // Delete analyzer
+ if ( m_pAnalyzer )
+ delete m_pAnalyzer;
+
+ // Temporary datafile
+ if ( !m_sDataFileTemp.empty() )
+ {
+ if ( FileExists( m_sDataFileTemp.c_str() ) )
+ FileDelete( m_sDataFileTemp, false );
+ }
+}
+
+bool CATProject::SetArguments( ARGUMENTS& arguments )
+{
+ LOG_FUNC_ENTRY("CATProject::SetArguments");
+ bool bRet = true;
+
+ //Project mode.
+ if( arguments.eHookSwitch == HOOK_INTERNAL )
+ {
+ SetMode( CATProject::COMPILE );
+ SetLoggingMode( CATProject::FILE );
+ }
+ else if ( arguments.eHookSwitch == HOOK_EXTERNAL )
+ {
+ SetMode( CATProject::COMPILE );
+ SetLoggingMode( CATProject::TRACE );
+ }
+ else if ( arguments.eHookSwitch == HOOK_EXTERNAL_FAST )
+ {
+ SetMode( CATProject::COMPILE );
+ SetLoggingMode( CATProject::TRACE_FAST );
+ }
+ /* Extension*/
+ else if ( arguments.eHookSwitch == HOOK_EXTENSION_INTERNAL )
+ {
+ SetMode( CATProject::INSTRUMENT );
+ SetLoggingMode( CATProject::FILE );
+ }
+ else if ( arguments.eHookSwitch == HOOK_EXTENSION_EXTERNAL )
+ {
+ SetMode( CATProject::INSTRUMENT );
+ SetLoggingMode( CATProject::TRACE );
+ }
+ else if ( arguments.eHookSwitch == HOOK_EXTENSION_EXTERNAL_FAST )
+ {
+ SetMode( CATProject::INSTRUMENT );
+ SetLoggingMode( CATProject::TRACE_FAST );
+ }
+ else if ( arguments.eHookSwitch == HOOK_EXTENSION_UNINSTRUMENT )
+ {
+ SetMode( CATProject::UNINSTRUMENT );
+ }
+ else if ( arguments.eHookSwitch == HOOK_EXTENSION_FAILED )
+ {
+ SetMode( CATProject::UNINSTRUMENT_FAILED );
+ }
+ //Return if uninstrumenting because no other arguments are set.
+ if ( GetMode() == CATProject::UNINSTRUMENT
+ || GetMode() == CATProject::UNINSTRUMENT_FAILED )
+ {
+ return bRet;
+ }
+
+ // No build / instrument.
+ if ( arguments.HOOK.bNoBuild )
+ SetMode( CATProject::INSTRUMENT_CONSOLE );
+
+ // Call stack sizes
+ SetAllocCallStackSize( arguments.HOOK.iAllocCallStackSize );
+ SetFreeCallStackSize( arguments.HOOK.iFreeCallStackSize );
+
+ //Build system.
+ if ( arguments.HOOK.iBuildSystem == 1 )
+ SetBuildSystem( CATProject::SBS_V1 );
+ else if ( arguments.HOOK.iBuildSystem == 2 )
+ SetBuildSystem( CATProject::SBS_V2 );
+
+ //Test module build only
+ if ( arguments.HOOK.bAbldTest == true )
+ m_bAbldTest = true;
+
+ //Platform.
+ if ( !_stricmp( arguments.HOOK.sPlatform.c_str(), "armv5" ) )
+ SetPlatform( arguments.HOOK.sPlatform );
+ else if ( !_stricmp( arguments.HOOK.sPlatform.c_str(), "gcce" ) )
+ SetPlatform( arguments.HOOK.sPlatform );
+ else if ( !_stricmp( arguments.HOOK.sPlatform.c_str(), "winscw" ) )
+ SetPlatform( arguments.HOOK.sPlatform );
+ else
+ {
+ LOG_STRING( "Error, no supported platform specified (armv5/gcce/winscw).");
+ bRet = false;
+ }
+
+ //BuildType.
+ if ( !_stricmp( arguments.HOOK.sBuildType.c_str(), "urel" ) )
+ SetBuildType( CATProject::UREL );
+ else if ( !_stricmp( arguments.HOOK.sBuildType.c_str(), "udeb" ) )
+ SetBuildType( CATProject::UDEB );
+ else
+ {
+ LOG_STRING( "Error, no build type specified.");
+ bRet = false;
+ }
+
+ //Internal data file.
+ if ( arguments.HOOK.bDataFileName )
+ SetS60FileName( arguments.HOOK.sDataFileName );
+
+ //Build command.
+ if ( arguments.HOOK.sBuildCmd.empty() && (
+ GetMode() == CATProject::COMPILE ||
+ GetMode() == CATProject::INSTRUMENT ||
+ GetMode() == CATProject::INSTRUMENT_CONSOLE
+ ))
+ {
+ cout << AT_MSG << "Error, no build command specified." << endl;
+ bRet = false;
+ }
+
+ SetBuildCommand( arguments.HOOK.sBuildCmd );
+
+ //Variant.
+ SetVariant( arguments.HOOK.sFeatureVariant );
+
+ //Target programs.
+ SetTargetModules( arguments.HOOK.vTargetPrograms );
+
+ return bRet;
+}
+
+void CATProject::CleanModuleVectors()
+{
+ LOG_FUNC_ENTRY("CATProject::CleanModuleVectors");
+ // delete modules from vector.
+ for( size_t i = 0; i < m_vModules.size() ; i++ )
+ delete m_vModules[i];
+ m_vModules.clear();
+
+ // Delete modules from vector (unsupported).
+ for( size_t i = 0; i < m_vUnsupportedModules.size() ; i++ )
+ delete m_vUnsupportedModules[i];
+ m_vUnsupportedModules.clear();
+
+ // Delete modules from static library vector.
+ for( size_t i = 0; i < m_vStaticLibraries.size() ; i++ )
+ delete m_vStaticLibraries[i];
+ m_vStaticLibraries.clear();
+}
+// ----------------------------------------------------------------------------
+// CATProject::Run
+// ----------------------------------------------------------------------------
+int CATProject::Run()
+{
+ LOG_FUNC_ENTRY("CATProject::Run");
+ int iReturnCode = 0;
+ switch( m_eMode )
+ {
+ case COMPILE:
+ // Run compile
+ iReturnCode = RunCompile();
+ if ( iReturnCode == AT_RETURN_CODE::READ_MAKEFILE_ERROR
+ || iReturnCode == AT_RETURN_CODE::KERNEL_SIDE_MODULE_ERROR
+ || iReturnCode == AT_RETURN_CODE::INVALID_MMP_DEFINED )
+ {
+ DeleteTemporaryDirs();
+ DirDelete( AT_TEMP_DIR, true );
+ }
+ else
+ {
+ DisplayCompileSummary();
+ DisplayBuildSummary();
+ }
+ break;
+ case CLEAN:
+ iReturnCode = RunClean();
+ break;
+ case ANALYZE:
+ iReturnCode = RunAnalyze();
+ break;
+ case INSTRUMENT:
+ iReturnCode = RunInstrument();
+ break;
+ case INSTRUMENT_CONSOLE:
+ iReturnCode = RunInstrumentConsole();
+ if ( iReturnCode == AT_RETURN_CODE::READ_MAKEFILE_ERROR
+ || iReturnCode == AT_RETURN_CODE::KERNEL_SIDE_MODULE_ERROR )
+ {
+ DeleteTemporaryDirs();
+ DirDelete( AT_TEMP_DIR, true );
+ }
+ else
+ {
+ DisplayBuildSummary();
+ }
+ break;
+ case UNINSTRUMENT:
+ iReturnCode = RunUninstrument();
+ // Show summary
+ DisplayCompileSummary();
+ DisplayBuildSummary();
+ break;
+ case UNINSTRUMENT_CONSOLE:
+ iReturnCode = RunUninstrumentConsole();
+ // Show summary
+ DisplayCompileSummary();
+ DisplayBuildSummary();
+ break;
+ case UNINSTRUMENT_FAILED:
+ iReturnCode = RunUninstrumentFailed();
+ // Display message
+ cout << AT_MSG << "Build aborted, because project contains compile error(s)."
+ << endl;
+ break;
+ default:
+ cout << AT_MSG << "Error, mode not supported / implemented." << endl;
+ break;
+ }
+ // Error messages
+ switch( iReturnCode )
+ {
+ case AT_RETURN_CODE::MAKEFILE_ERROR:
+ cout << AT_MSG << "Error, creating/reading makefiles." << endl;
+ break;
+ case AT_RETURN_CODE::COMPILE_ERROR:
+ cout << AT_MSG << "Error, compiling project." << endl;
+ break;
+ case AT_RETURN_CODE::UNKNOWN:
+ cout << AT_MSG << "Error, unknown." << endl;
+ break;
+ case AT_RETURN_CODE::WRONG_DATA_FILE_VERSION:
+ cout << AT_MSG << "unable to analyze the data file.\n";
+ cout << AT_MSG << "wrong data file version.\n";
+ break;
+ case AT_RETURN_CODE::INVALID_DATA_FILE:
+ cout << AT_MSG << "Error, invalid datafile." << endl;
+ break;
+ case AT_RETURN_CODE::RELEASABLES_ERROR:
+ cout << AT_MSG << "Error, copying releasable(s)." << endl;
+ break;
+ case AT_RETURN_CODE::RESTORE_MODULES_ERROR:
+ cout << AT_MSG << "Error, restoring mmp file(s)." << endl;
+ break;
+ case AT_RETURN_CODE::CREATING_TEMP_CPP_ERROR:
+ cout << AT_MSG << "Error, creating temporary cpp file(s)." << endl;
+ break;
+ case AT_RETURN_CODE::CLEANING_TEMP_ERROR:
+ cout << AT_MSG << "Error, cleaning temporary dir(s)." << endl;
+ break;
+ case AT_RETURN_CODE::READ_MAKEFILE_ERROR:
+ cout << AT_MSG << "Error, reading makefile." << endl;
+ break;
+ case AT_RETURN_CODE::MODIFY_MODULES_ERROR:
+ cout << AT_MSG << "Error, modifying mmp file(s)." << endl;
+ break;
+ case AT_RETURN_CODE::INVALID_MMP_DEFINED:
+ break;
+ case AT_RETURN_CODE::WRITE_ATTRIBUTES_ERROR:
+ cout << AT_MSG << "Error, writing attributes." << endl;
+ break;
+ case AT_RETURN_CODE::READ_ATTRIBUTES_ERROR:
+ cout << AT_MSG << "Error, reading project configuration. Instrument project again." << endl;
+ break;
+ case AT_RETURN_CODE::EMPTY_DATA_FILE:
+ cout << AT_MSG << "Error, no data to be analyzed." << endl;
+ break;
+ case AT_RETURN_CODE::NO_SUPPORTED_MODULES_ERROR:
+ cout << AT_MSG << "Error, no modules found with supported target type." << endl;
+ break;
+ case AT_RETURN_CODE::KERNEL_SIDE_MODULE_ERROR:
+ cout << AT_MSG << "Error, kernel side component found component. Build/instrument aborted." << endl;
+ break;
+ }
+ return iReturnCode;
+}
+// ----------------------------------------------------------------------------
+// CATProject::RunRecoveryAndExit()
+// Restore modules quick and exit. Used when user wants to kill/end process.
+// ----------------------------------------------------------------------------
+int CATProject::RunRecoveryAndExit()
+{
+ LOG_FUNC_ENTRY("CATProject::RunRecoveryAndExit");
+ cout << AT_MSG << "Error, user requested exit." << endl;
+ VerifyAndRecoverModules();
+ DeleteTemporaryDirs();
+ DirDelete( AT_TEMP_DIR, true );
+ cout << AT_MSG << "Exit." << endl;
+ return AT_RETURN_CODE::USER_ISSUED_EXIT;
+}
+
+// ----------------------------------------------------------------------------
+// CATProject::IsUninstrumented()
+// Reads projects configuration file if it exists.
+// Return false in case the data contains information that project is
+// uninstrumented. Otherwise returns always true.
+// ----------------------------------------------------------------------------
+bool CATProject::IsUninstrumented()
+{
+ LOG_FUNC_ENTRY("CATProject::IsUninstrumented");
+ string sCfgFile( AT_TEMP_DIR );
+ sCfgFile.append( "\\" );
+ sCfgFile.append( AT_PROJECT_ATTRIBUTES_FILE_NAME );
+ if ( ! FileExists( sCfgFile.c_str() ) )
+ return true;
+ if( !ReadAttributes() )
+ {
+ LOG_STRING( "Error, reading project.cfg file." );
+ return false;
+ }
+ return m_bUninstrumented;
+}
+
+// ----------------------------------------------------------------------------
+// CATProject::RunCompile()
+// Helper functions to run different modes.
+// ----------------------------------------------------------------------------
+int CATProject::RunCompile()
+{
+ LOG_FUNC_ENTRY("CATProject::RunCompile");
+ // Store attributes
+ if( ! MakeTempDirIfNotExist() )
+ return AT_RETURN_CODE::WRITE_ATTRIBUTES_ERROR;
+ if ( ! WriteAttributes() )
+ return AT_RETURN_CODE::WRITE_ATTRIBUTES_ERROR;
+ // Create makefile
+ if ( ! CreateMakeFile() )
+ return AT_RETURN_CODE::MAKEFILE_ERROR;
+ // Read makefile to get project attributes
+ if ( ! ReadMakeFile() )
+ return AT_RETURN_CODE::READ_MAKEFILE_ERROR;
+ // Filter unsupported
+ FilterModules();
+ // Check that we have some "valid" modules to hook
+ if ( m_vModules.size() == 0 &&( m_vUnsupportedModules.size() > 0 || m_vStaticLibraries.size() > 0 ) )
+ return AT_RETURN_CODE::NO_SUPPORTED_MODULES_ERROR;
+ // Check is possible target module defined in project
+ if ( ! IsTargetModuleInProject() )
+ return AT_RETURN_CODE::INVALID_MMP_DEFINED;
+ // Clean temporary dirs of modules
+ if ( ! CleanTemporaryDirs() )
+ return AT_RETURN_CODE::CLEANING_TEMP_ERROR;
+ // Create temporary cpps for modulse
+ if (! CreateTemporaryCpps() )
+ return AT_RETURN_CODE::CREATING_TEMP_CPP_ERROR;
+ // Hook modules
+ if (! ModifyModules() )
+ return AT_RETURN_CODE::MODIFY_MODULES_ERROR;
+ // Compile all
+ // Return code
+ int iRetCode = AT_RETURN_CODE::OK;
+ // Compile
+ if ( ! Compile() )
+ iRetCode = AT_RETURN_CODE::COMPILE_ERROR;
+ // Listings
+ if (! CreateListings() )
+ iRetCode = AT_RETURN_CODE::COMPILE_ERROR;
+ // Releasables
+ if (! CopyReleasables() )
+ iRetCode = AT_RETURN_CODE::RELEASABLES_ERROR;
+ // Restore "unhook" modules
+ if (! RestoreModules() )
+ iRetCode = AT_RETURN_CODE::RESTORE_MODULES_ERROR;
+ // Return error code OK
+ return iRetCode;
+}
+
+int CATProject::RunClean()
+{
+ LOG_FUNC_ENTRY("CATProject::RunClean");
+ int iRetCode = AT_RETURN_CODE::OK;
+ bool bNothingFound = true;
+ // Read attributes.
+ if ( ReadAttributes() )
+ {
+ bNothingFound = false;
+ if ( m_eBuildSystem == SBS_V1 )
+ InitSbs1MakeFileWithPathToTemp();
+ // Read makefile to get project attributes
+ if( ReadMakeFile() )
+ {
+ // Filter unsupported
+ FilterModules();
+ // Restore modules to make sure no changes left
+ if( VerifyAndRecoverModules() )
+ {
+ // Run reallyclean
+ switch ( m_eBuildSystem )
+ {
+ case SBS_V1:
+ RunReallyCleanSbs1();
+ break;
+ case SBS_V2:
+ RunReallyCleanSbs2();
+ break;
+ default:
+ break;
+ }
+ // Delete temporary dirs of modules
+ if(! DeleteTemporaryDirs() )
+ {
+
+ }
+ }
+ else
+ {
+
+ }
+ }
+ }
+ // Projects
+ if ( ! DirDelete( AT_TEMP_DIR, true ) )
+ {
+
+ }
+ else
+ bNothingFound = false;
+
+ if ( bNothingFound )
+ cout << AT_MSG << "Nothing found to clean." << endl;
+ else
+ cout << AT_MSG << "Cleaning done." << endl;
+ return iRetCode;
+}
+
+int CATProject::RunAnalyze()
+{
+ LOG_FUNC_ENTRY("CATProject::RunAnalyze");
+
+ // Parse data file if it is trace.
+ if ( !IsDataFile( m_sDataFile ) )
+ {
+ m_sDataFileTemp.clear();
+ m_sDataFileTemp.append( m_sDataFile );
+ m_sDataFileTemp.append( ".atool" );
+ cout << AT_MSG << "Parsing trace file..." << endl;
+ CATParseTraceFile Parser;
+ if ( ! Parser.StartParse( m_sDataFile.c_str(), m_sDataFileTemp.c_str() ) )
+ {
+ return AT_RETURN_CODE::EMPTY_DATA_FILE;
+ }
+ m_sDataFile = m_sDataFileTemp;
+ }
+
+ // Init makefile member for this run mode.
+ if ( m_eBuildSystem == SBS_V1 )
+ InitSbs1MakeFileWithPathToTemp();
+ // Read makefile to get project attributes
+ if( ! ReadMakeFile() )
+ {
+ cout << AT_MSG << "Error, cannot find project build with AnalyzeTool." << endl;
+ }
+ else
+ FilterModules();
+
+ #ifndef ADDR2LINE
+ // Initialize modules locating code lines.
+ for( size_t i = 0 ; i < m_vModules.size() ; i++ )
+ {
+ m_vModules.at(i)->InitializeAddressToLine();
+ }
+ #endif
+
+ // Create analyzer
+ m_pAnalyzer = new CATDatParser( &m_vModules );
+
+ // Pass some info from project if it "exists" to analyzer.
+ if ( m_vModules.size() > 0 )
+ {
+ // Pass platform.
+ m_pAnalyzer->SetProjectPlatform( m_sPlatform );
+ // Pass build type.
+ m_pAnalyzer->SetProjectBuildType( m_eBuildType );
+ }
+
+ // Set file.
+ m_pAnalyzer->SetInputFile( m_sDataFile );
+
+ // Set rom symbol file.
+ m_pAnalyzer->SetRomSymbolFiles( m_vRomSymbolFiles );
+
+ // Set output file if specified
+ if ( ! m_sDataFileOutput.empty() )
+ {
+ m_pAnalyzer->SetOutputFile( m_sDataFileOutput );
+ }
+ // Set log level
+ m_pAnalyzer->SetLogLevel( m_iLoggingLevel );
+
+ // Analyze
+ return m_pAnalyzer->Analyze();
+}
+
+int CATProject::RunInstrument()
+{
+ LOG_FUNC_ENTRY("CATProject::RunInstrument");
+ // Store attributes
+ if( ! MakeTempDirIfNotExist() )
+ return AT_RETURN_CODE::WRITE_ATTRIBUTES_ERROR;
+ if ( ! WriteAttributes() )
+ return AT_RETURN_CODE::WRITE_ATTRIBUTES_ERROR;
+ if ( m_eBuildSystem == SBS_V1 )
+ {
+ // Initialize level 1 make file member.
+ if ( ! InitSbs1MakeFileWithPath() )
+ return AT_RETURN_CODE::MAKEFILE_ERROR;
+ // Copy it to temporary folder.
+ CopyMakeFileSbs1ToTemporaryFolder();
+ // Run export.
+ if( ! RunExportSbs1() )
+ return AT_RETURN_CODE::MAKEFILE_ERROR;
+ // Create level 2 makefiles.
+ if ( ! CreateMakeFileSbs1Level2() )
+ return AT_RETURN_CODE::MAKEFILE_ERROR;
+ }
+ else if ( m_eBuildSystem == SBS_V2 )
+ {
+ // Create makefile only when using SBS v.2
+ if ( ! CreateMakeFile() )
+ return AT_RETURN_CODE::MAKEFILE_ERROR;
+ }
+ else
+ {
+ return AT_RETURN_CODE::UNKNOWN;
+ }
+ // Read makefile to get project attributes
+ if ( ! ReadMakeFile() )
+ return AT_RETURN_CODE::READ_MAKEFILE_ERROR;
+ // Filter unsupported
+ FilterModules();
+ // Check that we have some "valid" modules to hook
+ if ( m_vModules.size() == 0 &&( m_vUnsupportedModules.size() > 0 || m_vStaticLibraries.size() > 0 ) )
+ return AT_RETURN_CODE::NO_SUPPORTED_MODULES_ERROR;
+
+ // Clean temporary dirs of modules
+ if ( ! CleanTemporaryDirs() )
+ return AT_RETURN_CODE::CLEANING_TEMP_ERROR;
+ // Create temporary cpps for modulse
+ if (! CreateTemporaryCpps() )
+ return AT_RETURN_CODE::CREATING_TEMP_CPP_ERROR;
+ // Hook modules
+ if (! ModifyModules() )
+ return AT_RETURN_CODE::MODIFY_MODULES_ERROR;
+ return AT_RETURN_CODE::OK;
+}
+
+int CATProject::RunInstrumentConsole()
+{
+ LOG_FUNC_ENTRY("CATProject::RunInstrumentConsole");
+ if( ! MakeTempDirIfNotExist() )
+ return AT_RETURN_CODE::UNKNOWN;
+ // Store attributes
+ m_bUninstrumented = false;
+ if ( ! WriteAttributes() )
+ return AT_RETURN_CODE::WRITE_ATTRIBUTES_ERROR;
+ // Create makefile
+ if ( ! CreateMakeFile() )
+ return AT_RETURN_CODE::MAKEFILE_ERROR;
+ // Read makefile to get project attributes
+ if ( ! ReadMakeFile() )
+ return AT_RETURN_CODE::READ_MAKEFILE_ERROR;
+ // Filter unsupported
+ FilterModules();
+ // Check that we have some "valid" modules to hook
+ if ( m_vModules.size() == 0 &&( m_vUnsupportedModules.size() > 0 || m_vStaticLibraries.size() > 0 ) )
+ return AT_RETURN_CODE::NO_SUPPORTED_MODULES_ERROR;
+
+ // Clean temporary dirs of modules
+ if ( ! CleanTemporaryDirs() )
+ return AT_RETURN_CODE::CLEANING_TEMP_ERROR;
+ // Create temporary cpps for modulse
+ if (! CreateTemporaryCpps() )
+ return AT_RETURN_CODE::CREATING_TEMP_CPP_ERROR;
+ // Hook modules
+ if (! ModifyModules() )
+ return AT_RETURN_CODE::MODIFY_MODULES_ERROR;
+ // Run Reallyclean when using abld.
+ if ( m_eBuildSystem == SBS_V1 )
+ RunReallyCleanSbs1();
+ return AT_RETURN_CODE::OK;
+}
+
+int CATProject::RunUninstrument()
+{
+ LOG_FUNC_ENTRY("CATProject::RunUninstrument");
+ // Read attributes.
+ if ( ! ReadAttributes() )
+ return AT_RETURN_CODE::READ_ATTRIBUTES_ERROR;
+ // Init makefile member for this run mode.
+ if ( m_eBuildSystem == SBS_V1 )
+ InitSbs1MakeFileWithPathToTemp();
+ // Read makefile to get project attributes
+ if ( ! ReadMakeFile() )
+ return AT_RETURN_CODE::READ_MAKEFILE_ERROR;
+ // Filter unsupported
+ FilterModules();
+ // Check that we have some "valid" modules to hook
+ if ( m_vModules.size() == 0 &&( m_vUnsupportedModules.size() > 0 || m_vStaticLibraries.size() > 0 ) )
+ return AT_RETURN_CODE::NO_SUPPORTED_MODULES_ERROR;
+ // Create lst files
+ if (! CreateListings() )
+ return AT_RETURN_CODE::COMPILE_ERROR;
+ // Copy releasables of modules
+ if (! CopyReleasables() )
+ return AT_RETURN_CODE::RELEASABLES_ERROR;
+ // Restore "unhook" modules
+ if (! RestoreModules() )
+ return AT_RETURN_CODE::RESTORE_MODULES_ERROR;
+ // Return error code OK
+ return AT_RETURN_CODE::OK;
+}
+
+int CATProject::RunUninstrumentConsole()
+{
+ LOG_FUNC_ENTRY("CATProject::RunUninstrumentConsole");
+ int iErrorCode = AT_RETURN_CODE::OK;
+ // Read attributes
+ if ( ReadAttributes() )
+ {
+ // Init makefile member for this run mode.
+ if ( m_eBuildSystem == SBS_V1 )
+ InitSbs1MakeFileWithPathToTemp();
+ // Read makefile to get project attributes
+ if( ReadMakeFile() )
+ {
+ // Filter unsupported
+ FilterModules();
+ // Create lst files
+ CreateListings();
+ if (! CopyReleasables() )
+ iErrorCode = AT_RETURN_CODE::RELEASABLES_ERROR;
+ }
+ else
+ iErrorCode = AT_RETURN_CODE::READ_MAKEFILE_ERROR;
+ // Change state to uninstrumented and write status
+ m_bUninstrumented = true;
+ if ( ! WriteAttributes() )
+ iErrorCode = AT_RETURN_CODE::WRITE_ATTRIBUTES_ERROR;
+ }
+ else
+ {
+ iErrorCode = AT_RETURN_CODE::READ_ATTRIBUTES_ERROR;
+ }
+ return iErrorCode;
+}
+
+int CATProject::RunUninstrumentFailed()
+{
+ LOG_FUNC_ENTRY("CATProject::RunUninstrumentFailed");
+ // Read attributes.
+ if ( ! ReadAttributes() )
+ return AT_RETURN_CODE::READ_ATTRIBUTES_ERROR;
+ // Init makefile member for this run mode.
+ if ( m_eBuildSystem == SBS_V1 )
+ InitSbs1MakeFileWithPathToTemp();
+ // Read makefile to get project attributes
+ if( ReadMakeFile() )
+ {
+ // Filter modules
+ FilterModules();
+ // Restore modules to make sure no changes left
+ if( RestoreModules() )
+ {
+ // Delete temporary dirs of modules
+ if(! DeleteTemporaryDirs() )
+ {
+
+ }
+
+ }
+ else
+ {
+
+ }
+ }
+ else
+ {
+
+ }
+ // Projects
+ if ( ! DirDelete( AT_TEMP_DIR, true ) )
+ {
+
+ }
+ return AT_RETURN_CODE::OK;
+}
+
+// ----------------------------------------------------------------------------
+// Main Functions
+// ----------------------------------------------------------------------------
+void CATProject::DisplayCompileSummary()
+{
+ LOG_FUNC_ENTRY("CATProject::DisplayCompileSummary");
+ cout << AT_BUILD_SUMMARY_HEADER;
+ // Supported modules
+ for( size_t i = 0; i < m_vModules.size(); i++ )
+ {
+ // Successful
+ if ( m_vModules.at(i)->GetErrors().empty() )
+ {
+ // Create build complete file for Carbide xtension
+ m_vModules.at(i)->CreateBuildCompleteFile();
+ cout << AT_BUILD_SUMMARY_INSTRUMENTED_BUILD_COMPLETE
+ << GetPathOrFileName( true, m_vModules.at(i)->GetMmpFile() )
+ << endl
+ << AT_BUILD_SUMMARY_TARGET
+ << m_vModules.at(i)->GetBinaryName()
+ << endl;
+ // Datafiles
+ // Use module data file name if project's data file not defined.
+ if ( m_eLoggingMode == CATProject::FILE
+ && m_vModules.at(i)->GetTargetType().compare("exe") == 0 )
+ {
+ if ( m_sS60FileName.empty() )
+ cout << AT_BUILD_SUMMARY_DATA_FILE_NAME
+ << m_vModules.at(i)->GetS60FileName()
+ << endl;
+ else
+ cout << AT_BUILD_SUMMARY_DATA_FILE_NAME
+ << m_sS60FileName
+ << endl;
+ }
+ }
+ else
+ {
+ // Failed
+ cout << AT_BUILD_SUMMARY_FAILED
+ << GetPathOrFileName( true, m_vModules.at(i)->GetMmpFile() )
+ << endl
+ << AT_BUILD_SUMMARY_TARGET
+ << m_vModules.at(i)->GetBinaryName()
+ << endl;
+ // Print errors.
+ cout << AT_BUILD_SUMMARY_ERRORS
+ << m_vModules.at(i)->GetErrors()
+ << endl;
+ }
+ }
+
+ // Static libraries
+ for( size_t i = 0; i < m_vStaticLibraries.size(); i++ )
+ {
+ if ( m_vStaticLibraries.at(i)->GetErrors().empty() )
+ {
+ cout << AT_BUILD_SUMMARY_NORMAL_BUILD_COMPLETE
+ << GetPathOrFileName( true, m_vStaticLibraries.at(i)->GetMmpFile())
+ << endl
+ << AT_BUILD_SUMMARY_TARGET
+ << m_vStaticLibraries.at(i)->GetBinaryName()
+ << endl
+ << AT_BUILD_SUMMARY_STATIC_LIBRARY
+ << endl;
+
+ }
+ else
+ {
+ // Failed
+ cout << AT_BUILD_SUMMARY_FAILED
+ << GetPathOrFileName( true, m_vStaticLibraries.at(i)->GetMmpFile() )
+ << endl
+ << AT_BUILD_SUMMARY_TARGET
+ << m_vStaticLibraries.at(i)->GetBinaryName()
+ << endl;
+ // Print errors.
+ cout << AT_BUILD_SUMMARY_ERRORS
+ << m_vStaticLibraries.at(i)->GetErrors()
+ << endl;
+ }
+ }
+
+ // Unsupported modules
+ for( size_t i = 0; i < m_vUnsupportedModules.size(); i++ )
+ {
+ cout << AT_BUILD_SUMMARY_NORMAL_BUILD_COMPLETE
+ << GetPathOrFileName( true, m_vUnsupportedModules.at(i)->GetMmpFile() )
+ << endl
+ << AT_BUILD_SUMMARY_TARGET
+ << m_vUnsupportedModules.at(i)->GetBinaryName()
+ << endl;
+ cout << m_vUnsupportedModules.at(i)->GetCompileInfoText() << endl;
+ }
+}
+
+void CATProject::DisplayBuildSummary( void )
+{
+ LOG_FUNC_ENTRY("CATProject::DisplayBuildSummary");
+ cout << endl;
+ // Build information
+ cout << AT_BUILD_SUMMARY_BUILD_TYPE << GetBuildTypeString() << endl;
+ // Platform
+ cout << AT_BUILD_SUMMARY_BUILD_PLATFORM << m_sPlatform << endl;
+ // Possible variant
+ if ( ! m_sVariant.empty() )
+ cout << AT_BUILD_SUMMARY_BUILD_VARIANT << m_sVariant << endl;
+ // Logging mode
+ cout << AT_BUILD_SUMMARY_LOGGING_MODE;
+ if ( m_eLoggingMode == FILE )
+ cout << AT_BUILD_SUMMARY_FILE;
+ else if ( m_eLoggingMode == TRACE )
+ cout << AT_BUILD_SUMMARY_TRACE;
+ else if ( m_eLoggingMode == TRACE_FAST )
+ cout << AT_BUILD_SUMMARY_TRACE_FAST;
+ cout << endl;
+ // Call stack sizes
+ cout << AT_BUILD_SUMMARY_ALLOC_CALL_STACK_SIZE
+ << m_iAllocCallStackSize
+ << endl;
+ cout << AT_BUILD_SUMMARY_FREE_CALL_STACK_SIZE
+ << m_iFreeCallStackSize
+ << endl;
+
+ if(!_stricmp(m_sPlatform.c_str(), ("winscw")))
+ {
+ //print version info only when version is not up-to-date
+ cout << endl;
+ showDbgHelpVersionInfo( false );
+ }
+}
+
+bool CATProject::CreateMakeFile()
+{
+ switch ( m_eBuildSystem )
+ {
+ case SBS_V1:
+ if( ! CreateMakeFileSbs1() )
+ return false;
+ // Copy main make file.
+ if( ! CopyMakeFileSbs1ToTemporaryFolder() )
+ return false;
+ // Run export.
+ if( ! RunExportSbs1() )
+ return false;
+ // Create level 2 makefiles.
+ if( ! CreateMakeFileSbs1Level2() )
+ return false;
+ return true;
+ case SBS_V2:
+ return CreateMakeFileSbs2();
+ default:
+ return false;
+ }
+}
+
+bool CATProject::CreateMakeFileSbs1()
+{
+ LOG_FUNC_ENTRY("CATProject::CreateMakeFileSbs1");
+
+ // If variant defined check does it exist.
+ if( ! m_sVariant.empty() )
+ {
+ if ( ! CheckVariant( m_sEpocRoot, m_sVariant ) )
+ {
+ cout << INVALID_VARIANT_ERROR;
+ if ( IsDefaultVariant( m_sEpocRoot ) )
+ {
+ m_sVariant = "default";
+ cout << USING_DEFAULT_VARIANT_MESSAGE;
+ if ( ! WriteAttributes() )
+ return false;
+ }
+ else
+ {
+ cout << NO_DEFAULT_VARIANT_ERROR;
+ return false;
+ }
+ }
+ }
+
+ // Create level 1 make file.
+ string sCmd( "bldmake bldfiles " );
+ sCmd.append( m_sPlatform );
+ cout << AT_MSG_SYSTEM_CALL << sCmd << endl;
+ (void)system( sCmd.c_str() );
+ return InitSbs1MakeFileWithPath();
+}
+
+bool CATProject::CopyMakeFileSbs1ToTemporaryFolder()
+{
+ LOG_FUNC_ENTRY("CATProject::CopyMakeFileSbs1ToTemporaryFolder");
+ // Check that temporary dir exists if not create it.
+ if ( ! MakeTempDirIfNotExist() )
+ return false;
+ // Copy makefile to temporary directory
+ string sMakeFileInTemp( AT_TEMP_DIR );
+ sMakeFileInTemp.append( "\\" );
+ sMakeFileInTemp.append( AT_LEVEL_1_MAKEFILE_NAME );
+ if ( ! FileCopyToPath( m_sMakeFile, sMakeFileInTemp ) )
+ return false;
+ return true;
+
+}
+
+bool CATProject::RunReallyCleanSbs1()
+{
+ LOG_FUNC_ENTRY("CATProject::RunReallyCleanSbs1");
+ // Check that abld.bat has been made.
+ if ( ! FileExists( "abld.bat" ) )
+ return false;
+ // Run reallyclean.
+ string sCmd;
+ if ( m_bAbldTest )
+ sCmd = "abld test reallyclean ";
+ else
+ sCmd = "abld reallyclean ";
+ sCmd.append( m_sPlatform );
+ if ( ! m_sVariant.empty() )
+ {
+ sCmd.append( "." );
+ sCmd.append( m_sVariant );
+ }
+ sCmd.append( " " );
+ sCmd.append( GetBuildTypeString() );
+ if ( m_vTargetModules.size() > 1 )
+ {
+ RunAbldCommandToAllTargets( sCmd );
+ }
+ else
+ {
+ AddTargetModuleIfDefined( sCmd );
+ cout << AT_MSG_SYSTEM_CALL << sCmd << endl;
+ (void) system( sCmd.c_str() );
+ }
+ return true;
+}
+
+bool CATProject::RunReallyCleanSbs2()
+{
+ LOG_FUNC_ENTRY("CATProject::RunReallyCleanSbs2");
+ string sCmd("");
+ if ( m_sBuildCommand.empty() )
+ {
+ // If no build command defined (not found in project.cfg).
+ sCmd.append( RAPTOR_CMD_BASE );;
+ sCmd.append( m_sPlatform );
+ sCmd.append( "_" );
+ sCmd.append( GetBuildTypeString() );
+ if ( ! m_sVariant.empty() )
+ {
+ sCmd.append( "." );
+ sCmd.append( m_sVariant );
+ }
+ sCmd.append( RAPTOR_REALLYCLEAN_LOG );
+ AddTargetModuleIfDefined( sCmd );
+ sCmd.append( " REALLYCLEAN" );
+ }
+ else
+ {
+ // When build command set use it.
+ sCmd.append( m_sBuildCommand );
+ sCmd.append( RAPTOR_REALLYCLEAN_LOG );
+ sCmd.append( " REALLYCLEAN" );
+ }
+ cout << AT_MSG_SYSTEM_CALL << sCmd << endl;
+ int iRet = (int)system( sCmd.c_str() );
+ if ( iRet == 0 )
+ return true;
+ return false;
+}
+
+bool CATProject::RunExportSbs1()
+{
+ LOG_FUNC_ENTRY("CATProject::RunExportSbs1");
+ // Run export.
+ string sCmd;
+ if ( m_bAbldTest )
+ sCmd = "abld test export";
+ else
+ sCmd = "abld export";
+ cout << AT_MSG_SYSTEM_CALL << sCmd << endl;
+ (void) system( sCmd.c_str() );
+ return true;
+}
+
+bool CATProject::CreateMakeFileSbs1Level2()
+{
+ LOG_FUNC_ENTRY("CATProject::CreateMakeFileSbs1Level2");
+ // Create level 2 makefiles.
+
+ string sCmd;
+
+ if ( m_bAbldTest )
+ sCmd ="abld test makefile ";
+ else
+ sCmd ="abld makefile ";
+
+ sCmd.append( m_sPlatform );
+ if ( ! m_sVariant.empty() )
+ {
+ sCmd.append( "." );
+ sCmd.append( m_sVariant );
+ }
+
+ // Check if multiple targets defined and sbs 1.
+ if ( m_vTargetModules.size() > 1 )
+ {
+ RunAbldCommandToAllTargets( sCmd );
+ }
+ else
+ {
+ AddTargetModuleIfDefined( sCmd );
+ cout << AT_MSG_SYSTEM_CALL << sCmd << endl;
+ (void) system( sCmd.c_str() );
+ }
+ return true;
+}
+
+bool CATProject::CreateMakeFileSbs2()
+{
+ LOG_FUNC_ENTRY("CATProject::CreateMakeFileSbs2");
+ // Delete build directory if it exists before creating new makefiles.
+ if ( DirectoryExists( "atool_temp\\build" ) )
+ DirDelete( "atool_temp\\build", true );
+ // Create command to create makefiles.
+ string sCmd( m_sBuildCommand );
+ sCmd.append( " " );
+ sCmd.append( RAPTOR_MAKEFILE_SWITCH );
+ sCmd.append( " " );
+ sCmd.append( RAPTOR_NOBUILD_SWITCH );
+ cout << AT_MSG_SYSTEM_CALL << sCmd << endl;
+ int iRet = (int)system( sCmd.c_str() );
+ if ( iRet == 0 )
+ return true;
+ return false;
+}
+
+bool CATProject::ReadMakeFile()
+{
+ // Clean modules before reading.
+ CleanModuleVectors();
+ if ( m_eBuildSystem == SBS_V1 )
+ {
+ // Read level 1 makefile which contains module name and makefiles.
+ if( ! ReadMakeFileSbs1Level1() )
+ return false;
+ // Read level 2 makefiles.
+ vector<CATModule2*>::iterator it;
+ // If we are compiling or etc... we need to create temporary directories.
+ if ( m_eMode == COMPILE || m_eMode == INSTRUMENT || m_eMode == INSTRUMENT_CONSOLE )
+ {
+ // Read make makefiles from /epoc32/build... and create temporary directory.
+ bool bLevel2 = true;
+ for( it = m_vModules.begin(); it != m_vModules.end() ; it ++ )
+ {
+ if( ! (*it)->CreateTemporaryDirectory() )
+ return false;
+ if( ! (*it)->ReadMakeFile() )
+ {
+ bLevel2 = false;
+ break;
+ }
+ }
+ // If failed reading modules from level 2 makefiles.
+ if ( ! bLevel2 )
+ {
+ // Clean modules.
+ CleanModuleVectors();
+ // Try use default variant if it exists.
+ if ( CheckVariant( m_sEpocRoot, "default" ) )
+ {
+ m_sVariant = "default";
+ cout << USING_DEFAULT_VARIANT_MESSAGE;
+ if ( ! WriteAttributes() )
+ return false;
+ if ( ! InitSbs1MakeFileWithPath() )
+ return false;
+ if ( ! ReadMakeFileSbs1Level1() )
+ return false;
+ for( it = m_vModules.begin(); it != m_vModules.end() ; it ++ )
+ {
+ if( ! (*it)->CreateTemporaryDirectory() )
+ return false;
+ if( ! (*it)->ReadMakeFile() )
+ return false;
+ }
+
+ }
+ }
+ }
+ else
+ {
+ // Read make files from temporary directories.
+ for( it = m_vModules.begin(); it != m_vModules.end() ; it ++ )
+ {
+ if ( ! (*it)->ReadMakeFileFromTemp() )
+ return false;
+ }
+ }
+ return true;
+ }
+ else if ( m_eBuildSystem == SBS_V2 )
+ {
+ // Read make file.
+ if( ! ReadMakeFileSbs2() )
+ return false;
+ // Create module temporary directories if we are compiling or etc...
+ if ( m_eMode == COMPILE || m_eMode == INSTRUMENT || m_eMode == INSTRUMENT_CONSOLE )
+ {
+ for( vector<CATModule2*>::iterator it = m_vModules.begin(); it < m_vModules.end(); it++ )
+ (*it)->CreateTemporaryDirectory();
+ for( vector<CATModule2*>::iterator it = m_vStaticLibraries.begin(); it < m_vStaticLibraries.end(); it++ )
+ (*it)->CreateTemporaryDirectory();
+ }
+ }
+ return true;
+}
+
+bool CATProject::ReadMakeFileSbs1Level1()
+{
+ LOG_FUNC_ENTRY("CATProject::ReadMakeFileSbs1Level1");
+
+ bool bRet = false;
+
+ //Try to open makefile
+ ifstream in;
+ in.open( m_sMakeFile.c_str() );
+
+ //File open ok?
+ if( !in.good() )
+ {
+ printf( "Can not open file: %s\n", m_sMakeFile.c_str() );
+ in.close();
+ return bRet;
+ }
+
+ // Add also these so "compatible with sbs2".
+ // Releasables path (binaries).
+ string sReleasePath( m_sEpocRoot );
+ // add trailing '\' if root path is missing it
+ if ( sReleasePath.size() < 1 )
+ sReleasePath.append( "\\" );
+ else if ( sReleasePath.at( sReleasePath.length() -1 ) != '\\' )
+ sReleasePath.append( "\\" );
+ sReleasePath.append( "epoc32\\release" );
+ string sFullVariantPath( m_sPlatform );
+ sFullVariantPath.append( "\\" );
+ sFullVariantPath.append( GetBuildTypeString() );
+
+ char cTemp[MAX_LINE_LENGTH];
+ bool bContinueSearch = true;
+ bool bMmpInfoFound = false;
+ CATModule2* pModule = 0;
+ string sTempLineFromFile;
+ string sMmpFileSearchString;
+ if ( m_bAbldTest )
+ sMmpFileSearchString = MMPTESTFILE_SEARCH_STRING;
+ else
+ sMmpFileSearchString = MMPFILE_SEARCH_STRING;
+ do
+ {
+ // get line from file
+ in.getline( cTemp, MAX_LINE_LENGTH );
+ sTempLineFromFile.clear();
+ sTempLineFromFile.append( cTemp );
+
+ //Search makefile string
+ if( sTempLineFromFile.find( MAKEFILE_SEARCH_STRING ) != string::npos )
+ {
+ bMmpInfoFound = true;
+ if( sTempLineFromFile.find( sMmpFileSearchString ) != string::npos )
+ {
+ bRet = true;
+ //Parse mmp path + mmp filename
+ sTempLineFromFile.erase( 0, sTempLineFromFile.find_first_of("\"") );
+ sTempLineFromFile.erase( 0, 1 );
+
+ string sPath = sTempLineFromFile.substr(0, sTempLineFromFile.find_first_of("\"") );
+
+ sPath = ChangeSlashToBackSlash( sPath );
+ //Remove text "bld.inf"
+ sPath.erase( (sPath.find_last_of( "\\" ) + 1) , string::npos );
+
+ string sFileName = sTempLineFromFile.substr( (sTempLineFromFile.find( sMmpFileSearchString ) + sMmpFileSearchString.length() + 3), string::npos );
+ sFileName = ChangeSlashToBackSlash( sFileName );
+ sFileName = sFileName.substr( 0, sFileName.find_first_of("\"") );
+
+ // Append .mmp to filename if it does not exist
+ if ( sFileName.find(".mmp") == string::npos )
+ sFileName.append(".mmp");
+
+ //Insert drive letter
+ sPath.insert(0, string( m_cCurrentDir).substr(0,2) );
+
+ //Insert mmp file to the end
+ sPath.append( sFileName );
+
+ ChangeToLower( sPath );
+
+ // If target programs defined find from those or do not
+ // add module to vector.
+ bool bAddToVector = true;
+ if ( m_vTargetModules.size() > 0 )
+ {
+ bAddToVector = false;
+ vector<string>::iterator it;
+ for( it = m_vTargetModules.begin() ; it != m_vTargetModules.end() ; it++ )
+ {
+ string sFind( *it );
+ sFind.insert( 0, "\\" );
+ if ( sPath.find( sFind ) != string::npos )
+ {
+ bAddToVector = true;
+ break;
+ }
+ }
+ }
+
+ if ( bAddToVector )
+ {
+ pModule = new CATModule2();
+ pModule->SetMmpFile( sPath );
+ pModule->SetVariantType( GetBuildTypeString() );
+ pModule->SetVariantPlatform( m_sPlatform );
+ pModule->SetReleasePath( sReleasePath );
+ pModule->SetFullVariantPath( sFullVariantPath );
+ pModule->SetBuildSystem( SBS_V1 );
+ m_vModules.push_back( pModule );
+ }
+ }
+ }
+ else if( bMmpInfoFound )
+ //Do not continue search if mmp info lines are all handled
+ bContinueSearch = false;
+ if( !in.good() )
+ bContinueSearch = false;
+ }
+ while( bContinueSearch );
+
+ bContinueSearch = true;
+
+ //Search MAKEFILES for invidual modules
+ do
+ {
+ in.getline( cTemp, MAX_LINE_LENGTH );
+ sTempLineFromFile.clear();
+ sTempLineFromFile.append( cTemp );
+ // find the lines 'MAKEFILE[modulename]_FILES'
+ if( (sTempLineFromFile.find( "MAKEFILE" ) == 0) && (sTempLineFromFile.find( "_FILES" ) != string::npos) )
+ {
+ //Math the makefile line with one of our modules
+ for( size_t i = 0 ; i < m_vModules.size() ; i++ )
+ {
+ //Create name
+ string sMakeFile( "MAKEFILE" );
+ string sTempMmpFile( RemovePathAndExt( m_vModules.at(i)->GetMmpFile(), true ) );
+ ChangeToUpper( sTempMmpFile );
+ sMakeFile.append( sTempMmpFile );
+ sMakeFile.append( "_FILES" );
+ // matched
+ if( sTempLineFromFile.find( sMakeFile ) != string::npos )
+ {
+ //parse the makefile name from line
+ in.getline( cTemp, MAX_LINE_LENGTH );
+ sTempLineFromFile.clear();
+ sTempLineFromFile.append( cTemp );
+ //Remove character "\""
+ sTempLineFromFile.erase( 0, ( sTempLineFromFile.find_first_of("\"") + 1 ) );
+ // in winscw last part is '" \' and on armd '"' so remove all after last '"'
+ sTempLineFromFile.erase( sTempLineFromFile.find_last_of("\""), sTempLineFromFile.size() );
+ // Set correct makefile for module
+ m_vModules.at( i )->SetMakeFile( sTempLineFromFile );
+ // break
+ break;
+ } // If mathed to mmp
+ } // End of mmp file loop
+ } // found lines 'MAKEFILE[modulename]_FILES'
+ if( !in.good() )
+ bContinueSearch = false;
+ }
+ while( bContinueSearch );
+ in.close();
+ return bRet;
+}
+
+bool CATProject::ReadMakeFileSbs2( void )
+{
+ LOG_FUNC_ENTRY("CATProject::ReadMakeFileSbs2(void)");
+ // File is by default named make_build.default but when building specific layer
+ // make_build_LAYERNAME.default is produced by Raptor.
+ // So find makefile(s) and read them.
+ vector<string> vMakeFiles = DirList( "atool_temp\\build\\", false, true );
+ bool bRet = true;
+ for( vector<string>::iterator it = vMakeFiles.begin(); it != vMakeFiles.end() ; it++ )
+ {
+ // Recognize multiple makefiles.
+ if ( it->find("make_build_") != string::npos && it->find(".default") != string::npos )
+ {
+ if ( ! ReadMakeFileSbs2( *it ) )
+ bRet = false;
+ }
+ // Single makefile.
+ else if ( it->find( "make_build.default" ) != string::npos )
+ {
+ if ( ! ReadMakeFileSbs2( *it ) )
+ bRet = false;
+ }
+ }
+ // We got some modules?
+ if ( m_vModules.size() == 0 )
+ bRet = false;
+ return bRet;
+}
+
+bool CATProject::ReadMakeFileSbs2( string& sMakeFile )
+{
+ LOG_FUNC_ENTRY("CATProject::ReadMakeFileSbs2(string)");
+ try {
+ // Open file
+ ifstream in;
+ in.open( sMakeFile.c_str() , ios_base::in );
+ // Check that open ok
+ if ( ! in.good() )
+ {
+ cout << AT_MSG << "Error, opening file "
+ << RAPTOR_MAKEFILE << endl;
+ in.close();
+ return false;
+ }
+ // Source line from file
+ string sSourceLine;
+ // Module pointer
+ CATModule2* pModule = 0;
+ // Are we looking for module attributes
+ bool bFindAttributes = false;
+ // Until end of file
+ while( in.good() )
+ {
+ // Get new line from file
+ string sLine;
+ getline(in, sLine);
+ // New module
+ if ( sLine.find( RAPTOR_PROJECT_META ) == 0 )
+ {
+ // Remove project_meta from line
+ sLine.erase(0, strlen( RAPTOR_PROJECT_META ) );
+ LOG_STRING("Found module: " << sLine );
+ // Check is name empty
+ // This seems to happen when sbs2 "wraps" i.e. mifconv to a module type item
+ if ( sLine.empty() )
+ {
+ LOG_STRING("skipping empty module");
+ // Skip it
+ continue;
+ }
+ // If module add it to vector
+ if ( pModule )
+ {
+ // Add sources,
+ pModule->AddSources( sSourceLine );
+ // Build system.
+ pModule->SetBuildSystem( SBS_V1 );
+ // Push to vector.
+ m_vModules.push_back( pModule );
+ }
+ // New module
+ pModule = new CATModule2();
+ // Clear sourceline
+ sSourceLine.clear();
+ // Set modules mmp with path
+
+ if ( ! pModule->SetMmpFile( sLine ) )
+ {
+ // Fatal error setting mmp file
+ in.close();
+ return false;
+ }
+ // Find attributes on
+ bFindAttributes = true;
+ // Get new line from file
+ getline(in, sLine);
+ }
+ // If attribute finding on
+ if ( bFindAttributes )
+ {
+ // Pickup modules attributes
+ if ( sLine.find ( RAPTOR_SOURCE ) == 0 )
+ {
+ sLine.erase(0, strlen( RAPTOR_SOURCE ) );
+ sSourceLine = sLine;
+ }
+ else if ( sLine.find ( RAPTOR_TARGET ) == 0 )
+ {
+ sLine.erase(0, strlen( RAPTOR_TARGET ) );
+ pModule->SetTarget( sLine );
+ }
+ else if ( sLine.find ( RAPTOR_TARGETYPE ) == 0 )
+ {
+ sLine.erase(0, strlen( RAPTOR_TARGETYPE ));
+ pModule->SetTargetType( sLine );
+ }
+ else if ( sLine.find( RAPTOR_REQUESTEDTARGETEXT ) == 0 )
+ {
+ sLine.erase(0, strlen( RAPTOR_REQUESTEDTARGETEXT ) );
+ pModule->SetRequestedTargetExt( sLine );
+ }
+ else if ( sLine.find ( RAPTOR_VARIANTPLATFORM ) == 0 )
+ {
+ sLine.erase(0, strlen( RAPTOR_VARIANTPLATFORM ));
+ pModule->SetVariantPlatform( sLine );
+ }
+ else if ( sLine.find ( RAPTOR_VARIANTTYPE ) == 0 )
+ {
+ sLine.erase(0, strlen( RAPTOR_VARIANTTYPE ));
+ pModule->SetVariantType( sLine );
+ }
+ else if ( sLine.find ( RAPTOR_FEATUREVARIANT ) == 0 )
+ {
+ sLine.erase(0, strlen( RAPTOR_FEATUREVARIANT ));
+ pModule->SetFeatureVariant( sLine );
+ }
+ else if ( sLine.find ( RAPTOR_FEATUREVARIANTNAME ) == 0 )
+ {
+ sLine.erase(0, strlen( RAPTOR_FEATUREVARIANTNAME ));
+ pModule->SetFeatureVariantName( sLine );
+ }
+ else if ( sLine.find ( RAPTOR_RELEASEPATH ) == 0 )
+ {
+ sLine.erase(0, strlen( RAPTOR_RELEASEPATH ));
+ pModule->SetReleasePath( sLine );
+ }
+ else if ( sLine.find ( RAPTOR_FULLVARIANTPATH ) == 0 )
+ {
+ sLine.erase(0, strlen( RAPTOR_FULLVARIANTPATH ));
+ pModule->SetFullVariantPath( sLine );
+ }
+ else if ( sLine.find ( RAPTOR_COMPILE_DEFINITIONS ) == 0 )
+ {
+ sLine.erase(0, strlen( RAPTOR_COMPILE_DEFINITIONS ) );
+ pModule->SetCompileDefinitions( sLine );
+ }
+ }
+ } // while in.good()
+ // Add last module if n number of modules found
+ if ( pModule )
+ {
+ if ( ! pModule->GetTarget().empty() )
+ {
+ // Add sources
+ pModule->AddSources( sSourceLine );
+ // Build system.
+ pModule->SetBuildSystem( SBS_V1 );
+ // Push back to vector
+ m_vModules.push_back( pModule );
+ }
+ }
+ // Close file
+ in.close();
+ return true;
+ } // try.
+ catch(...)
+ {
+ LOG_STRING("Unexpected exception reading sbs 2 makefile");
+ return false;
+ }
+}
+bool CATProject::CreateTemporaryDirectories()
+{
+ LOG_FUNC_ENTRY("CATProject::CreateTemporaryDirectories");
+ bool bRet = true;
+ for( size_t i = 0 ; i < m_vModules.size(); i++)
+ {
+ if( ! m_vModules.at(i)->CreateTemporaryDirectory() )
+ bRet = false;
+ }
+ for( size_t i = 0 ; i < m_vStaticLibraries.size(); i++)
+ {
+ if( ! m_vStaticLibraries.at(i)->CreateTemporaryDirectory() )
+ bRet = false;
+ }
+ return bRet;
+
+}
+
+bool CATProject::CreateTemporaryCpps()
+{
+ LOG_FUNC_ENTRY("CATProject::CreateTemporaryCpps");
+ bool bRet = true;
+ for( size_t i = 0 ; i < m_vModules.size(); i++)
+ {
+ if( ! m_vModules.at(i)->CreateTempCpp(
+ m_sS60FileName, m_eLoggingMode, m_eBuildType, m_iAllocCallStackSize, m_iFreeCallStackSize ) )
+ bRet = false;
+ }
+ return bRet;
+}
+
+bool CATProject::FilterModules()
+{
+ LOG_FUNC_ENTRY("CATProject::FilterModules");
+ vector<CATModule2*>::iterator it;
+ // Loop thru modules.
+ it = m_vModules.begin();
+ while( it != m_vModules.end() )
+ {
+ // Get target type of module to separate string (will be modified).
+ string sTargetType = (*it)->GetTargetType();
+ // Modules compile definitions.
+ string sCompileDefinition = (*it)->GetCompileDefinitions();
+ // Check is it supported.
+ if ( !IsTargetTypeSupported( sTargetType) )
+ {
+ (*it)->SetCompileInfoText( AT_UNSUPPORTED_TARGET_TYPE );
+ // Not supported add to not supported vector.
+ m_vUnsupportedModules.push_back( *it );
+ // Erase cell.
+ it = m_vModules.erase( it );
+ }
+ // Check if its static library
+ else if ( _stricmp( sTargetType.c_str(), "lib" ) == 0 )
+ {
+ // Static librarie move to their vector.
+ m_vStaticLibraries.push_back( *it );
+ // Erase cell.
+ it = m_vModules.erase( it );
+
+ }
+ else if ( sCompileDefinition.find( KERNEL_MODE_COMPILE_DEFINITION ) != string::npos )
+ {
+ (*it)->SetCompileInfoText( AT_UNSUPPORTED_COMPILE_DEFINITION );
+ // Not supported add to not supported vector.
+ m_vUnsupportedModules.push_back( *it );
+ // Erase cell.
+ it = m_vModules.erase( it );
+ }
+ else
+ it++;
+ }
+ return true;
+}
+
+bool CATProject::ModifyModules()
+{
+ LOG_FUNC_ENTRY("CATProject::ModifyModules");
+ bool bRet = true;
+ for( size_t i = 0; i < m_vModules.size(); i++ )
+ {
+ if (! m_vModules.at(i)->ModifyMmp() )
+ bRet = false;
+ }
+ for( size_t i = 0; i < m_vStaticLibraries.size(); i++ )
+ {
+ if (! m_vStaticLibraries.at(i)->ModifyMmp() )
+ bRet = false;
+ }
+ return bRet;
+}
+
+bool CATProject::RestoreModules()
+{
+ LOG_FUNC_ENTRY("CATProject::RestoreModules");
+ bool bRet = true;
+ for( size_t i = 0; i < m_vModules.size(); i++ )
+ {
+ if (! m_vModules.at(i)->RestoreMmp() )
+ bRet = false;
+ }
+ for( size_t i = 0; i < m_vStaticLibraries.size(); i++ )
+ {
+ if (! m_vStaticLibraries.at(i)->RestoreMmp() )
+ bRet = false;
+ }
+ return bRet;
+}
+
+bool CATProject::VerifyAndRecoverModules()
+{
+ LOG_FUNC_ENTRY("CATProject::VerifyAndRecoverModules");
+ bool bRet = true;
+ for( size_t i = 0; i < m_vModules.size(); i++ )
+ {
+ if (! m_vModules.at(i)->VerifyAndRecoverMmp() )
+ bRet = false;
+ }
+ for( size_t i = 0; i < m_vStaticLibraries.size(); i++ )
+ {
+ if (! m_vStaticLibraries.at(i)->VerifyAndRecoverMmp() )
+ bRet = false;
+ }
+ return bRet;
+}
+bool CATProject::Compile()
+{
+ switch ( m_eBuildSystem )
+ {
+ case SBS_V1:
+ // Run Reallyclean.
+ if( ! RunReallyCleanSbs1() )
+ return false;
+ return CompileSbs1();
+ case SBS_V2:
+ return CompileSbs2();
+ default:
+ return false;
+ }
+}
+
+bool CATProject::CompileSbs1()
+{
+ LOG_FUNC_ENTRY("CATProject::CompileSbs1");
+ string sCommand("");
+ if ( m_sBuildCommand.empty() )
+ {
+ sCommand = "abld build";
+ // -debug if urel
+ if ( m_eBuildType == UREL )
+ sCommand.append( " -debug" );
+
+ // No variant
+ if ( m_sVariant.empty() )
+ {
+ sCommand.append( " " );
+ sCommand.append( m_sPlatform );
+ }
+ else
+ {
+ // Add variant
+ sCommand.append( " " );
+ sCommand.append( m_sPlatform );
+ sCommand.append( "." );
+ sCommand.append( m_sVariant );
+ }
+
+ // urel vs udeb
+ sCommand.append( " " );
+ sCommand.append( GetBuildTypeString() );
+
+ // Possible target module
+ AddTargetModuleIfDefined( sCommand );
+ }
+ // Check that build command contains -debug switch if sbs v.1 used
+ else if ( ! m_sBuildCommand.empty()
+ && m_eBuildType == UREL
+ && m_eBuildSystem == SBS_V1
+ && m_sBuildCommand.find( "-debug" ) == string::npos )
+ {
+ // Find correct index to insert -debug switch
+ size_t iPos = m_sBuildCommand.find( "build" );
+ if ( iPos != string::npos )
+ {
+ sCommand = m_sBuildCommand;
+ sCommand.insert( iPos+5, " -debug" );
+ }
+ else
+ {
+ LOG_STRING("Overwriting given build command to add -debug switch. Original command is: " << m_sBuildCommand );
+ if ( m_bAbldTest )
+ sCommand = "abld test build -debug ";
+ else
+ sCommand = "abld build -debug ";
+ // No variant
+ if ( m_sVariant.empty() )
+ {
+ sCommand.append( m_sPlatform );
+ }
+ else
+ {
+ // Add variant
+ sCommand.append( m_sPlatform );
+ sCommand.append( "." );
+ sCommand.append( m_sVariant );
+ }
+
+ // urel vs udeb
+ sCommand.append( " " );
+ sCommand.append( GetBuildTypeString() );
+ // Possible target module
+ AddTargetModuleIfDefined( sCommand );
+ }
+ }
+ else
+ sCommand = m_sBuildCommand;
+ // Run command
+ cout << AT_MSG_SYSTEM_CALL << sCommand << endl;
+ (void)system( sCommand.c_str() );
+ return true;
+}
+
+bool CATProject::CompileSbs2()
+{
+ LOG_FUNC_ENTRY("CATProject::CompileSbs2");
+ // Create command to compile with raptor
+ string sCmd( m_sBuildCommand );
+ sCmd.append( RAPTOR_BUILD_LOG );
+ cout << AT_MSG_SYSTEM_CALL << sCmd << endl;
+ int iRet = (int)system( sCmd.c_str() );
+ if ( iRet == 0 )
+ return true;
+ return false;
+}
+
+bool CATProject::CreateListings()
+{
+ // Create listings if no addr2line defined
+ #ifndef ADDR2LINE
+ if ( _stricmp( m_sPlatform.c_str(), "armv5" ) == 0 )
+ {
+ switch ( m_eBuildSystem )
+ {
+ case SBS_V1:
+ return CreateListingsSbs1();
+ case SBS_V2:
+ return CreateListingsSbs2();
+ default:
+ return false;
+ }
+ }
+ #endif
+ return true;
+}
+
+bool CATProject::CreateListingsSbs1()
+{
+ LOG_FUNC_ENTRY("CATProject::CreateListingsSbs1");
+ string sCommand;
+ if ( m_bAbldTest )
+ sCommand = "abld test listing ";
+ else
+ sCommand = "abld listing ";
+
+ // Listing
+ if ( m_sVariant.empty() )
+ {
+ // No variant
+ sCommand.append( m_sPlatform );
+ }
+ else
+ {
+ // Use specified variant
+ sCommand.append( m_sPlatform );
+ sCommand.append( "." );
+ sCommand.append( m_sVariant );
+ }
+ // udeb vs urel
+ sCommand.append( " " );
+ sCommand.append( GetBuildTypeString() );
+
+ if ( m_vTargetModules.size() > 1 )
+ {
+ RunAbldCommandToAllTargets( sCommand );
+ }
+ else
+ {
+ AddTargetModuleIfDefined( sCommand );
+ cout << AT_MSG_SYSTEM_CALL << sCommand << endl;
+ (void)system( sCommand.c_str() );
+ }
+ return true;
+}
+
+bool CATProject::CreateListingsSbs2()
+{
+ LOG_FUNC_ENTRY("CATProject::CreateListingsSbs2");
+ string sCmd( m_sBuildCommand );
+ sCmd.append( RAPTOR_LISTING_LOG );
+ sCmd.append( " LISTING");
+ cout << AT_MSG_SYSTEM_CALL << sCmd << endl;
+ int iRet = (int)system( sCmd.c_str() );
+ if ( iRet == 0 )
+ return true;
+ return false;
+}
+
+bool CATProject::CopyReleasables()
+{
+ bool bRet = true;
+ LOG_FUNC_ENTRY("CATProject::CopyReleasables");
+ // Only copy releasables on armv5 platform and no addr2line defined.
+ #ifndef ADDR2LINE
+ if ( _stricmp( m_sPlatform.c_str(), "armv5" ) == 0 )
+ {
+ for( size_t i = 0; i < m_vModules.size(); i++ )
+ {
+ if ( ! m_vModules.at(i)->CopyReleasables() )
+ bRet = false;
+ }
+ // Static libraries lst files.
+ // First create directory for them (delete old one if exists).
+ if ( ! DirectoryExists( AT_TEMP_LST_DIR ) )
+ {
+ DirCreate( AT_TEMP_LST_DIR, true );
+ }
+ else
+ {
+ DirDelete( AT_TEMP_LST_DIR, true );
+ DirCreate( AT_TEMP_LST_DIR, true );
+ }
+ for ( size_t i = 0 ; i < m_vStaticLibraries.size(); i ++ )
+ {
+ if( ! m_vStaticLibraries.at(i)->CopyLstFilesToDir( AT_TEMP_LST_DIR ) )
+ bRet = false;
+ }
+
+ // Delete lst files from all type of modules in project.
+ // Ignoring errors because different modules might use same source/lst files.
+ for( size_t i = 0; i < m_vModules.size(); i++ )
+ m_vModules.at(i)->DeleteLstFilesFromSrc();
+ for ( size_t i = 0 ; i < m_vUnsupportedModules.size(); i ++ )
+ m_vUnsupportedModules.at(i)->DeleteLstFilesFromSrc();
+ for ( size_t i = 0 ; i < m_vStaticLibraries.size(); i ++ )
+ m_vStaticLibraries.at(i)->DeleteLstFilesFromSrc();
+
+ return bRet;
+ }
+ #endif
+ // When addr2line defined and used we use symbol and map file(s).
+ #ifdef ADDR2LINE
+ if ( _stricmp( m_sPlatform.c_str(), "armv5" ) == 0 )
+ {
+ // Verify that module(s) symbol file(s) exist
+ for( size_t i = 0; i < m_vModules.size(); i++ )
+ {
+ // Check symbol file.
+ if ( ! m_vModules.at(i)->SymbolFileExist() )
+ bRet = false;
+ // Check map file.
+ if ( ! m_vModules.at(i)->MapFileExist() )
+ bRet = false;
+ }
+ }
+ #endif
+ // Platform winscw.
+ else if ( _stricmp( m_sPlatform.c_str(), "winscw" ) == 0 )
+ {
+ // Verify that module(s) binaries exist
+ for( size_t i = 0; i < m_vModules.size(); i++ )
+ {
+ if ( ! m_vModules.at(i)->BinaryFileExist() )
+ bRet = false;
+ }
+ // For static libraries binary/target is same as their library.
+ for ( size_t i = 0 ; i < m_vStaticLibraries.size(); i ++ )
+ if ( ! m_vStaticLibraries.at(i)->BinaryFileExist() )
+ bRet = false;
+ }
+ // Platform gcce.
+ else if ( _stricmp( m_sPlatform.c_str(), "gcce" ) == 0 )
+ {
+ // Verify that module(s) symbol file(s) exist
+ for( size_t i = 0; i < m_vModules.size(); i++ )
+ {
+ // Check symbol file.
+ if ( ! m_vModules.at(i)->SymbolFileExist() )
+ bRet = false;
+ }
+ }
+ return bRet;
+}
+
+// ----------------------------------------------------------------------------
+// Write project's (user) attributes to a file under temp folder
+// ----------------------------------------------------------------------------
+bool CATProject::WriteAttributes() const
+{
+ LOG_FUNC_ENTRY("CATProject::WriteAttributes");
+ // File to write to
+ string sOutFile( AT_TEMP_DIR );
+ sOutFile.append( "\\" );
+ sOutFile.append( AT_PROJECT_ATTRIBUTES_FILE_NAME );
+ // Open file truncate if exists
+ ofstream out( sOutFile.c_str(), ios_base::trunc );
+ // Check file opened successfully
+ if ( ! out.good() )
+ return false;
+ // Write attributes line by line
+ out << m_bUninstrumented << endl; // Is project instrumented
+ // Sbs version
+ if ( m_eBuildSystem == CATProject::SBS_V2 )
+ out << "SBS_2" << endl;
+ else
+ out << "SBS_1" << endl;
+ out << endl; // Reserved for possible binary data
+ out << m_sPlatform << endl;
+ out << m_sVariant << endl;
+ out << m_eLoggingMode << endl;
+ out << m_eBuildType << endl;
+ out << m_sS60FileName << endl;
+ out << m_iAllocCallStackSize << endl;
+ out << m_iFreeCallStackSize << endl;
+ for ( size_t i = 0 ; i < m_vTargetModules.size() ; i++ )
+ out << m_vTargetModules.at(i) << AT_PROJECT_ATTRIBUTES_SEPARATOR;
+ out << endl;
+ out << m_sBuildCommand << endl;
+ out.close();
+ return true;
+}
+// ----------------------------------------------------------------------------
+// Reads project's (user) attributes to a file under temp folder
+// ----------------------------------------------------------------------------
+bool CATProject::ReadAttributes()
+{
+ LOG_FUNC_ENTRY("CATProject::ReadAttributes");
+ // File to read on
+ string sInFile( AT_TEMP_DIR );
+ sInFile.append( "\\" );
+ sInFile.append( AT_PROJECT_ATTRIBUTES_FILE_NAME );
+ // Open file
+ ifstream in( sInFile.c_str() );
+ // Check file opened successfully
+ if ( ! in.good() )
+ return false;
+ // Read attributes
+ char cLine[ MAX_LINE_LENGTH ];
+ string sLine;
+ in.getline( cLine, MAX_LINE_LENGTH );
+ int iValue = atoi( cLine );
+ if ( iValue == 1 )
+ m_bUninstrumented = true;
+ else
+ m_bUninstrumented = false;
+ // Sbs version
+ in.getline( cLine, MAX_LINE_LENGTH ); string sBuildSystem = string( cLine );
+ if ( sBuildSystem.compare( "SBS_1" ) == 0 )
+ m_eBuildSystem = CATProject::SBS_V1;
+ else if ( sBuildSystem.compare( "SBS_2" ) == 0 )
+ m_eBuildSystem = CATProject::SBS_V2;
+ else {
+ LOG_STRING("Error invalid build system defined in project.cfg");
+ m_eBuildSystem = CATProject::SBS_V1;
+ }
+ in.getline( cLine, MAX_LINE_LENGTH ); // reserverd for possible binary timestamp or similar
+ in.getline( cLine, MAX_LINE_LENGTH ); m_sPlatform = string( cLine );
+ in.getline( cLine, MAX_LINE_LENGTH ); m_sVariant = string( cLine );
+ in.getline( cLine, MAX_LINE_LENGTH ); m_eLoggingMode = atoi( cLine );
+ in.getline( cLine, MAX_LINE_LENGTH ); m_eBuildType = atoi( cLine );
+ in.getline( cLine, MAX_LINE_LENGTH ); m_sS60FileName = string( cLine );
+ in.getline( cLine, MAX_LINE_LENGTH ); m_iAllocCallStackSize = atoi( cLine );
+ in.getline( cLine, MAX_LINE_LENGTH ); m_iFreeCallStackSize = atoi( cLine );
+ in.getline( cLine, MAX_LINE_LENGTH ); sLine = cLine;
+ size_t iSpot = sLine.find( AT_PROJECT_ATTRIBUTES_SEPARATOR );
+ while ( iSpot != string::npos )
+ {
+ string sTarget = sLine.substr(0, iSpot );
+ m_vTargetModules.push_back( sTarget );
+ sLine.erase(0, iSpot + AT_PROJECT_ATTRIBUTES_SEPARATOR.size() );
+ iSpot = sLine.find( AT_PROJECT_ATTRIBUTES_SEPARATOR );
+ }
+ in.getline( cLine, MAX_LINE_LENGTH ); m_sBuildCommand = cLine;
+ in.close();
+ return true;
+}
+
+// ----------------------------------------------------------------------------
+// Creates atool_temp directory to current folder if does not exist
+// ----------------------------------------------------------------------------
+bool CATProject::MakeTempDirIfNotExist()
+{
+ LOG_FUNC_ENTRY("CATProject::MakeTempDirIfNotExist");
+ if ( ! DirectoryExists( AT_TEMP_DIR ) )
+ {
+ if( !CreateDirectory( AT_TEMP_DIR , NULL ) )
+ {
+ return false;
+ }
+ }
+ return true;
+}
+// ----------------------------------------------------------------------------
+// Utilities
+// ----------------------------------------------------------------------------
+
+bool CATProject::RunAbldCommandToAllTargets( const string& sCommand )
+{
+ LOG_FUNC_ENTRY("CATProject::RunAbldCommandToAllTargets");
+
+ // Check for space at the commands end.
+ string sSystemCall( sCommand );
+ if ( *(sSystemCall.rbegin()) != ' ' )
+ sSystemCall.append( " " );
+
+ // Loop calls.
+ bool bRet = true;
+ for ( vector<string>::iterator it = m_vTargetModules.begin(); it < m_vTargetModules.end(); it++ )
+ {
+ string sCall( sSystemCall );
+ sCall.append( RemovePathAndExt( *it, true ) );
+ cout << AT_MSG_SYSTEM_CALL << sCall << endl;
+ if ( (int) system( sCall.c_str() ) != 0 )
+ bRet = false;
+ }
+ return bRet;
+}
+
+void CATProject::AddTargetModuleIfDefined( string& sCmd )
+{
+ LOG_FUNC_ENTRY("CATProject::AddTargetModuleIfDefined");
+ // Do we have target modules defined
+ if ( m_vTargetModules.size() > 0 )
+ {
+ switch( m_eBuildSystem )
+ {
+ case SBS_V1:
+ // Add first target modules name without extension to build cmd.
+ sCmd.append( " " );
+ sCmd.append( RemovePathAndExt( m_vTargetModules.at( 0 ), true ) );
+ break;
+ case SBS_V2:
+ // Add all target modules to build command using raptor switch '-p'.
+ for( size_t i = 0 ; i < m_vTargetModules.size() ; i++ )
+ {
+ LOG_STRING("Adding :" << m_vTargetModules.at( i ) );
+ sCmd.append( " -p " );
+ sCmd.append( m_vTargetModules.at( i ) );
+ }
+ break;
+ }
+ }
+}
+
+bool CATProject::IsTargetModuleInProject() const
+{
+ LOG_FUNC_ENTRY("CATProject::IsTargetModuleInProject");
+ vector<CATModule2*>::const_iterator modules;
+ vector<CATModule2*>::const_iterator staticModules;
+ vector<string>::const_iterator targets;
+ bool bRet = true;
+ // Do we have target modules defined
+ if ( m_vTargetModules.size() > 0 )
+ {
+ // Sbs version 1 support only single target module.
+ if ( m_eBuildSystem == SBS_V1 )
+ {
+ // Try to find module from project.
+ bRet = false;
+ string sTarget = m_vTargetModules.at(0);
+ for( modules = m_vModules.begin() ; modules != m_vModules.end() ; modules++ )
+ {
+ if( (*modules)->GetMmpFile().find( sTarget ) != string::npos )
+ {
+ // Found it return true.
+ bRet = true;
+ break;
+ }
+ }
+ for( staticModules = m_vStaticLibraries.begin(); staticModules != m_vStaticLibraries.end(); staticModules++ )
+ {
+ if( (*staticModules)->GetMmpFile().find( sTarget ) != string::npos )
+ {
+ bRet = true;
+ break;
+ }
+ }
+ if ( ! bRet )
+ {
+ // Not found display error message.
+ cout << AT_MSG << "Error, " << sTarget << " not defined in project." << endl;
+ }
+ }
+ // Sbs version 2 supports multiple target modules.
+ else if ( m_eBuildSystem == SBS_V2 )
+ {
+ // Check that all targets are defined in project.
+ for( targets = m_vTargetModules.begin(); targets != m_vTargetModules.end() ; targets++ )
+ {
+ // Found iterated target?
+ bool bFound = false;
+ for ( modules = m_vModules.begin() ; modules != m_vModules.end() ; modules++ )
+ {
+ if( (*modules)->GetMmpFile().find( *targets ) != string::npos )
+ {
+ // yes.
+ bFound = true;
+ break;
+ }
+ }
+ for( staticModules = m_vStaticLibraries.begin(); staticModules != m_vStaticLibraries.end(); staticModules++ )
+ {
+ if( (*staticModules)->GetMmpFile().find( *targets ) != string::npos )
+ {
+ bFound = true;
+ break;
+ }
+ }
+ if ( ! bFound )
+ {
+ // Display error when not found and set return value false.
+ bRet = false;
+ cout << AT_MSG << "Error, " << targets->c_str() << " not defined in project." << endl;
+ }
+ }
+ }
+ }
+ return bRet;
+}
+
+string CATProject::GetBuildTypeString()
+{
+ LOG_LOW_FUNC_ENTRY("CATProject::GetBuildTypeString");
+ // Return build type as lowercase string
+ switch( m_eBuildType )
+ {
+ case UDEB:
+ return string("udeb");
+ case UREL:
+ return string("urel");
+ default:
+ return "";
+ }
+}
+
+string CATProject::GetBuildTypeString( int eType )
+{
+ LOG_LOW_FUNC_ENTRY("CATProject::GetBuildTypeString( int eType )");
+ // Return build type as lowercase string
+ switch( eType )
+ {
+ case UDEB:
+ return string("udeb");
+ case UREL:
+ return string("urel");
+ default:
+ return string("unknown");
+ }
+}
+
+bool CATProject::CleanTemporaryDirs()
+{
+ LOG_FUNC_ENTRY("CATProject::CleanTemporaryDirs");
+ bool bRet = true;
+ // Modules
+ for( size_t i = 0; i < m_vModules.size(); i++ )
+ {
+ if ( ! m_vModules.at(i)->CleanTemporaryDir() )
+ bRet = false;
+ }
+ for( size_t i = 0; i < m_vStaticLibraries.size(); i++ )
+ {
+ if ( ! m_vStaticLibraries.at(i)->CleanTemporaryDir() )
+ bRet = false;
+ }
+ // Projects
+ vector<string> vFileList = DirList( AT_TEMP_DIR, false , true );
+ vector<string>::iterator it2 = vFileList.begin();
+ // Size of constant table
+ int iCount = sizeof( TEMP_EXTENSION_NO_DELETE ) / sizeof( string );
+ while ( it2 != vFileList.end() )
+ {
+ // Get extension and compare it to list
+ bool bDelete = true;
+ string sExtension = GetExtension( *it2 );
+ ChangeToLower( sExtension );
+ for ( int i = 0 ; i < iCount ; i++ )
+ {
+ if( sExtension.compare( TEMP_EXTENSION_NO_DELETE[i] ) == 0 )
+ {
+ bDelete = false;
+ break;
+ }
+ }
+ if ( bDelete )
+ {
+ // Delete file
+ if ( ! FileDelete( *it2, true ) )
+ bRet = false;
+ }
+ // Increment
+ it2++;
+ }
+ return bRet;
+}
+
+bool CATProject::DeleteTemporaryDirs()
+{
+ LOG_FUNC_ENTRY("CATProject::DeleteTemporaryDirs");
+ bool bRet = true;
+ // Modules
+ for( size_t i = 0; i < m_vModules.size(); i++ )
+ {
+ if (! m_vModules.at(i)->DeleteTemporaryDir() )
+ bRet = false;
+ }
+ for( size_t i = 0; i < m_vStaticLibraries.size(); i++ )
+ {
+ if (! m_vStaticLibraries.at(i)->DeleteTemporaryDir() )
+ bRet = false;
+ }
+ return bRet;
+}
+
+bool CATProject::InitSbs1MakeFileWithPathToTemp()
+{
+ LOG_FUNC_ENTRY("CATProject::InitSbs1MakeFileWithPathToTemp");
+ // Use temporary folder
+ m_sMakeFile.clear();
+ m_sMakeFile.append( AT_TEMP_DIR );
+ m_sMakeFile.append( "\\" );
+ m_sMakeFile.append( AT_LEVEL_1_MAKEFILE_NAME );
+ // At end check does it exist, return the result.
+ return FileExists( m_sMakeFile.c_str() );
+}
+
+bool CATProject::InitSbs1MakeFileWithPath()
+{
+ LOG_FUNC_ENTRY("CATProject::InitMakeFileWithPath");
+ if ( m_sEpocRoot.empty() )
+ {
+ LOG_STRING("Error, epocroot is not set.");
+ return false;
+ }
+ m_sMakeFile.clear();
+ m_sMakeFile.append( m_sEpocRoot );
+ if( *m_sMakeFile.rbegin() != '\\' )
+ m_sMakeFile.append( "\\" );
+ m_sMakeFile.append( "epoc32\\build\\" );
+ // Add current directory to path (first remove driveletter).
+ string sCurrentDir( m_cCurrentDir );
+ if ( sCurrentDir.length() < 3 )
+ {
+ LOG_STRING("Error, current dir invalid.");
+ return false;
+ }
+ sCurrentDir.erase(0,3);
+ m_sMakeFile.append( sCurrentDir );
+ m_sMakeFile.append( "\\" );
+ // Platform
+ string sPlatInUpper( m_sPlatform);
+ ChangeToUpper( sPlatInUpper );
+ m_sMakeFile.append( sPlatInUpper );
+ // Possible variant
+ if ( m_sVariant.empty() )
+ {
+ // Test modules only?
+ if ( m_bAbldTest )
+ m_sMakeFile.append( "TEST" );
+ m_sMakeFile.append( "." );
+ m_sMakeFile.append( "MAKE" );
+ }
+ else
+ {
+ m_sMakeFile.append( "." );
+ m_sMakeFile.append( m_sVariant );
+ // Test modules only?
+ if ( m_bAbldTest )
+ m_sMakeFile.append( "TEST" );
+ m_sMakeFile.append( ".MAKE" );
+ }
+ // At end check does it exist, return the result.
+ return FileExists( m_sMakeFile.c_str() );
+}
+
+// ----------------------------------------------------------------------------
+// Get & Sets
+// ----------------------------------------------------------------------------
+void CATProject::SetBuildSystem( BUILD_SYSTEM eSystem )
+{
+ LOG_FUNC_ENTRY("CATProject::SetBuildSystem");
+ m_eBuildSystem = eSystem;
+}
+void CATProject::SetMode( PROJECT_MODE eMode )
+{
+ LOG_FUNC_ENTRY("CATProject::SetMode");
+ m_eMode = eMode;
+}
+int CATProject::GetMode() const
+{
+ LOG_LOW_FUNC_ENTRY("CATProject::GetMode");
+ return m_eMode;
+}
+void CATProject::SetEpocRoot( const string& sEpocRoot )
+{
+ LOG_FUNC_ENTRY("CATProject::SetEpocRoot");
+ m_sEpocRoot = sEpocRoot;
+}
+void CATProject::SetPlatform( const string& sPlatform )
+{
+ LOG_FUNC_ENTRY("CATProject::SetPlatform");
+ m_sPlatform = sPlatform;
+}
+void CATProject::SetVariant( const string& sVariant )
+{
+ LOG_FUNC_ENTRY("CATProject::SetVariant");
+ m_sVariant = sVariant;
+}
+void CATProject::SetLoggingMode( LOGGING_MODE eLoggingMode)
+{
+ LOG_FUNC_ENTRY("CATProject::SetLoggingMode");
+ m_eLoggingMode = eLoggingMode;
+}
+void CATProject::SetAllocCallStackSize( int iAllocCallStackSize )
+{
+ m_iAllocCallStackSize = iAllocCallStackSize;
+}
+void CATProject::SetFreeCallStackSize( int iFreeCallStackSize )
+{
+ m_iFreeCallStackSize = iFreeCallStackSize;
+}
+void CATProject::SetBuildType( BUILD_TYPE eType )
+{
+ LOG_FUNC_ENTRY("CATProject::SetBuildType");
+ m_eBuildType = eType;
+}
+void CATProject::SetS60FileName( const string& sFileName)
+{
+ LOG_FUNC_ENTRY("CATProject::SetS60FileName");
+ m_sS60FileName = sFileName;
+}
+void CATProject::SetRomSymbolFiles(const vector<string>& vRomSymbolFiles)
+{
+ LOG_FUNC_ENTRY("CATProject::SetRomSymbolFiles");
+ m_vRomSymbolFiles = vRomSymbolFiles;
+}
+void CATProject::SetTargetModule(const string& sTargetModule)
+{
+ LOG_FUNC_ENTRY("CATProject::SetTargetModule");
+ m_sTargetModule = sTargetModule;
+ ChangeToLower( m_sTargetModule);
+}
+void CATProject::SetBinaryTarget(const string& sBinaryTarget)
+{
+ LOG_FUNC_ENTRY("CATProject::SetBinaryTarget");
+ m_sBinaryTarget = sBinaryTarget;
+ ChangeToLower( m_sBinaryTarget );
+}
+void CATProject::SetDataFile( const string& sDataFile )
+{
+ LOG_FUNC_ENTRY("CATProject::SetDataFile");
+ m_sDataFile = sDataFile;
+}
+void CATProject::SetLogLevel( int iLogLevel )
+{
+ LOG_FUNC_ENTRY("CATProject::SetLogLevel");
+ m_iLoggingLevel = iLogLevel;
+}
+void CATProject::SetDataFileOutput( const string& sDataFileOutput )
+{
+ LOG_FUNC_ENTRY("CATProject::SetDataFileOutput");
+ m_sDataFileOutput = sDataFileOutput;
+}
+void CATProject::SetTargetModules( const vector<string>& vTargetModules )
+{
+ LOG_FUNC_ENTRY("CATProject::SetTargetModules");
+ m_vTargetModules = vTargetModules;
+}
+void CATProject::SetBuildCommand( const string& sBuildCommand )
+{
+ LOG_FUNC_ENTRY("CATProject::SetBuildCommand");
+ m_sBuildCommand = sBuildCommand;
+}
+// End of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/arguments.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,798 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Argument parsing functions.
+*/
+#include "../inc/ATCommonDefines.h"
+#include "../inc/CATBase.h"
+
+//Forward declarations.
+bool parseBaseArguments( vector<string>& vArgs, ARGUMENTS& args );
+bool parseHookArguments( vector<string>& vArgs, ARGUMENTS& args );
+bool parseAnalyzeArguments( vector<string>& vArgs, ARGUMENTS& args );
+bool parseParseArguments( vector<string>& vArgs, ARGUMENTS& args );
+bool checkDataFileName( string& sFileName );
+bool parseSbsConfiguration( string& sConfiguration, ARGUMENTS& args );
+
+// Constants for old "hooking" parameter parsing.
+#define INVALID_PARAMETER "AnalyzeTool : Error, invalid parameter: "
+const char DATAFILENAME_INVALID_CHARS[] = " &^+-@$%*()|\\/[]{}<>?;:,\"'";
+
+/**
+* Check datafile name for invalid characters.
+* @return true if file name ok.
+*/
+bool checkDataFileName( string& sFileName )
+{
+ for ( size_t i = 0; i < sFileName.length(); i++ )
+ {
+ const char c = sFileName.at( i );
+ if( strchr( DATAFILENAME_INVALID_CHARS, c ) != 0 )
+ return false;
+ }
+ return true;
+}
+
+/**
+* Parse base arguments from given vector of strings.
+* Removes debug / help arguments from vector.
+*/
+bool parseBaseArguments( vector<string>& vArgs, ARGUMENTS& args )
+{
+ // Iterator used in this function.
+ vector<string>::iterator it;
+ // If no arguments set show help true.
+ if ( vArgs.size() == 0 )
+ {
+ args.eMainSwitch = SWITCH_UNKNOWN;
+ args.bHelp = true;
+ }
+ //Try find help and debug switches.
+ //Note: -help is main switch what shows syntax examples.
+ for(it = vArgs.begin(); it != vArgs.end(); it++ )
+ {
+ //Help switches.
+ if ( ! _stricmp( (*it).c_str(), "-?" ) )
+ {
+ args.bHelp = true;
+ it = vArgs.erase( it );
+ if ( it == vArgs.end() )
+ break;
+ }
+ else if ( ! _stricmp( (*it).c_str(), "--?" ) )
+ {
+ args.bHelp = true;
+ it = vArgs.erase( it );
+ if ( it == vArgs.end() )
+ break;
+ }
+ else if ( ! _stricmp( (*it).c_str(), "--help" ) )
+ {
+ args.bHelp = true;
+ it = vArgs.erase( it );
+ if ( it == vArgs.end() )
+ break;
+ }
+ else if ( ! _stricmp( (*it).c_str(), "/?" ) )
+ {
+ args.bHelp = true;
+ it = vArgs.erase( it );
+ if ( it == vArgs.end() )
+ break;
+ }
+ //Debug switches.
+ else if ( ! _stricmp( (*it).c_str(), "-show_debug" ) )
+ {
+ args.bDebugConsole = true;
+ it = vArgs.erase( it );
+ if ( it == vArgs.end() )
+ break;
+ }
+ else if ( ! _stricmp( (*it).c_str(), "--show_debug" ) )
+ {
+ args.bDebugConsole = true;
+ it = vArgs.erase( it );
+ if ( it == vArgs.end() )
+ break;
+ }
+ else if ( ! _stricmp( (*it).c_str(), "-show_debug_all" ) )
+ {
+ args.bDebugConsole = true;
+ args.bDebugLowLevel = true;
+ it = vArgs.erase( it );
+ if ( it == vArgs.end() )
+ break;
+ }
+ else if ( ! _stricmp( (*it).c_str(), "--show_debug_all" ) )
+ {
+ args.bDebugConsole = true;
+ args.bDebugLowLevel = true;
+ it = vArgs.erase( it );
+ if ( it == vArgs.end() )
+ break;
+ }
+ else if ( ! _stricmp( (*it).c_str(), "-show_dbgview" ) )
+ {
+ args.bDebugDbgView = true;
+ it = vArgs.erase( it );
+ if ( it == vArgs.end() )
+ break;
+ }
+ else if ( ! _stricmp( (*it).c_str(), "--show_dbgview" ) )
+ {
+ args.bDebugDbgView = true;
+ it = vArgs.erase( it );
+ if ( it == vArgs.end() )
+ break;
+ }
+ else if ( ! _stricmp( (*it).c_str(), "-show_dbgview_all" ) )
+ {
+ args.bDebugDbgView = true;
+ args.bDebugLowLevel = true;
+ it = vArgs.erase( it );
+ if ( it == vArgs.end() )
+ break;
+ }
+ else if ( ! _stricmp( (*it).c_str(), "--show_dbgview_all" ) )
+ {
+ args.bDebugDbgView = true;
+ args.bDebugLowLevel = true;
+ it = vArgs.erase( it );
+ if ( it == vArgs.end() )
+ break;
+ }
+ //Raptor switch.
+ else if ( ! _stricmp( (*it).c_str(), "-sbs2" ) )
+ {
+ args.bEnableSbs2 = true;
+ it = vArgs.erase( it );
+ if ( it == vArgs.end() )
+ break;
+ }
+ }
+ if ( vArgs.size() > 0 )
+ {
+ //Pick up main switch.
+ it = vArgs.begin();
+ if ( ! _stricmp( (*it).c_str(), "-a" ) )
+ args.eMainSwitch = SWITCH_ANALYZE;
+ else if ( ! _stricmp( (*it).c_str(), "-p" ) )
+ args.eMainSwitch = SWITCH_PARSE_TRACE;
+ else if ( ! _stricmp( (*it).c_str(), "-c" ) )
+ args.eMainSwitch = SWITCH_CLEAN;
+ else if ( ! _stricmp( (*it).c_str(), "-v" ) )
+ args.eMainSwitch = SWITCH_VERSION;
+ else if ( ! _stricmp( (*it).c_str(), "-vdbghelp" ) )
+ args.eMainSwitch = SWITCH_DBGHELP_VERSION;
+ else if ( ! _stricmp( (*it).c_str(), "-help" ) )
+ args.eMainSwitch = SWITCH_HELP;
+ else if ( ! _stricmp( (*it).c_str(), "-me" ) )
+ {
+ args.eMainSwitch = SWITCH_HOOK;
+ args.eHookSwitch = HOOK_EXTERNAL;
+ }
+ else if ( ! _stricmp( (*it).c_str(), "-e" ) )
+ {
+ args.eMainSwitch = SWITCH_HOOK;
+ args.eHookSwitch = HOOK_EXTERNAL_FAST;
+ }
+ else if ( ! _stricmp( (*it).c_str(), "-mi" ) )
+ {
+ args.eMainSwitch = SWITCH_HOOK;
+ args.eHookSwitch = HOOK_INTERNAL;
+ }
+ else if ( ! _stricmp( (*it).c_str(), "-instrument_i" ) )
+ {
+ args.eMainSwitch = SWITCH_HOOK;
+ args.eHookSwitch = HOOK_EXTENSION_INTERNAL;
+ }
+ else if ( ! _stricmp( (*it).c_str(), "-instrument_e" ) )
+ {
+ args.eMainSwitch = SWITCH_HOOK;
+ args.eHookSwitch = HOOK_EXTENSION_EXTERNAL;
+ }
+ else if ( ! _stricmp( (*it).c_str(), "-instrument_ef" ) )
+ {
+ args.eMainSwitch = SWITCH_HOOK;
+ args.eHookSwitch = HOOK_EXTENSION_EXTERNAL_FAST;
+ }
+ else if ( ! _stricmp( (*it).c_str(), "-uninstrument" ) )
+ {
+ args.eMainSwitch = SWITCH_UNHOOK;
+ args.eHookSwitch = HOOK_EXTENSION_UNINSTRUMENT;
+ }
+ else if ( ! _stricmp( (*it).c_str(), "-uninstrument_failed" ) )
+ {
+ args.eMainSwitch = SWITCH_UNHOOK;
+ args.eHookSwitch = HOOK_EXTENSION_FAILED;
+ }
+ }
+ return true;
+}
+
+/**
+* Parse analyze related arguments from given vector of strings.
+*/
+bool parseAnalyzeArguments( vector<string>& vArgs, ARGUMENTS& args )
+{
+ bool bRet = true;
+ if ( vArgs.size() < 2 )
+ {
+ cout << AT_MSG << "Error, missing datafile." << endl;
+ return false;
+ }
+ // Iterator used in this function.
+ vector<string>::const_iterator it;
+ for(it = vArgs.begin()+1; it != vArgs.end(); it++ )
+ {
+ if ( it->find("-l") != string::npos )
+ {
+ if ( it->length() == 3 )
+ {
+ // Create char array for atoi function
+ char level[2];
+ level[0] = it->at(2);
+ level[1] = 0; // null terminate
+ // check that its digit first
+ if ( isdigit(level[0]) )
+ {
+ // pass array to atoi
+ int iLoggingLevel = atoi( level );
+ if ( iLoggingLevel >= 0 && iLoggingLevel <= 3 )
+ {
+ // log level ok
+ args.ANALYZE.iLoggingLevel = iLoggingLevel;
+ continue;
+ }
+ }
+ bRet = false;
+ cout << AT_MSG << "Invalid logging level specified (0-3)." << endl;
+ args.ANALYZE.iLoggingLevel = -1;
+ }
+ }
+ // No else here because logging level check is done to all args in list.
+ // Rom symbol file
+ if( _stricmp( it->c_str(), "-s" ) == 0 )
+ {
+ it++;
+ if ( it == vArgs.end() )
+ {
+ bRet = false;
+ cout << AT_MSG << "Missing symbol file." << endl;
+ break; // Leave for loop.
+ }
+ else
+ {
+ args.ANALYZE.bSymbolFile = true;
+ args.ANALYZE.vSymbolFiles.push_back( *it );
+ continue;
+ }
+ }
+ else
+ {
+ // If we got datafile we must assume this is output
+ if( ! args.ANALYZE.sDataFile.empty() )
+ {
+ if ( args.ANALYZE.sOutputFile.empty() )
+ args.ANALYZE.sOutputFile = *it;
+ else
+ {
+ bRet = false;
+ cout << AT_MSG << "Invalid parameter: " << *it << endl;
+ }
+ }
+ // If this is file we assume datafile
+ else if( CATBase::FileExists( it->c_str() ) )
+ {
+ args.ANALYZE.sDataFile = *it;
+ }
+ else
+ {
+ bRet = false;
+ cout << AT_MSG << "Specified datafile does not exist." << endl;
+ }
+ }
+ }
+ if ( args.ANALYZE.sDataFile.empty() )
+ bRet = false;
+ return bRet;
+}
+
+
+/**
+* Parse hooking related arguments from given vector of strings.
+*/
+bool parseHookArguments( vector<string>& vArgs, ARGUMENTS& args )
+{
+ bool bRet = true;
+ try {
+ // Iterator used in this function.
+ vector<string>::const_iterator it;
+
+ // Check that we have some arguments except main switch.
+ if ( vArgs.size() < 2 )
+ {
+ if ( args.eHookSwitch == HOOK_EXTENSION_UNINSTRUMENT
+ || args.eHookSwitch == HOOK_EXTENSION_FAILED
+ )
+ return bRet;
+ cout << AT_MSG << "Error, Missing build command." << endl;
+ bRet = false;
+ }
+ bool bBuildFound = false;
+ for(it = vArgs.begin()+1; it != vArgs.end(); it++ )
+ {
+ // If's to pickup atool options
+ // no build switch
+ if ( _stricmp( it->c_str(), "-nobuild" ) == 0 )
+ {
+ args.HOOK.bNoBuild = true;
+ }
+ // call stack size(s)
+ else if ( _stricmp( it->c_str(), "-acs" ) == 0 || _stricmp( it->c_str(), "-fcs" ) == 0 )
+ {
+ // Free vs Alloc
+ bool bAlloc = true;
+ if ( _stricmp( it->c_str(), "-fcs" ) == 0 )
+ bAlloc = false;
+ // Value
+ it++;
+ if ( it== vArgs.end() )
+ {
+ bRet = false;
+ cout << AT_MSG << "Error, missing call stack size parameter." << endl;
+ break;
+ }
+ else if ( ! _stricmp( it->c_str(), "sbs" )
+ || ! _stricmp( it->c_str(), "abld" )
+ || ! _stricmp( it->c_str(), "-f" ) )
+ {
+ bRet = false;
+ cout << AT_MSG << "Error, missing call stack size parameter." << endl;
+ break;
+ }
+ else
+ {
+ int i;
+ // Try to parse integer value using stream.
+ istringstream ss( *it );
+ if ( ss>>i )
+ {
+ // Value parsed ok now check bounds.
+ if ( i < AT_CALL_STACK_SIZE_MIN )
+ {
+ bRet = false;
+ cout << AT_MSG << "Error, specified call stack size value too small." << endl;
+ break;
+ }
+ else if ( i > AT_CALL_STACK_SIZE_MAX )
+ {
+ bRet = false;
+ cout << AT_MSG << "Error, specified call stack size value too big." << endl;
+ break;
+ }
+ else
+ {
+ // Value valid.
+ if ( bAlloc )
+ args.HOOK.iAllocCallStackSize = i;
+ else
+ args.HOOK.iFreeCallStackSize = i;
+ }
+ }
+ else
+ {
+ // Error parsing value using stream.
+ bRet = false;
+ cout << AT_MSG << "Error, specified call stack size value invalid." << endl;
+ break;
+ }
+
+ }
+ }
+ // Data file name.
+ else if ( _stricmp( it->c_str(), "-f" ) == 0 )
+ {
+ it++;
+ if ( it == vArgs.end() )
+ {
+ bRet = false;
+ cout << AT_MSG << "Error, missing internal data gathering file name." << endl;
+ break;
+ }
+ else if ( ! _stricmp( it->c_str(), "sbs" ) || ! _stricmp( it->c_str(), "abld" ) )
+ {
+ bRet = false;
+ cout << AT_MSG << "Error, missing internal data gathering file name." << endl;
+ break;
+ }
+ else
+ {
+ if ( checkDataFileName( string( *it ) ) )
+ {
+ // Pickup filename.
+ args.HOOK.bDataFileName = true;
+ args.HOOK.sDataFileName = *it;
+ }
+ else
+ {
+ bRet = false;
+ cout << AT_MSG << "Error, specified internal data gathering file name contains invalid character(s)." << endl;
+ break;
+ }
+ }
+ }
+ // Build command parsing.
+ else if ( _stricmp( it->c_str(), "sbs" ) == 0 )
+ {
+ // By default sbs command is not valid.
+ bRet = false;
+ // By default build found
+ bBuildFound = true;
+ // Use raptor build system, pickup all rest arguments to sbs commmand.
+ bool bFoundConfig = false; // Is configuration defined.
+ args.HOOK.iBuildSystem = 2;
+ vector<string>::const_iterator itC = it;
+ args.HOOK.sBuildCmd.clear();
+ for ( ; itC != vArgs.end() ; itC++ )
+ {
+ args.HOOK.sBuildCmd.append( *itC );
+ args.HOOK.sBuildCmd.append( " " );
+ args.HOOK.vBuildCmd.push_back( *itC );
+ }
+ // Remove last space
+ if ( args.HOOK.vBuildCmd.size() > 1 )
+ args.HOOK.sBuildCmd.erase( args.HOOK.sBuildCmd.size()-1 );
+
+ // Parse needed variables from sbs command.
+ vector<string>::iterator itSbs;
+ for( itSbs = args.HOOK.vBuildCmd.begin(); itSbs != args.HOOK.vBuildCmd.end() ; itSbs++ )
+ {
+ // Program(s).
+ if ( _stricmp( itSbs->c_str(), "-p" ) == 0 )
+ {
+ // Next is program.
+ itSbs++;
+ args.HOOK.vTargetPrograms.push_back( *itSbs );
+ }
+ else if ( itSbs->find( "--project=" ) != string::npos )
+ {
+ itSbs->erase(0, 10 );
+ args.HOOK.vTargetPrograms.push_back( *itSbs );
+ }
+ // platform & build type ( configuration )
+ else if ( _stricmp( itSbs->c_str(), "-c" ) == 0 || itSbs->find( "--config=" ) != string::npos )
+ {
+ // Error message if config found more than once.
+ if ( bFoundConfig )
+ {
+ cout << AT_MSG << "Error, no support defining more than one configuration." << endl;
+ bRet = false;
+ continue;
+ }
+
+ if (_stricmp( itSbs->c_str(), "-c" ) == 0 )
+ {
+ // Next is the configuration
+ itSbs++;
+ // Check that iterator is valid.
+ if ( itSbs == args.HOOK.vBuildCmd.end() )
+ break;
+ }
+ else
+ {
+ // Remove the "--config=".
+ itSbs->erase( 0, 9 );
+ // Check its not empty.
+ if ( itSbs->size() == 0 )
+ break;
+ }
+
+ // Identify configuration, if successful set sbs command as valid.
+ if ( parseSbsConfiguration( *itSbs, args ) )
+ bRet = true;
+ // Set we encountered one configuration.
+ bFoundConfig = true;
+ }
+ }
+ // Error message if command is missing configuration.
+ if ( !bFoundConfig )
+ cout << AT_MSG << "Error, missing configuration definition from sbs cmd." << endl;
+ }
+ else if ( _stricmp( it->c_str(), "abld" ) == 0 )
+ {
+ bBuildFound = true;
+ // Use abld build system, pickup all rest argumenst as abld options.
+ args.HOOK.iBuildSystem = 1;
+
+ vector<string>::const_iterator itC = it;
+ args.HOOK.sBuildCmd.clear();
+ for ( ; itC != vArgs.end() ; itC++ )
+ {
+ args.HOOK.sBuildCmd.append( *itC );
+ args.HOOK.sBuildCmd.append( " " );
+ args.HOOK.vBuildCmd.push_back( *itC );
+ }
+
+ string sCmd( args.HOOK.sBuildCmd ); // build command to lower case here.
+ for( size_t i = 0 ; i < sCmd.size(); i++ )
+ sCmd.at(i) = tolower( sCmd.at(i) );
+
+ // Remove all until platform
+ if ( sCmd.find("build ") != string::npos )
+ {
+ // Check is test defined
+ if ( sCmd.substr(0, sCmd.find("build ")).find("test") != string::npos )
+ args.HOOK.bAbldTest = true;
+ sCmd.erase( 0, sCmd.find("build")+6 );
+ }
+ else
+ return false;
+
+ //Is -debug switch in command?
+ if( sCmd.find( "-debug " ) != string::npos )
+ {
+ sCmd.erase( sCmd.find( "-debug " ), 7 );
+ }
+
+ // Parse needed "variables" from command.
+ bool bOk = false;
+
+ // Find platform
+ if ( sCmd.find( "armv5" ) != string::npos )
+ {
+ bOk = true;
+ args.HOOK.sPlatform = "armv5";
+ sCmd.erase( sCmd.find( "armv5" ), 5 );
+ }
+ else if ( sCmd.find( "winscw" ) != string::npos )
+ {
+ bOk = true;
+ args.HOOK.sPlatform = "winscw";
+ sCmd.erase( sCmd.find( "winscw" ), 6 );
+ }
+ else if ( sCmd.find( "gcce" ) != string::npos )
+ {
+ bOk = true;
+ args.HOOK.sPlatform = "gcce";
+ sCmd.erase( sCmd.find( "gcce" ), 4 );
+ }
+ if ( bOk )
+ {
+ // Feature variant.
+ if ( sCmd.at(0 ) == '.' )
+ {
+ sCmd.erase(0,1);
+ args.HOOK.sFeatureVariant = sCmd.substr( 0, sCmd.find_first_of(' ') );
+ sCmd.erase(0, sCmd.find_first_of(' ')+1 );
+ }
+ }
+ else
+ {
+ // not platform specified.
+ cout << AT_MSG << "Error, no supported platform found in abld parameters (armv5/winscw/gcce)." << endl;
+ bRet = false;
+ }
+
+ // find build type
+ bOk = false;
+ if ( sCmd.find( "urel" ) != string::npos )
+ {
+ bOk = true;
+ args.HOOK.sBuildType = "urel";
+ sCmd.erase( sCmd.find( "urel" ), 4 );
+ }
+
+ else if ( sCmd.find( "udeb" ) != string::npos )
+ {
+ bOk = true;
+ args.HOOK.sBuildType = "udeb";
+ sCmd.erase( sCmd.find( "udeb" ), 4 );
+ }
+ if( !bOk )
+ {
+ // no build type specified.
+ cout << AT_MSG << "Error, no build type specified in abld parameters (udeb/urel)." << endl;
+ bRet = false;
+ }
+
+ // Is there multiple programs (only should be used from extension).
+ if ( sCmd.find(" -p") != string::npos )
+ {
+ sCmd.erase( sCmd.find(" -p" ), sCmd.size() - sCmd.find(" -p" ) );
+ // Loop thru all parameters and pick up programs.
+ vector<string>::iterator it;
+ for( it = args.HOOK.vBuildCmd.begin(); it != args.HOOK.vBuildCmd.end(); it++ )
+ {
+ if ( _stricmp( it->c_str(), "-p" ) == 0 )
+ {
+ // Next is program.
+ it++;
+ string sProgram = *it;
+ // Make sure program name ends with ".mmp".
+ CATBase::ChangeToLower( sProgram );
+ if ( sProgram.length() >= 4 )
+ {
+ string sEnd = sProgram.substr( sProgram.length()-4, 4 );
+ if ( sEnd.compare( ".mmp" ) != 0 )
+ sProgram.append( ".mmp" );
+ }
+ else
+ sProgram.append( ".mmp" );
+ args.HOOK.vTargetPrograms.push_back( sProgram );
+ }
+ }
+ }
+ else {
+ // find single defined program.
+ if ( sCmd.find_first_not_of(' ') != string::npos )
+ {
+ size_t iS = sCmd.find_first_not_of(' ');
+ size_t iE = sCmd.find_first_of(' ', iS );
+ string sProgram;
+ if ( iE == string::npos )
+ sProgram = sCmd.substr( iS, sCmd.size()-iS );
+ else
+ sProgram = sCmd.substr( iS, iE-iS);
+ // Make sure program name ends with ".mmp".
+ CATBase::ChangeToLower( sProgram );
+ if ( sProgram.length() >= 4 )
+ {
+ string sEnd = sProgram.substr( sProgram.length()-4, 4 );
+ if ( sEnd.compare( ".mmp" ) != 0 )
+ sProgram.append( ".mmp" );
+ }
+ else
+ sProgram.append( ".mmp" );
+ args.HOOK.vTargetPrograms.push_back( sProgram );
+ }
+ }
+ }
+ else
+ {
+ if ( ! bBuildFound )
+ {
+ bRet = false;
+ cout << AT_MSG << "Error, invalid parameter :" << *it << endl;
+ break;
+ }
+ }
+ }
+ }
+ catch(...)
+ {
+ bRet = false;
+ cout << AT_MSG << "Error parsing arguments." << endl;
+ }
+ return bRet;
+}
+
+
+/**
+* Parse trace parsing related arguments from given vector of strings.
+*/
+bool parseParseArguments( vector<string>& vArgs, ARGUMENTS& args )
+{
+ // Iterator used in this function.
+ vector<string>::const_iterator it = vArgs.begin();
+
+ if ( it == vArgs.end() )
+ return false;
+
+ it++;
+
+ if ( it == vArgs.end() )
+ {
+ cout << AT_MSG << "Error, input file not defined (raw data file)." << endl;
+ return false;
+ }
+
+ //Input.
+ args.PARSE.bDataFile = true;
+ args.PARSE.sDataFile = *it;
+
+ it++;
+ if ( it == vArgs.end() )
+ {
+
+ cout << AT_MSG << "Error, output file not defined (device data file)." << endl;
+ return false;
+ }
+
+ //Output.
+ args.PARSE.bOutputFile = true;
+ args.PARSE.sOutputFile = *it;
+ return true;
+}
+
+/**
+* Identifies/parses the configuration string when raptor used (-c / --config= ).
+*/
+bool parseSbsConfiguration( string& sConfiguration, ARGUMENTS& args )
+{
+ CATBase::ChangeToLower( sConfiguration );
+ vector<string> tokens = CATBase::ParseStringToVector( sConfiguration, '.' );
+
+ //we check if winscw/armv5 and udeb/urel is used
+ //rest of the "." are variants which we all support by default.
+
+ //first we check if some of aliases is used
+ if ( tokens.at(0).compare("armv5_urel") == 0 )
+ {
+ args.HOOK.sPlatform = "armv5";
+ args.HOOK.sBuildType = "urel";
+ return true;
+ }
+ else if ( tokens.at(0).compare("armv5_udeb") == 0 )
+ {
+ args.HOOK.sPlatform = "armv5";
+ args.HOOK.sBuildType = "udeb";
+ return true;
+ }
+ else if ( tokens.at(0).compare("winscw_udeb") == 0)
+ {
+ args.HOOK.sPlatform = "winscw";
+ args.HOOK.sBuildType = "udeb";
+ return true;
+ }
+ else if ( tokens.at(0).compare("winscw_urel") == 0 )
+ {
+ args.HOOK.sPlatform = "winscw";
+ args.HOOK.sBuildType = "urel";
+ return true;
+ }
+ //if 1st token is not an alias, lets try dot configurations
+ else if ( tokens.at(0).compare("arm") == 0 )
+ {
+ // check we have atleast 3 tokens. i.e arm v5 debug x ...
+ if ( tokens.size() >= 3 )
+ {
+ // Next configuration is arm version, we only support v5.
+ if ( tokens.at(1).compare( "v5" ) == 0)
+ {
+ args.HOOK.sPlatform = "armv5";
+
+ // Check next configuration part is debug or release
+ if ( tokens.at(2).compare( "udeb" ) == 0)
+ {
+ args.HOOK.sBuildType = "udeb";
+ return true;
+ }
+ else if ( tokens.at(2).compare( "urel" ) == 0 )
+ {
+ args.HOOK.sBuildType = "urel";
+ return true;
+ }
+ else
+ {
+ cout << AT_MSG << "Error in sbs configuration part: " << tokens.at(2) << endl;
+ cout << AT_MSG << "Supported are: udeb,urel." << endl;
+ return false;
+ }
+ }
+ else
+ {
+ cout << AT_MSG << "Error in sbs configuration part: " << tokens.at(1) << endl;
+ cout << AT_MSG << "Supported are: v5." << endl;
+ return false;
+ }
+ }
+ }
+
+ cout << AT_MSG << "Error in sbs configuration part: " << tokens.at(0) << endl;
+ cout << AT_MSG << "Supported are: arm, armv5_urel, armv5_udeb, winscw_udeb, winscw_urel." << endl;
+ return false;
+
+}
+
+//EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/atool.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,236 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Defines the entry point for the console application.
+*
+*/
+
+// Includes.
+#include "../inc/ATCommonDefines.h"
+#include "../inc/CATDatParser.h"
+#include "../inc/CATParseTraceFile.h"
+#include "../inc/CATProject.h"
+
+//Debug logging parameters
+//To enable debugging as argument to atool.exe use:
+//--show_debug / -show_debug : Normal logging in console.
+//--show_debug_all / -show_debug_all : Log all (low level functions also) to console.
+//--show_dbgview / -show_dbgview : Normal logging to windows debug messages.
+//--show_dbgview_all / -show_dbgview_all : Log all (low level functions also) to windows debug messages.
+
+//Return codes (errorlevel) defined in AT_RETURN_CODE structure see ATCommonDefines.h.
+
+extern bool g_bDebugConsole = false;
+extern bool g_bDebugDbgView = false;
+extern bool g_bDebugLowLevel = false;
+
+//Argument parsing.
+extern bool parseBaseArguments( vector<string>& vArgs, ARGUMENTS& args );
+extern bool parseHookArguments( vector<string>& vArgs, ARGUMENTS& args );
+extern bool parseAnalyzeArguments( vector<string>& vArgs, ARGUMENTS& args );
+extern bool parseParseArguments( vector<string>& vArgs, ARGUMENTS& args );
+
+//Helps.
+extern void print_help( void );
+extern void print_syntax_examples( void );
+
+//AT Library check functions
+extern bool CheckATLibrariesArmv5( string sEpocRoot );
+extern bool CheckATLibrariesArmv5Abiv2( string sEpocRoot );
+extern bool CheckATLibrariesWinscw( string sEpocRoot );
+
+//CLE version functions.
+extern int showVersionInfo( void );
+
+//dbghelp.dll version function.
+extern int showDbgHelpVersionInfo( bool showVersion );
+
+//Miscelllanaeous functions.
+extern bool CheckSBS2Folder( void );
+
+const char DEBUG_PARAMETER_CONSOLE[] = "-debug";
+const char DEBUG_PARAMETER_DBGVIEW[] = "-dbgview";
+const char SBS2_PARAMETER[] = "-sbs2";
+char g_cCurrentDir[MAX_LINE_LENGTH];
+
+//Global compile class objects are neededif ctrl+c is pressed mmp file must be restored.
+CATProject project_module;
+
+//Parse object.
+CATParseTraceFile Parser;
+
+/**
+* Handle process control signals.
+*/
+BOOL WINAPI HandlerRoutine( DWORD dwCtrlType )
+{
+ //Run recovery and exit for project if user presses ctrl+c
+ //or close signal is received.
+ if( dwCtrlType == CTRL_C_EVENT || dwCtrlType == CTRL_CLOSE_EVENT )
+ {
+ int iMode = project_module.GetMode();
+ if ( iMode == CATProject::COMPILE
+ || iMode == CATProject::INSTRUMENT
+ || iMode == CATProject::INSTRUMENT_CONSOLE )
+ project_module.RunRecoveryAndExit();
+ }
+ //Return false so program execution is stopped.
+ return false;
+}
+// TESTING
+int _tmain( int argc, _TCHAR* argv[] )
+{
+ #ifdef MEM_LEAK_CHECK
+ _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
+ #endif
+ try {
+ //Set function to handle process control signals.
+ SetConsoleCtrlHandler( HandlerRoutine, true );
+ vector<string> vArguments;
+ for( int i = 1 ; i < argc ; i++ )
+ {
+ vArguments.push_back( argv[i] );
+ }
+ //Help variables.
+ string sEpocRoot("");
+ //Parse base arguments.
+ ARGUMENTS args;
+ parseBaseArguments( vArguments, args );
+
+ // Debugging messages.
+ if ( args.bDebugConsole == true )
+ g_bDebugConsole = true;
+ if ( args.bDebugDbgView == true )
+ g_bDebugDbgView = true;
+ if ( args.bDebugLowLevel == true )
+ g_bDebugLowLevel = true;
+
+ //According to main switch parse rest arguments.
+ switch( args.eMainSwitch )
+ {
+ case SWITCH_UNKNOWN:
+ print_help();
+ return AT_RETURN_CODE::INVALID_ARGUMENT_ERROR;
+ case SWITCH_ANALYZE:
+ if ( ! parseAnalyzeArguments( vArguments, args ) )
+ return AT_RETURN_CODE::INVALID_ARGUMENT_ERROR;
+ // Get epocroot
+ if( ! CATBase::GetEpocRoot( sEpocRoot ) )
+ return AT_RETURN_CODE::CANNOT_FIND_EPOCROOT;
+ project_module.SetEpocRoot( sEpocRoot );
+ // project not uninstrumented run it first.
+ if ( ! project_module.IsUninstrumented() )
+ {
+ project_module.SetMode( CATProject::UNINSTRUMENT_CONSOLE );
+ project_module.Run();
+ }
+ // Set mode.
+ project_module.SetMode( CATProject::ANALYZE );
+ project_module.SetLogLevel( args.ANALYZE.iLoggingLevel );
+ project_module.SetDataFile( args.ANALYZE.sDataFile );
+ if ( args.ANALYZE.bSymbolFile )
+ project_module.SetRomSymbolFiles( args.ANALYZE.vSymbolFiles );
+ project_module.SetDataFileOutput( args.ANALYZE.sOutputFile);
+ return project_module.Run();
+ case SWITCH_HOOK:
+ // Parse arguments related to hooking.
+ if ( ! parseHookArguments( vArguments, args ) )
+ return AT_RETURN_CODE::INVALID_ARGUMENT_ERROR;
+ // Set variables for project.
+ if ( ! project_module.SetArguments( args ) )
+ return AT_RETURN_CODE::INVALID_ARGUMENT_ERROR;
+ // Get epocroot
+ if( ! CATBase::GetEpocRoot( sEpocRoot ) )
+ return AT_RETURN_CODE::CANNOT_FIND_EPOCROOT;
+ project_module.SetEpocRoot( sEpocRoot );
+ // Check AnalyzeTool libraries
+ if ( _stricmp( args.HOOK.sPlatform.c_str(), "winscw") == 0 )
+ {
+ // Emulator winscw platform
+ if ( ! CheckATLibrariesWinscw(sEpocRoot) )
+ return AT_RETURN_CODE::AT_LIBS_MISSING;
+ }
+ else
+ {
+ // Armv5
+ if ( args.HOOK.iBuildSystem == 2 )
+ {
+ // Abiv2
+ if ( ! CheckATLibrariesArmv5Abiv2(sEpocRoot) )
+ return AT_RETURN_CODE::AT_LIBS_MISSING;
+ }
+ else
+ {
+ // Abiv1
+ if( ! CheckATLibrariesArmv5(sEpocRoot) )
+ return AT_RETURN_CODE::AT_LIBS_MISSING;
+ }
+ }
+ // Run hooking.
+ return project_module.Run();
+ //Uninstrument
+ case SWITCH_UNHOOK:
+ // Set variables for project.
+ if ( ! project_module.SetArguments( args ) )
+ return AT_RETURN_CODE::INVALID_ARGUMENT_ERROR;
+ // Get epocroot
+ if( ! CATBase::GetEpocRoot( sEpocRoot ) )
+ return AT_RETURN_CODE::CANNOT_FIND_EPOCROOT;
+ project_module.SetEpocRoot( sEpocRoot );
+ return project_module.Run();
+ case SWITCH_VERSION:
+ return showVersionInfo();
+ case SWITCH_DBGHELP_VERSION:
+ return showDbgHelpVersionInfo( true );
+ case SWITCH_CLEAN:
+ project_module.SetMode( CATProject::CLEAN );
+ if ( CheckSBS2Folder() )
+ project_module.SetBuildSystem( CATProject::SBS_V2 );
+ else
+ project_module.SetBuildSystem( CATProject::SBS_V1 );
+ return project_module.Run();
+ case SWITCH_PARSE_TRACE:
+ if ( ! parseParseArguments( vArguments, args ) )
+ return AT_RETURN_CODE::INVALID_ARGUMENT_ERROR;
+ if ( CATBase::IsDataFile( args.PARSE.sDataFile ) )
+ {
+ cout << AT_MSG << "Error, " << args.PARSE.sDataFile << " is already parsed." << endl;
+ return AT_RETURN_CODE::INVALID_ARGUMENT_ERROR;
+ }
+ if ( args.PARSE.bOutputFile )
+ {
+ //Save data with name in arguments[3]
+ Parser.StartParse( args.PARSE.sDataFile.c_str(), args.PARSE.sOutputFile.c_str() );
+ }
+ else
+ {
+ Parser.StartParse( args.PARSE.sDataFile.c_str(), NULL );
+ }
+ return AT_RETURN_CODE::OK;
+ case SWITCH_HELP:
+ print_help();
+ print_syntax_examples();
+ return AT_RETURN_CODE::OK;
+ default:
+ cout << AT_MSG << "Invalid parameters." << endl;
+ return AT_RETURN_CODE::INVALID_ARGUMENT_ERROR;
+ }
+
+ } catch(...)
+ {
+ cout << AT_MSG << "Error, unhandled exception." << endl;
+ return AT_RETURN_CODE::UNHANDLED_EXCEPTION;
+ }
+}
+
+//EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/cataddr2line.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,388 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Main module for addr2line pinpointing.
+*
+*/
+
+#include "../inc/cataddr2line.h"
+#include "../inc/CATMemoryAddress.h"
+#include "../inc/CATBase.h"
+#include "../inc/CATDatParser.h"
+
+#define ASCII_CHAR_CARRIAGE_RETURN 0x0D
+
+CATAddr2line::CATAddr2line()
+{
+ LOG_FUNC_ENTRY("CATAddr2line::CATAddr2line");
+}
+
+bool CATAddr2line::Open( const string& sParameter, const unsigned long /* iLong */ )
+{
+ LOG_FUNC_ENTRY("CATAddr2line::Open");
+ //Debugging for addr2line task.
+ //debug.open( "addr2line-lines.txt", ios_base::trunc );
+
+ m_sMapFileName.clear();
+ // Add .map extendsion
+ m_sMapFileName.append( sParameter );
+ m_sMapFileName.append( ".map" );
+
+ ReadMapFileArmv5();
+
+ //Make symfile path+name
+ string sFullPathToSymFile(sParameter);
+ sFullPathToSymFile.erase( sFullPathToSymFile.find_last_of( "." ), string::npos );
+ sFullPathToSymFile.append( ".sym" );
+
+ // Check with extension + .sym also.
+ if ( ! CATBase::FileExists( sFullPathToSymFile.c_str() ) )
+ {
+ sFullPathToSymFile.clear();
+ sFullPathToSymFile.append( sParameter );
+ sFullPathToSymFile.append( ".sym" );
+ }
+
+ return server.Initialize( sFullPathToSymFile );
+}
+
+string CATAddr2line::GetError( void )
+{
+ LOG_FUNC_ENTRY("CATAddr2line::GetError");
+ string s;
+ return s;
+}
+
+bool CATAddr2line::Close( void )
+{
+ LOG_FUNC_ENTRY("CATAddr2line::Close");
+ //Debugging for addr2line task.
+ //debug.close();
+ return true;
+}
+
+bool CATAddr2line::AddressToLine( CATMemoryAddress* result )
+{
+ LOG_FUNC_ENTRY("CATAddr2line::AddressToLine");
+
+ result->SetAddressToLineState( CATMemoryAddress::OUT_OF_RANGE);
+
+ if( !server.GetProcessCreatedState() )
+ return false;
+ //Count address
+ ULONG uStartA = result->GetModuleStartAddress();
+ ULONG uMemoryA = result->GetAddress();
+ ULONG uCountedA = uMemoryA - uStartA;
+ uCountedA += FUNCTIONS_OFFSET_IN_GCCE;
+
+ string sTemp = CATBase::NumberToHexString( uCountedA );
+ //Remove "0x"
+ size_t iCounter = sTemp.find_first_of('x');
+ if( iCounter != string::npos )
+ {
+ sTemp.erase( 0, (int)iCounter+1 );
+ }
+ // Write to pipe that is the standard input for a child process.
+ server.WriteToPipe( sTemp );
+
+ // Read from pipe that is the standard output for child process.
+ string s = server.ReadFromPipe();
+
+ //If output not empty, parse output
+ if( !s.empty() )
+ {
+ //Debugging code for addr2line task.
+ //debug.write( "##########\n", 12 );
+ //debug.write( s.c_str(), s.size() );
+ result->SetAddressToLineState( CATMemoryAddress::EXACT );
+
+ string s2;
+ size_t iLocation = s.find_first_of( ASCII_CHAR_CARRIAGE_RETURN );
+
+ bool bFunctionNameFoundUsingAddr2line = false;
+
+ //Function name
+
+ if(iLocation != string::npos )
+ {
+ s2 = s.substr( 0, iLocation );
+ //All characters ascii?
+ if( CATBase::IsAscii( s2.c_str(), (int)s2.length() ) )
+ {
+ //addr2line returns $x if function name not found
+ //length must over 2 to be real function name
+ if( s2.length() > 2 )
+ {
+ bFunctionNameFoundUsingAddr2line = true;
+ result->SetFunctionName( s2 );
+ s.erase( 0, iLocation+2 );
+ }
+ }
+ }
+ //If function name not found using addr2line find it from map file
+ if( !bFunctionNameFoundUsingAddr2line )
+ {
+ string sFuncName( GetFunctionNameUsingAddress( uCountedA ) );
+ //If function name empty, print "???"
+ if( sFuncName.empty() )
+ {
+ s2 = "???";
+ result->SetFunctionName( s2 );
+ if(iLocation != string::npos )
+ {
+ s.erase( 0, iLocation+2 );
+ }
+ }
+ else
+ result->SetFunctionName( sFuncName );
+ }
+ iLocation = s.find_first_of( ':' );
+
+ //Filename and location
+
+ if(iLocation != string::npos )
+ {
+ s2 = s.substr( 0, iLocation );
+ result->SetFileName( s2 );
+ s.erase( 0, iLocation+1 );
+ }
+
+ //Exact line number
+
+ s2 = s.substr( 0, s.find_first_of( ASCII_CHAR_CARRIAGE_RETURN ) );
+ result->SetExactLineNumber( atoi( s2.c_str() ) );
+ }
+ return true;
+}
+
+bool CATAddr2line::ReadMapFileArmv5()
+{
+ LOG_FUNC_ENTRY("CATModule2::ReadMapFileArmv5");
+ // Open .map file
+ ifstream in( m_sMapFileName.c_str() );
+ // File open ok?
+ if( ! in.good() )
+ {
+ in.close();
+ return false;
+ }
+ char cTemp[MAX_LINE_LENGTH];
+ bool bFirstFuncFound = false;
+ bool bFirstLine = true;
+ // Get all lines where is "Thumb"
+ do
+ {
+ // Load one line from .map file
+ in.getline( cTemp, MAX_LINE_LENGTH );
+ if( bFirstLine )
+ {
+ bFirstLine = false;
+ if( strstr( cTemp, "ARM Linker" ) == NULL )
+ return false;
+ }
+ // Find _E32Startup
+ if( !bFirstFuncFound && ( strstr( cTemp, "_E32Startup" ) != NULL) )
+ {
+ bFirstFuncFound = true;
+ }
+ else if( !bFirstFuncFound && ( strstr( cTemp, "_E32Dll" ) != NULL) )
+ {
+ bFirstFuncFound = true;
+ }
+ else if( !bFirstFuncFound )
+ // Skip if _E32Startup not found
+ continue;
+
+ if( strstr( cTemp, "Thumb Code" ) != NULL || strstr( cTemp, "ARM Code" ) != NULL)
+ {
+ MAP_FUNC_INFO structMapFileLineInfo;
+ structMapFileLineInfo.sWholeLine.append( cTemp );
+
+ // Get memory string address from line
+ char* pStart = strstr( cTemp, "0x" );
+ // Check did strstr return null.
+ if ( pStart == NULL )
+ continue;
+ char* pTemp = pStart;
+ char TempString[MAX_LINE_LENGTH];
+ TempString[0] = 0;
+ size_t iLength = 0;
+ while( *pTemp != ' ' )
+ {
+ TempString[iLength] = *pTemp;
+ pTemp++;
+ iLength++;
+ }
+ TempString[iLength] = 0;
+
+ structMapFileLineInfo.iAddress = CATDatParser::_httoi( TempString );
+
+ pTemp = cTemp;
+ TempString[0] = 0;
+
+ // Get function name
+
+ // Skip spaces
+ while( *pTemp == ' ' )
+ {
+ pTemp++;
+ }
+ iLength = 0;
+ // Find end of function name
+ string sTemp( pTemp );
+
+ // Location of character ')'
+ iLength = sTemp.find_first_of(')');
+
+ // Location of character ' '
+ size_t iLength2 = sTemp.find_first_of(' ');
+
+ // If ')' character is the last char and
+ // character ' ' is closer than ')' use location of ' '
+ if( ( iLength + 1 ) == sTemp.length() && iLength2 < iLength )
+ iLength = iLength2 - 1;
+
+ if( iLength != string::npos )
+ sTemp.resize( (iLength + 1) );
+
+ structMapFileLineInfo.sFunctionName.append( sTemp.c_str() );
+
+ bool bARM = false;
+ // Find function length
+ pStart = strstr( cTemp, "Thumb Code" );
+ if( pStart == NULL )
+ {
+ pStart = strstr( cTemp, "ARM Code" );
+ bARM = true;
+ }
+ if( pStart != NULL )
+ {
+ if( bARM )
+ pStart += 8;
+ else
+ pStart += 10;
+ while(*pStart == ' ')
+ {
+ pStart++;
+ }
+ sTemp.clear();
+ sTemp.append( pStart );
+ size_t iSize = sTemp.find_first_of(' ');
+ if( iSize != string::npos )
+ sTemp.resize( iSize );
+ }
+
+ structMapFileLineInfo.iFuncLength = atoi( sTemp.c_str() );
+ if( bFirstFuncFound && structMapFileLineInfo.iFuncLength > 0 )
+ // Save to list
+ m_vMapFileFuncList.push_back( structMapFileLineInfo );
+ }
+ }
+ while( in.good() );
+ in.close();
+ return true;
+}
+
+// Find function name of given address
+string CATAddr2line::GetFunctionNameUsingAddress( unsigned long iAddress )
+{
+ LOG_LOW_FUNC_ENTRY("CATAddr2line::GetSymbolIndexUsingAddress");
+ string sRet;
+ for( size_t i = 0; i < m_vMapFileFuncList.size(); i++ )
+ {
+ unsigned long iStart = m_vMapFileFuncList.at( i ).iAddress;
+ unsigned long iEnd = ( m_vMapFileFuncList.at( i ).iAddress
+ + m_vMapFileFuncList.at( i ).iFuncLength );
+
+ if ( iAddress >= iStart && iAddress < iEnd )
+ return m_vMapFileFuncList.at( i ).sFunctionName;
+ }
+ return sRet;
+}
+
+//Note: New filtering functions commented out until they are taken into use.
+/**
+* Filter string out of unwanted characters.
+*/
+/*
+void CATAddr2line::FilterString( string &sString )
+{
+ LOG_LOW_FUNC_ENTRY("CATAddr2line::FilterString");
+ string sFiltered("");
+ for( size_t i = 0 ; i < sString.length() ; i++ )
+ {
+ const char p = sString.at( i );
+ if ( p != 0 && strchr( ADDR2LINEALLOWEDCHARS, p ) != 0 )
+ sFiltered.push_back( p );
+ }
+ sString = sFiltered;
+}
+*/
+/**
+* Find line feed position from string.
+*/
+/*
+size_t CATAddr2line::FindLineFeed( const string& sString )
+{
+ LOG_LOW_FUNC_ENTRY("CATAddr2line::FindLineFeed");
+ size_t iLineFeed1 = sString.find( 12 );
+ size_t iLineFeed2 = sString.find( 15 );
+ if ( iLineFeed1 < iLineFeed2 && iLineFeed1 != string::npos )
+ return iLineFeed1;
+ else if ( iLineFeed2 != string::npos )
+ return iLineFeed2;
+ else
+ return string::npos;
+}
+*/
+/**
+* Erase characters from start of the string until other char than linefeed found.
+*/
+/*
+void CATAddr2line::EraseUntilNoLineFeed( string& sString )
+{
+ LOG_LOW_FUNC_ENTRY("CATAddr2line::EraseUntilNoLineFeed");
+ for ( size_t i = 0 ; i < sString.length() ; i++ )
+ {
+ if ( sString.at( i ) != 15 && sString.at( i ) != 12 )
+ break;
+ }
+ sString.erase( 0, i );
+}
+*/
+/**
+* Split multiple line string with unexpected line feeds to vector of strings.
+*/
+/*
+vector<string> CATAddr2line::SplitToStrings( string& sMultiLineString )
+{
+ LOG_LOW_FUNC_ENTRY("CATAddr2line::SplitToStrings");
+ vector<string> vLines;
+ while ( 1 )
+ {
+ size_t iLineFeed = FindLineFeed( sMultiLineString );
+ if ( iLineFeed == string::npos )
+ break;
+ string sCell = sMultiLineString.substr(0, iLineFeed );
+ sMultiLineString.erase(0, iLineFeed );
+ EraseUntilNoLineFeed( sMultiLineString );
+ FilterString( sCell );
+ vLines.push_back( sCell );
+ }
+ // If no lines were found set single one.
+ if ( vLines.size() == 0 )
+ vLines.push_back( sMultiLineString );
+ return vLines;
+}
+*/
+//EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/cataddr2lineserver.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,286 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Class representing a server that uses addr2line.exe.
+*
+*/
+
+#include "../inc/cataddr2lineserver.h"
+#include "../inc/CATBase.h"
+
+// ----------------------------------------------------------------------------
+// Constructor
+// ----------------------------------------------------------------------------
+CATAddr2lineServer::CATAddr2lineServer()
+{
+ LOG_FUNC_ENTRY("CATAddr2lineServer::CATAddr2lineServer");
+ m_bProcessCreated = false;
+
+ // Pipe handles.
+ m_hChildErroutRd = 0;
+ m_hChildErroutRdDup = 0;
+ m_hChildErroutWr = 0;
+ m_hChildStdinRd = 0;
+ m_hChildStdinWr = 0;
+ m_hChildStdinWrDup = 0;
+ m_hChildStdoutRd = 0;
+ m_hChildStdoutWr = 0;
+ m_hChildStdoutRdDup = 0;
+
+ m_hSaveErrout = 0;
+ m_hSaveStdin = 0;
+ m_hSaveStdout = 0;
+
+ // Set the bInheritHandle flag so pipe handles are inherited.
+ m_saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
+ m_saAttr.bInheritHandle = TRUE;
+ m_saAttr.lpSecurityDescriptor = NULL;
+
+ // Symbol file.
+ m_sFullPathAndBinaryName = "";
+}
+// ----------------------------------------------------------------------------
+// Destructor
+// ----------------------------------------------------------------------------
+CATAddr2lineServer::~CATAddr2lineServer()
+{
+ LOG_FUNC_ENTRY("CATAddr2lineServer::~CATAddr2lineServer");
+ // Close the pipe handle so the child process stops reading.
+ CloseHandle(m_hChildStdinWrDup);
+ // Close the write end of the pipe
+ CloseHandle(m_hChildStdoutWr);
+ // Close the write end of the error pipe
+ CloseHandle(m_hChildErroutWr);
+}
+bool CATAddr2lineServer::Initialize( const string& sFullPathAndBinaryName )
+{
+ LOG_FUNC_ENTRY("CATAddr2lineServer::Initialize");
+ BOOL fSuccess;
+ m_sFullPathAndBinaryName = sFullPathAndBinaryName;
+
+ // The steps for redirecting child process's STDOUT:
+ // 1. Save current STDOUT, to be restored later.
+ // 2. Create anonymous pipe to be STDOUT for child process.
+ // 3. Set STDOUT of the parent process to be write handle to
+ // the pipe, so it is inherited by the child process.
+ // 4. Create a noninheritable duplicate of the read handle and
+ // close the inheritable read handle.
+
+ // Save the handle to the current STDOUT.
+ m_hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
+
+ // Create a pipe for the child process's STDOUT.
+ if (! CreatePipe(&m_hChildStdoutRd, &m_hChildStdoutWr, &m_saAttr, 0))
+ return PrintErrorAndExit( "Stdout pipe creation failed\n" );
+
+ // Set a write handle to the pipe to be STDOUT.
+ if (! SetStdHandle(STD_OUTPUT_HANDLE, m_hChildStdoutWr))
+ return PrintErrorAndExit( "Redirecting STDOUT failed\n" );
+
+ // Create noninheritable read handle and close the inheritable read
+ // handle.
+ fSuccess = DuplicateHandle(GetCurrentProcess(), m_hChildStdoutRd,
+ GetCurrentProcess(), &m_hChildStdoutRdDup , 0,
+ FALSE,
+ DUPLICATE_SAME_ACCESS);
+ if( !fSuccess )
+ return PrintErrorAndExit( "DuplicateHandle failed" );
+ CloseHandle(m_hChildStdoutRd);
+
+ // The steps for redirecting child process's STDIN:
+ // 1. Save current STDIN, to be restored later.
+ // 2. Create anonymous pipe to be STDIN for child process.
+ // 3. Set STDIN of the parent to be the read handle to the
+ // pipe, so it is inherited by the child process.
+ // 4. Create a noninheritable duplicate of the write handle,
+ // and close the inheritable write handle.
+
+ // Save the handle to the current STDIN.
+ m_hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);
+
+ // Create a pipe for the child process's STDIN.
+ if (! CreatePipe(&m_hChildStdinRd, &m_hChildStdinWr, &m_saAttr, 0))
+ return PrintErrorAndExit( "Stdin pipe creation failed\n" );
+
+ // Set a read handle to the pipe to be STDIN.
+ if (! SetStdHandle(STD_INPUT_HANDLE, m_hChildStdinRd))
+ return PrintErrorAndExit( "Redirecting Stdin failed\n" );
+
+ // Duplicate the write handle to the pipe so it is not inherited.
+
+ fSuccess = DuplicateHandle(GetCurrentProcess(), m_hChildStdinWr,
+ GetCurrentProcess(), &m_hChildStdinWrDup, 0,
+ FALSE, // not inherited
+ DUPLICATE_SAME_ACCESS);
+ if (! fSuccess)
+ return PrintErrorAndExit( "DuplicateHandle failed\n" );
+
+ CloseHandle(m_hChildStdinWr);
+
+ // The steps for redirecting child process's ERROUT:
+ // 1. Save current STDOUT, to be restored later.
+ // 2. Create anonymous pipe to be STDOUT for child process.
+ // 3. Set STDOUT of the parent process to be write handle to
+ // the pipe, so it is inherited by the child process.
+ // 4. Create a noninheritable duplicate of the read handle and
+ // close the inheritable read handle.
+
+ // Save the handle to the current STDOUT.
+ m_hSaveErrout = GetStdHandle( STD_ERROR_HANDLE );
+
+ // Create a pipe for the child process's ERROUT.
+ if (! CreatePipe(&m_hChildErroutRd, &m_hChildErroutWr, &m_saAttr, 0))
+ return PrintErrorAndExit( "Errout pipe creation failed\n" );
+
+ // Set a write handle to the pipe to be ERROUT.
+ if (! SetStdHandle(STD_ERROR_HANDLE, m_hChildErroutWr))
+ return PrintErrorAndExit( "Redirecting ERROUT failed\n" );
+
+ // Create noninheritable read handle and close the inheritable read
+ // handle.
+
+ fSuccess = DuplicateHandle(GetCurrentProcess(), m_hChildErroutRd,
+ GetCurrentProcess(), &m_hChildErroutRdDup , 0,
+ FALSE,
+ DUPLICATE_SAME_ACCESS);
+ if( !fSuccess )
+ return PrintErrorAndExit( "DuplicateHandle failed" );
+
+ CloseHandle(m_hChildErroutRd);
+ CloseHandle(m_hChildErroutRdDup);
+
+ // Now create the child process.
+ fSuccess = CreateChildProcess();
+ if (!fSuccess )
+ return PrintErrorAndExit( "Create process failed\n" );
+
+ // After process creation, restore the saved STDIN and STDOUT.
+ if (! SetStdHandle(STD_INPUT_HANDLE, m_hSaveStdin))
+ return PrintErrorAndExit( "Re-redirecting Stdin failed\n" );
+
+ if (! SetStdHandle(STD_OUTPUT_HANDLE, m_hSaveStdout))
+ return PrintErrorAndExit( "Re-redirecting Stdout failed\n" );
+
+ if (! SetStdHandle(STD_ERROR_HANDLE, m_hSaveErrout))
+ return PrintErrorAndExit( "Re-redirecting Stderrout failed\n" );
+
+ m_bProcessCreated = true;
+ return true;
+}
+BOOL CATAddr2lineServer::CreateChildProcess()
+{
+ LOG_FUNC_ENTRY("CATAddr2lineServer::CreateChildProcess");
+ PROCESS_INFORMATION piProcInfo;
+ STARTUPINFO siStartInfo;
+ BOOL bFuncRetn = FALSE;
+
+ // Set up members of the PROCESS_INFORMATION structure.
+ ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
+
+ // Set up members of the STARTUPINFO structure.
+ ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
+ siStartInfo.cb = sizeof(STARTUPINFO);
+
+ //atool.exe:s path + filename
+ char buffer[MAX_PATH];
+
+ GetModuleFileName( NULL, buffer, MAX_PATH );
+
+ string sCommand( buffer );
+
+ //Remove 'atool.exe'
+ size_t tPos = sCommand.rfind( "\\" );
+ if ( tPos != string::npos )
+ sCommand.resize( sCommand.rfind( "\\" )+1 );
+ else
+ sCommand.clear();
+
+ sCommand.append( "addr2line.exe" );
+
+ //addr2line file exists
+ if( !CATBase::FileExists( sCommand.c_str() ) )
+ return PrintErrorAndExit( "File not found addr2line.exe\n" );
+
+ //Sym file exists
+ if( !CATBase::FileExists( m_sFullPathAndBinaryName.c_str() ) )
+ {
+ string sTemp( "File not found " );
+ sTemp.append( m_sFullPathAndBinaryName );
+ sTemp.append( "\n" );
+ return PrintErrorAndExit( sTemp );
+ }
+
+ sCommand.append(" -f -C -e ");
+ sCommand.append( m_sFullPathAndBinaryName );
+
+ // Create the child process.
+ bFuncRetn = CreateProcess(NULL,
+ (LPSTR)sCommand.c_str(), // command line
+ NULL, // process security attributes
+ NULL, // primary thread security attributes
+ TRUE, // handles are inherited
+ 0, // creation flags
+ NULL, // use parent's environment
+ NULL, // use parent's current directory
+ &siStartInfo, // STARTUPINFO pointer
+ &piProcInfo); // receives PROCESS_INFORMATION
+
+ if (bFuncRetn == 0)
+ {
+ //CreateProcess failed
+ return false;
+ }
+ else
+ {
+ CloseHandle(piProcInfo.hProcess);
+ CloseHandle(piProcInfo.hThread);
+ return bFuncRetn;
+ }
+}
+VOID CATAddr2lineServer::WriteToPipe( const string& sAddress )
+{
+ LOG_LOW_FUNC_ENTRY("CATAddr2lineServer::WriteToPipe");
+ DWORD dwRead, dwWritten;
+ CHAR chBuf[2]; //This is for enter key
+
+ //Write data to a pipe.
+ dwRead = (DWORD)sAddress.length();
+ WriteFile(m_hChildStdinWrDup, sAddress.c_str(), dwRead, &dwWritten, NULL);
+
+ chBuf[0] = 0x0A; //Enter
+ chBuf[1] = 0; //NULL
+ //Write enter key to a pipe
+ WriteFile(m_hChildStdinWrDup, chBuf, 1, &dwWritten, NULL);
+}
+string CATAddr2lineServer::ReadFromPipe(VOID)
+{
+ LOG_LOW_FUNC_ENTRY("CATAddr2lineServer::ReadFromPipe");
+ string s;
+ DWORD dwRead;
+ CHAR chBuf[BUFSIZE];
+ // Read output from the child process, and save data to string.
+ ReadFile( m_hChildStdoutRdDup, chBuf, BUFSIZE, &dwRead, NULL);
+ s.append( chBuf );
+ return s;
+}
+bool CATAddr2lineServer::GetProcessCreatedState( void )
+{
+ LOG_LOW_FUNC_ENTRY("CATAddr2lineServer::GetProcessCreatedState");
+ return m_bProcessCreated;
+}
+bool CATAddr2lineServer::PrintErrorAndExit( const string sInput )
+{
+ LOG_FUNC_ENTRY("CATAddr2lineServer::PrintErrorAndExit");
+ cout << AT_MSG << sInput;
+ return false;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/catalloc.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,64 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+#include "../inc/ATCommonDefines.h"
+#include "../inc/catalloc.h"
+
+string CATAlloc::GetAllocString( void )
+{
+ LOG_LOW_FUNC_ENTRY("CATAlloc::GetAllocString");
+ // Create alloc string
+ string sLine("");
+ sLine.append( m_sTime ); sLine.append(" " );
+ sLine.append( m_sSize );
+
+ // Add all call stack fragments to line.
+ string sCallStack;
+ map<unsigned long, string>::iterator it;
+ for( it = m_vCallStack.begin() ; it != m_vCallStack.end() ; it++ )
+ {
+ sCallStack.append( (*it).second );
+ sCallStack.append( " " );
+ }
+ // Remove the last space
+ if ( sCallStack.size() > 0 )
+ sCallStack.erase( sCallStack.size()-1, 1 );
+
+ if ( m_iCSCount != 0 )
+ {
+ // Check integrity (calculate number of spaces in call stack)
+ unsigned long iCount = 0;
+ size_t pos = 0;
+ while ( pos != string::npos )
+ {
+ iCount++;
+ pos = sCallStack.find_first_of( ' ', pos+1 );
+ }
+ if ( iCount != m_iCSCount )
+ cout << AT_MSG << "Error, integrity check failed in alloc." << endl;
+ }
+
+ // Add call stack to line.
+ if ( sCallStack.size() > 0 )
+ {
+ sLine.append(" " );
+ sLine.append( sCallStack );
+ }
+
+ // return alloc line.
+ return sLine;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/catallocs.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,176 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+#include "../inc/ATCommonDefines.h"
+#include "../inc/catallocs.h"
+
+void CATAllocs::Alloc( const string& sAllocString )
+{
+ LOG_LOW_FUNC_ENTRY("CATAllocs::Alloc");
+ string sAlloc( sAllocString );
+ CATAlloc alloc;
+ string sAddress = GetStringUntilNextSpace( sAlloc, true );
+ alloc.m_sTime = GetStringUntilNextSpace( sAlloc, true );
+ alloc.m_sSize = GetStringUntilNextSpace( sAlloc, true );
+ alloc.m_vCallStack.insert( pair<unsigned long,string>(1, sAlloc) );
+ // Add allocation
+ pair< map<string,CATAlloc>::iterator, bool> ret;
+ ret = m_vAllocs.insert( pair<string, CATAlloc>( sAddress, alloc ) );
+ if( ret.second == false )
+ {
+ // Allocation to this memory address was already added.
+ LOG_STRING( "CATAllocs: Allocating same address again, address: " << sAddress );
+ }
+}
+
+void CATAllocs::AllocH( const string& sAllocHString )
+{
+ LOG_LOW_FUNC_ENTRY("CATAllocs::AllocH");
+ string sAllocH( sAllocHString );
+ // Parse alloc & create new allocation.
+ CATAlloc alloc;
+ string sAddress = GetStringUntilNextSpace( sAllocH, true );
+ alloc.m_sTime = GetStringUntilNextSpace( sAllocH, true );
+ alloc.m_sSize = GetStringUntilNextSpace( sAllocH, true );
+ alloc.m_iCSCount = _httoi( string( GetStringUntilNextSpace( sAllocH, true ) ).c_str() );
+ // Insert call stack fragment as "first" 1 because we are header.
+ if ( alloc.m_iCSCount > 0 )
+ alloc.m_vCallStack.insert( pair<unsigned long,string>( 0, sAllocH ) );
+ // Add allocation
+ pair< map<string,CATAlloc>::iterator, bool> ret;
+ ret = m_vAllocs.insert( pair<string, CATAlloc>( sAddress, alloc ) );
+ if( ret.second == false )
+ {
+ // Allocation to this memory address was already added.
+ LOG_STRING( "CATAllocs: Allocating same address again, address: " << sAddress );
+ }
+}
+
+void CATAllocs::AllocF( const string& sAllocFString )
+{
+ LOG_LOW_FUNC_ENTRY("CATAllocs::AllocF");
+ string sAllocF( sAllocFString );
+ string sAddress = GetStringUntilNextSpace( sAllocF, true );
+ string sTime = GetStringUntilNextSpace( sAllocF, true );
+ unsigned long iNumber = _httoi( string( GetStringUntilNextSpace( sAllocF, true ) ).c_str() );
+ string sCallSstack = sAllocF;
+ // Find correct allocation into which add call stack fragment.
+ map<string, CATAlloc>::iterator it;
+ it = m_vAllocs.find( sAddress );
+ // TODO: If cannot find, create new in cache.
+ if ( it == m_vAllocs.end() )
+ {
+ LOG_STRING( "CATAllocs: Allocate fragment without header: " << sAddress );
+ return;
+ }
+ pair< map<unsigned long,string>::iterator, bool> ret;
+ // Add call stack to it.
+ ret = it->second.m_vCallStack.insert( pair<unsigned long,string>( iNumber, sCallSstack ) );
+ if( ret.second == false )
+ {
+ LOG_STRING( "CATAllocs: Same allocation fragment again: " << sAddress );
+ }
+}
+
+// Free message.
+void CATAllocs::Free( const string& sFreeString )
+{
+ LOG_LOW_FUNC_ENTRY("CATAllocs::Free");
+ string sFree( sFreeString );
+ string sKey = GetStringUntilNextSpace( sFree );
+ // Find related allocation.
+ map<string, CATAlloc>::iterator it;
+ it = m_vAllocs.find( sKey );
+ if ( it == m_vAllocs.end() )
+ {
+ LOG_STRING( "CATAllocs: Free message which has no alloc pair: " << sKey );
+ return;
+ }
+ // Delete it.
+ m_vAllocs.erase( it );
+}
+
+// FreeH.
+void CATAllocs::FreeH( const string& sFreeH )
+{
+ LOG_LOW_FUNC_ENTRY("CATAllocs::FreeH");
+ // Current implementation does not use call stack of
+ // free message to anything.
+ string sFree( sFreeH );
+ string sKey = GetStringUntilNextSpace( sFree );
+ // Time stamp. (not used currently)
+ // Call stack count. (not used currently)
+ // Call stack data. (not used currently)
+
+ // Find related allocation.
+ map<string, CATAlloc>::iterator it;
+ it = m_vAllocs.find( sKey );
+ if ( it == m_vAllocs.end() )
+ {
+ LOG_STRING( "CATAllocs: FreeH message which has no alloc pair: " << sKey );
+ return;
+ }
+ // Delete it.
+ m_vAllocs.erase( it );
+}
+
+// FreeF.
+void CATAllocs::FreeF( const string& /* sFreeF */ )
+{
+ LOG_LOW_FUNC_ENTRY("CATAllocs::FreeF");
+ // Fragments are currently ignored.
+ // Memory address. (not used currently)
+ // Time stamp. (not used currently)
+ // Packet number. (not used currently)
+ // Call stack data. (not used currently)
+}
+
+// Get "leak" list ordered by allocation time.
+void CATAllocs::GetLeakList( vector<string>& vLeakList )
+{
+ LOG_LOW_FUNC_ENTRY("CATAllocs::GetLeakList");
+
+ // Create multimap where key is timestamp.
+ // Add allocations there so they will go ascending order.
+ multimap<string,string> mmap;
+ multimap<string,string>::iterator itMmap;
+
+ map<string, CATAlloc>::iterator it;
+ for( it = m_vAllocs.begin(); it != m_vAllocs.end() ; it++ )
+ {
+ string sTime = it->second.m_sTime;
+
+ string sLine = it->first;
+ sLine.append(" ");
+ sLine.append( it->second.GetAllocString() );
+
+ mmap.insert( pair<string,string>( sTime, sLine ) );
+ }
+
+ // Iterate list to parameter vector.
+ vLeakList.clear();
+ for ( itMmap = mmap.begin(); itMmap != mmap.end(); itMmap++ )
+ vLeakList.push_back( itMmap->second );
+}
+
+// Clear alloc data.
+void CATAllocs::ClearAllocs( void )
+{
+ LOG_LOW_FUNC_ENTRY("CATAllocs::ClearAllocs");
+ m_vAllocs.clear();
+}
+
+//EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/catdbghelper.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,314 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Windows debug api implementation for IAddressToLine interface.
+*
+*/
+
+#include "../inc/catdbghelper.h"
+#include "../inc/CATBase.h"
+#include "../inc/CATMemoryAddress.h"
+#include <dbghelp.h>
+
+/**
+* Notes on version number of api functions.
+* 5.1 Windows XP
+* 5.2 Windows Server 2003
+* 6.8 Debugging Tools for Windows 6.8
+* SymSetOptions DbgHelp.dll 5.1 or later
+* SymSetSearchPath DbgHelp.dll 5.1 or later
+* SymLoadModuleEx Versions 5.2 and 6.0
+* SymLoadModule64 DbgHelp.dll 5.1 or later
+* SymFromAddr Versions 4.0 and 5.1
+* SymGetLineFromAddr64 DbgHelp.dll 5.1 or later
+*/
+
+// Wrapper class for symbol information package.
+struct CSymbolInfo : public SYMBOL_INFO_PACKAGE
+{
+ CSymbolInfo()
+ {
+ si.SizeOfStruct = sizeof( SYMBOL_INFO );
+ si.MaxNameLen = sizeof( name );
+ }
+};
+
+// Wrapper class for line information container.
+struct CLineInfo : public IMAGEHLP_LINE64
+{
+ CLineInfo()
+ {
+ SizeOfStruct = sizeof( IMAGEHLP_LINE64 );
+ }
+};
+
+CATDbgHelper::CATDbgHelper()
+{
+ LOG_FUNC_ENTRY("CATDbgHelper::CDbgHelper");
+ // Set the some "default" base address.
+ m_BaseAddress = 0x2;
+ m_bMap = false;
+ m_pBinaryFile = NULL;
+}
+
+CATDbgHelper::~CATDbgHelper()
+{
+ LOG_FUNC_ENTRY("CATDbgHelper::~CDbgHelper");
+ // Close dbghelper only once.
+ if ( CDBGHELPER_OPEN )
+ {
+ Close();
+ }
+ if ( m_pBinaryFile )
+ {
+ delete[] m_pBinaryFile;
+ m_pBinaryFile = NULL;
+ }
+}
+
+bool CATDbgHelper::Open( const string& sParameter, const unsigned long iLong )
+{
+ LOG_FUNC_ENTRY("CATDbgHelper::Open");
+ // Verify that file exits. Version 5.1.2600.5512 of dbghelp.dll does not correctly
+ // return error code if missing image file. This can lead upto applicaton crash.
+ if ( ! CATBase::FileExists( sParameter.c_str() ) )
+ {
+ LOG_STRING( "Missing image file: " << sParameter );
+ return false;
+ }
+
+ // Is it urel try read map?
+ if ( sParameter.find( "\\urel\\" ) != string::npos )
+ {
+ string sMapFile = sParameter;
+ sMapFile.append( ".map" );
+ ReadMapFile( sMapFile );
+ }
+
+ // Set base address used
+ m_BaseAddress = iLong + AT_VIRTUAL_OFFSET_DBGHELPER;
+ // Binary file (also referred as symbol).
+ size_t length = sParameter.length();
+ if ( length == 0 )
+ {
+ LOG_STRING("DbgHelp:Invalid binary parameter.");
+ return false;
+ }
+
+ char* pChar = new char[ sParameter.length()+1 ];
+ strcpy( pChar, sParameter.c_str() );
+ // Have to be casted to PSTR before using dbg api. Even tho its typedef same.
+ // This will avoid access violations bug.
+ // Note pChar is not deleted because its the member pointer just casted its
+ // memory allocation freed in destructor.
+ if ( m_pBinaryFile )
+ delete[] m_pBinaryFile;
+
+ m_pBinaryFile = (PSTR) pChar;
+
+ // Initialize dbghelper if not done only once.
+ if ( ! CDBGHELPER_OPEN )
+ {
+ // Set symbol options
+ SymSetOptions( SYMOPT_LOAD_LINES | SYMOPT_DEBUG | SYMOPT_UNDNAME | SYMOPT_LOAD_ANYTHING );
+ if ( !SymInitialize( GetCurrentProcess(), NULL, TRUE ) )
+ {
+ LOG_STRING("DbgHelp:Error initializing dbghelper " << (int) GetLastError());
+ return false;
+ }
+ LOG_STRING("DbgHelp:dbghelper opened.");
+ CDBGHELPER_OPEN = true;
+ }
+
+ // Set symbol search path.
+ if ( !SymSetSearchPath( GetCurrentProcess(), NULL ) )
+ {
+ LOG_STRING("DbgHelp:Error setting symbol search path " << (int) GetLastError());
+ return false;
+ }
+
+ // Load module.
+ DWORD64 ret;
+ ret = SymLoadModule64( GetCurrentProcess(), NULL, m_pBinaryFile, NULL, m_BaseAddress, NULL ); // 5.1 api version.
+ if ( ret != m_BaseAddress && ret != 0)
+ {
+ LOG_STRING("Dbghelp:Module load failed " << (int) GetLastError());
+ return false;
+ }
+ CDBGHELPER_CLIENTS++;
+ return true;
+}
+
+string CATDbgHelper::GetError( void )
+{
+ LOG_FUNC_ENTRY("CATDbgHelper::GetError");
+ return string("not implemented.");
+}
+
+bool CATDbgHelper::Close( void )
+{
+ LOG_FUNC_ENTRY("CATDbgHelper::Close");
+ if ( ! SymUnloadModule64( GetCurrentProcess(), m_BaseAddress ) )
+ {
+ LOG_STRING("Dbghelp:Module unload failed.");
+ }
+ CDBGHELPER_CLIENTS--;
+ if ( CDBGHELPER_OPEN && CDBGHELPER_CLIENTS == 0)
+ {
+ // Cleanup dbghelper.
+ if ( ! SymCleanup( GetCurrentProcess() ) )
+ {
+ LOG_STRING("dbghelper cleanup failed.");
+ return false;
+ }
+ LOG_STRING("dbghelper closed.");
+ // Set state not opened.
+ CDBGHELPER_OPEN = false;
+ }
+ return true;
+}
+
+bool CATDbgHelper::AddressToLine( CATMemoryAddress* result )
+{
+ LOG_FUNC_ENTRY("CATDbgHelper::AddressToLine");
+
+ // Set state out of range
+ result->SetAddressToLineState( CATMemoryAddress::OUT_OF_RANGE );
+
+ // check that dbghelper has been initialized successfully.
+ if ( ! CDBGHELPER_OPEN )
+ return false;
+
+ // Check has binary been moved, if so unload and load to new base address.
+ if ( result->GetModuleStartAddress() + AT_VIRTUAL_OFFSET_DBGHELPER != m_BaseAddress )
+ {
+ // Unload.
+ if ( SymUnloadModule64( GetCurrentProcess(), m_BaseAddress ) )
+ {
+ // Set new base address.
+ m_BaseAddress = result->GetModuleStartAddress() + AT_VIRTUAL_OFFSET_DBGHELPER;
+ // (Re)load.
+ DWORD64 loading = SymLoadModule64( GetCurrentProcess(), NULL, m_pBinaryFile, NULL, m_BaseAddress, NULL );
+ if ( loading != m_BaseAddress && loading != 0)
+ {
+ LOG_STRING("Dbghelp:Module load failed " << (int) GetLastError());
+ return false;
+ }
+ }
+ else
+ LOG_STRING("Dbghelp:Module unload failed " << (int) GetLastError() );
+ }
+ // Address to find (offset+given address).
+ unsigned long iAddressToFind = result->GetAddress() + AT_VIRTUAL_OFFSET_DBGHELPER;
+ // Displacements of line/symbol information.
+ DWORD64 displacementSymbol;
+ DWORD displacementLine;
+ // Structure to get symbol information.
+ CSymbolInfo symbol;
+ // Structure to get line information.
+ CLineInfo line;
+ // Find Symbol for given address
+ if( ! SymFromAddr( GetCurrentProcess(), iAddressToFind , &displacementSymbol, &symbol.si ) )
+ {
+ LOG_STRING("Failed to find symbol information for given line.");
+ return AddressToFunction( result );
+ }
+ // Find line information
+ if( ! SymGetLineFromAddr64( GetCurrentProcess(), iAddressToFind, &displacementLine, &line ) )
+ {
+ // If it fails get symbol line information
+ LOG_STRING("Dbghelp:Failed to find line information for address, trying for symbol of address.");
+ if( ! SymGetLineFromAddr64( GetCurrentProcess(), symbol.si.Address, &displacementLine, &line ) )
+ {
+ LOG_STRING("Dbghelp:Failed to find line information for symbol address.");
+ return AddressToFunction( result );
+ }
+ }
+ // Set the results.
+ result->SetFileName( string( line.FileName ) );
+ result->SetFunctionName( string( symbol.si.Name ) );
+ result->SetExactLineNumber( (int) line.LineNumber );
+ result->SetAddressToLineState( CATMemoryAddress::EXACT );
+ // Return.
+ return true;
+}
+
+bool CATDbgHelper::AddressToFunction( CATMemoryAddress* result )
+{
+ LOG_FUNC_ENTRY("CATDbgHelper::AddressToFunction");
+ bool bFound = false;
+ // If map file read use it and return.
+ if ( m_bMap )
+ {
+ ULONG uCountedA = result->GetOffSetFromModuleStart();
+ for ( vector<MAP_FUNC_INFO>::iterator it = m_vMapFileFuncList.begin() ; it != m_vMapFileFuncList.end() ; it++ )
+ {
+ // Check is this the symbol where address is.
+ unsigned long iStart = it->iAddress;
+ unsigned long iEnd = it->iAddress + it->iFuncLength;
+ if ( uCountedA >= iStart
+ && uCountedA < iEnd )
+ {
+ result->SetAddressToLineState( CATMemoryAddress::SYMBOL );
+ result->SetFunctionName( it->sMangledName );
+ bFound = true;
+ break;
+ }
+ }
+ }
+ return bFound;
+}
+
+void CATDbgHelper::ReadMapFile( const string sMapFileName )
+{
+ LOG_FUNC_ENTRY("CATDbgHelper::ReadMapFile");
+ try {
+ ifstream in( sMapFileName.c_str() );
+ if ( ! in.good() )
+ {
+ in.close();
+ return;
+ }
+ char cLine[MAX_LINE_LENGTH];
+ do {
+ in.getline( cLine, MAX_LINE_LENGTH );
+ // Search pattern for 'image ro' symbols is ".text"
+ string sLine( cLine );
+ if ( sLine.find( ".text" ) != string::npos )
+ {
+ MAP_FUNC_INFO symbol;
+ // Pickup symbol attributes
+ // Address
+ string sAddress = CATBase::GetStringUntilNextSpace( sLine, true );
+ symbol.iAddress = CATBase::_httoi( sAddress.c_str() );
+ // Lenght
+ string sLength = CATBase::GetStringUntilNextSpace( sLine, true );
+ symbol.iFuncLength = CATBase::_httoi( sLength.c_str() );
+ // Name
+ size_t iStart = sLine.find_first_of( '(' );
+ size_t iEnd = sLine.find_last_of( ')' );
+ if ( iStart != string::npos && iEnd != string::npos )
+ {
+ symbol.sMangledName = sLine.substr( iStart+1, iEnd-iStart-1 );
+ // Add symbol to vector
+ m_vMapFileFuncList.push_back( symbol );
+ }
+ }
+ } while ( in.good() );
+ in.close();
+ m_bMap = true;
+ } catch (...) {
+ m_bMap = false;
+ LOG_STRING("DbgHelp: Error reading map file.");
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/catfilereader.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,111 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Class for reading ascii files in AnalyzeTool.
+*
+*/
+
+#include "../inc/ATCommonDefines.h"
+#include "../inc/catfilereader.h"
+
+// -----------------------------------------------------------------------------
+// CATFileReader::CATFileReader
+// Constructor.
+// -----------------------------------------------------------------------------
+CATFileReader::CATFileReader()
+{
+ LOG_FUNC_ENTRY("CATFileReader::CATFileReader");
+ m_cDelimiter = '\r'; // default line delimeter
+}
+
+// -----------------------------------------------------------------------------
+// CATFileReader::~CATFileReader
+// Destructor.
+// -----------------------------------------------------------------------------
+CATFileReader::~CATFileReader()
+{
+ LOG_FUNC_ENTRY("CATFileReader::~CATFileReader");
+}
+
+// -----------------------------------------------------------------------------
+// CATFileReader::Open
+// Open / Read file.
+// -----------------------------------------------------------------------------
+bool CATFileReader::Open( const char* cFile )
+{
+ LOG_FUNC_ENTRY("CATFileReader::Open");
+ if ( strlen( cFile ) < 1 )
+ {
+ LOG_STRING("CATFileReader::Open empty file argument.");
+ return false;
+ }
+ try {
+ ifstream in;
+ in.open( cFile, ios::binary );
+ if ( ! in.good() )
+ return false;
+ m_stream << in.rdbuf();
+ in.close();
+ }
+ catch(...)
+ {
+ LOG_STRING("CATFileReader::Open unhandled exception.");
+ return false;
+ }
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATFileReader::Close
+// Close file.
+// -----------------------------------------------------------------------------
+bool CATFileReader::Close( void )
+{
+ LOG_FUNC_ENTRY("CATFileReader::Close");
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATFileReader::GetLine
+// Get line from file.
+// -----------------------------------------------------------------------------
+bool CATFileReader::GetLine( string& sLine )
+{
+ //LOG_FUNC_ENTRY("CATFileReader::GetLine");
+ char cLine[MAX_LINE_LENGTH];
+ if ( !m_stream.good() )
+ return false;
+ m_stream.getline( cLine, MAX_LINE_LENGTH, m_cDelimiter ); m_stream.get();
+ sLine = cLine;
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATFileReader::SetDelimiter
+// Set line delimiting character.
+// -----------------------------------------------------------------------------
+void CATFileReader::SetDelimiter( char cDelimiter )
+{
+ LOG_FUNC_ENTRY("CATFileReader::SetDelimiter");
+ m_cDelimiter = cDelimiter;
+}
+
+// -----------------------------------------------------------------------------
+// CATFileReader::GetDelimiter
+// Get current line delimiting character.
+// -----------------------------------------------------------------------------
+char CATFileReader::GetDelimiter() const
+{
+ LOG_FUNC_ENTRY("CATFileReader::GetDelimiter()");
+ return m_cDelimiter;
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/catromsymbol.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,656 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Reads rom symbol file and provides interface to acquire
+* binary and function information using memory addresss.
+*
+*/
+
+#include "../inc/ATCommonDefines.h"
+#include "../inc/catromsymbol.h"
+#include "../inc/catfilereader.h"
+#include "../inc/CATBase.h"
+#include "../inc/CATMemoryAddress.h"
+
+// -----------------------------------------------------------------------------
+// RofsBinary::RofsBinary
+// Default construcor
+// -----------------------------------------------------------------------------
+RofsBinary::RofsBinary()
+{
+ LOG_LOW_FUNC_ENTRY("RofsBinary::RofsBinary");
+ m_sBinary = "";
+ vSymbols.clear();
+}
+
+// -----------------------------------------------------------------------------
+// RofsBinary::RofsBinary
+// Construcor
+// -----------------------------------------------------------------------------
+RofsBinary::RofsBinary( const string& sBinary )
+{
+ LOG_LOW_FUNC_ENTRY("RofsBinary::RofsBinary");
+ m_sBinary = sBinary;
+ vSymbols.clear();
+}
+
+// -----------------------------------------------------------------------------
+// RofsBinary::~RofsBinary
+// Destructor
+// -----------------------------------------------------------------------------
+RofsBinary::~RofsBinary()
+{
+ LOG_LOW_FUNC_ENTRY("RofsBinary::~RofsBinary");
+ for ( vector<Symbol*>::iterator it = vSymbols.begin() ; it != vSymbols.end() ; it++ )
+ delete *it;
+ vSymbols.clear();
+}
+
+// -----------------------------------------------------------------------------
+// CATRomSymbol::CATRomSymbol
+// Constructor.
+// -----------------------------------------------------------------------------
+CATRomSymbol::CATRomSymbol()
+{
+ LOG_FUNC_ENTRY("CATRomSymbol::CATRomSymbol");
+ m_bSymbolsRead = false;
+ m_iRomEndAddress = 0;
+ m_iRomStartAddress = 0;
+ m_vRomFiles.clear();
+ m_sErrorMessage = "";
+ m_vRomCache.clear();
+ m_vRomSymbols.clear();
+ m_bShowProgressMessages = false;
+}
+
+// -----------------------------------------------------------------------------
+// CATRomSymbol::~CATRomSymbol
+// Destructor.
+// -----------------------------------------------------------------------------
+CATRomSymbol::~CATRomSymbol()
+{
+ LOG_FUNC_ENTRY("CATRomSymbol::~CATRomSymbol");
+ // Rom
+ for ( vector<Symbol*>::iterator it = m_vRomSymbols.begin() ; it != m_vRomSymbols.end() ; it++ )
+ {
+ delete *it;
+ }
+ m_vRomSymbols.clear();
+ // Rofs
+ for ( vector<RofsBinary*>::iterator it = m_vRofsBinaries.begin() ; it != m_vRofsBinaries.end() ; it++ )
+ {
+ delete *it;
+ }
+ m_vRofsBinaries.clear();
+}
+
+// -----------------------------------------------------------------------------
+// CATRomSymbol::Open
+// This funtion should not be used anymore since
+// we support multiple rom/rofs files.
+// -----------------------------------------------------------------------------
+bool CATRomSymbol::Open( const string& /*sString*/, const unsigned long /*iLong*/)
+{
+ LOG_FUNC_ENTRY("CATRomSymbol::Open");
+ return false;
+}
+
+// -----------------------------------------------------------------------------
+// CATRomSymbol::SetSymbols
+// Set symbol file(s) to be used.
+// This also checks that files exists and identifies them as rom/rofs.
+// -----------------------------------------------------------------------------
+bool CATRomSymbol::SetSymbols( const vector<string>& vSymbols )
+{
+ LOG_FUNC_ENTRY("CATRomSymbol::SetSymbols");
+ bool ok = true;
+ // Check no same symbol defined twice.
+ for( vector<string>::const_iterator it = vSymbols.begin() ;
+ it != vSymbols.end(); it++ )
+ {
+ for( vector<string>::const_iterator it2 = vSymbols.begin() ;
+ it2 != vSymbols.end(); it2++ )
+ {
+ if ( it == it2 )
+ continue;
+ if ( _stricmp( (*it).c_str(), (*it2).c_str() ) == 0 )
+ {
+ m_sErrorMessage.append( "Same symbol file defined twice (" );
+ m_sErrorMessage.append( (*it) );
+ m_sErrorMessage.append( ")\n" );
+ return false;
+ }
+ }
+ }
+ // Loop given symbol files.
+ for( vector<string>::const_iterator it = vSymbols.begin() ;
+ it != vSymbols.end(); it++ )
+ {
+ // Symbol file exists?
+ if ( ! CATBase::FileExists( (*it).c_str() ) )
+ {
+ ok = false;
+ m_sErrorMessage.append( "Symbol file does not exists (" );
+ m_sErrorMessage.append( *it );
+ m_sErrorMessage.append( ").\n");
+ continue;
+ }
+ // Identify symbol file.
+ int type = IdentifySymbolFile( *it );
+ // Depending on type move it correct vector.
+ switch( type )
+ {
+ case SYMBOL_FILE_INVALID:
+ ok = false;
+ m_sErrorMessage.append( "Symbol file with invalid content (" );
+ m_sErrorMessage.append( *it );
+ m_sErrorMessage.append( ").\n");
+ break;
+ case SYMBOL_FILE_ROM:
+ m_vRomFiles.push_back( *it );
+ break;
+ case SYMBOL_FILE_ROFS:
+ m_vRofsFiles.push_back( *it );
+ break;
+ default:
+ ok = false;
+ LOG_STRING("IdentifySymbolFile returned unknown type.");
+ break;
+ }
+ }
+ if ( ok )
+ {
+ // Read symbols.
+ if ( m_vRomFiles.size() > 0 )
+ {
+ if ( ! ReadRomFiles() )
+ ok = false;
+ else
+ m_bSymbolsRead = true;
+ }
+ if ( m_vRofsFiles.size() > 0 )
+ {
+ if ( ! ReadRofsFiles() )
+ ok = false;
+ else
+ m_bSymbolsRead = true;
+ }
+ }
+ return ok;
+}
+
+// -----------------------------------------------------------------------------
+// CATRomSymbol::IdentifySymbolFile
+// Identify given file is it rom / rofs.
+// -----------------------------------------------------------------------------
+int CATRomSymbol::IdentifySymbolFile( const string& sFile )
+{
+ LOG_FUNC_ENTRY("CATRomSymbol::IdentifySymbolFile");
+ // Set type as invalid.
+ int iType = SYMBOL_FILE_INVALID;
+ // Line counter.
+ int iLineCount = 0;
+ // Minimun line length to identify it.
+ size_t iLineMinLength = MAX_LINE_LENGTH;
+ if ( ROFS_SYMBOL_IDENTIFY_STRING.length() > ROM_SYMBOL_IDENTIFY_STRING.length() )
+ iLineMinLength = ROFS_SYMBOL_IDENTIFY_STRING.length();
+ else
+ iLineMinLength = ROM_SYMBOL_IDENTIFY_STRING.length();
+ try {
+ ifstream in;
+ in.open( sFile.c_str(), ios::in );
+ if ( ! in.good() )
+ return SYMBOL_FILE_INVALID;
+ char cLine[MAX_LINE_LENGTH];
+ do {
+ // Dont read too many lines. (File might be contain invalid data).
+ iLineCount++;
+ if ( iLineCount > IDENTIFY_MAX_LINES_READ )
+ break;
+
+ // Get line -> string.
+ in.getline( cLine, MAX_LINE_LENGTH );
+ string sLine(cLine);
+
+ // Check its not too short.
+ if( sLine.length() < iLineMinLength )
+ continue;
+
+ // Take substring from start of line to identify it to rofs/rom.
+ if ( ! sLine.substr( 0, ROFS_SYMBOL_IDENTIFY_STRING.length() ).compare( ROFS_SYMBOL_IDENTIFY_STRING ) )
+ {
+ iType = SYMBOL_FILE_ROFS;
+ break;
+ }
+ else if ( ! sLine.substr( 0, ROM_SYMBOL_IDENTIFY_STRING.length() ).compare( ROM_SYMBOL_IDENTIFY_STRING ) )
+ {
+ iType = SYMBOL_FILE_ROM;
+ break;
+ }
+ } while ( in.good() );
+ in.close();
+ }
+ catch(...)
+ {
+ LOG_STRING("CATRomSymbol::IdentifySymbolFile unhandled exception.");
+ }
+ return iType;
+}
+
+// -----------------------------------------------------------------------------
+// CATRomSymbol::ReadRomFiles
+// Reads rom file(s) and creates symbols to vector.
+// -----------------------------------------------------------------------------
+bool CATRomSymbol::ReadRomFiles()
+{
+ LOG_FUNC_ENTRY("CATRomSymbol::ReadRomFile");
+
+ // Clear symbols.
+ for ( vector<Symbol*>::iterator it = m_vRomSymbols.begin() ; it != m_vRomSymbols.end() ; it++ )
+ {
+ delete *it;
+ }
+ m_vRomSymbols.clear();
+
+ // Clear cache. note cache is just pointers dont delete them.
+ m_vRomCache.clear();
+
+ // Any errors?
+ bool ok = true;
+
+ for( vector<string>::iterator it = m_vRomFiles.begin();
+ it != m_vRomFiles.end() ; it++ )
+ ok = ReadRomFile( *it );
+
+ // If size smaller than 1 it is not good rom file(s).
+ if ( m_vRomSymbols.size() < 1 || ok != true)
+ return false;
+
+ // Rom start and end addresses.
+ m_iRomStartAddress = (*m_vRomSymbols.begin())->iStartAddress;
+ m_iRomEndAddress = (*m_vRomSymbols.rbegin())->iEndAddress;
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATRomSymbol::ReadRofsFiles
+// Read rofs files.
+// -----------------------------------------------------------------------------
+bool CATRomSymbol::ReadRofsFiles()
+{
+ LOG_FUNC_ENTRY("CATRomSymbol::ReadRofsFiles");
+ // Clear.
+ for ( vector<RofsBinary*>::iterator it = m_vRofsBinaries.begin() ; it != m_vRofsBinaries.end() ; it++ )
+ {
+ delete *it;
+ }
+ m_vRofsBinaries.clear();
+
+ // Any errors?
+ bool ok = true;
+
+ for( vector<string>::iterator it = m_vRofsFiles.begin();
+ it != m_vRofsFiles.end() ; it++ )
+ ok = ReadRofsFile( *it );
+
+ // If size smaller than 1 it is not good rofs file(s).
+ if ( m_vRofsBinaries.size() < 1 || ok != true)
+ return false;
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATRomSymbol::ReadRomFile
+// Read given rom file
+// -----------------------------------------------------------------------------
+bool CATRomSymbol::ReadRomFile( const string& sFile )
+{
+ LOG_FUNC_ENTRY("CATRomSymbol::ReadRomfile");
+ // Open rom file.
+ CATFileReader* reader = new CATFileReader();
+ // Show progress message if flag set.
+ if ( m_bShowProgressMessages )
+ cout << AT_MSG << "Reading rom symbol file: " << sFile << "..." << endl;
+ if ( ! reader->Open( sFile.c_str() ) )
+ {
+ reader->Close();
+ delete reader;
+ return false;
+ }
+
+ // Show progress message if flag set.
+ if ( m_bShowProgressMessages )
+ cout << AT_MSG << "Parsing rom symbol file: " << sFile << "..." << endl;
+
+ // Loop thrue lines.
+ string sLine("");
+ string sBinary("");
+ while( reader->GetLine( sLine ) )
+ {
+ // From rom we just read symbols that have lenght, no need to separate them into diff binaries.
+ try {
+ if ( sLine.size() < 2 )
+ {
+ continue;
+ }
+ else if ( sLine.at(0) == '8' )
+ {
+ // Create new item.
+ Symbol* symbol = new Symbol();
+ ParseSymbolFromLine( sLine, symbol);
+ // Ignore symbols which have same start & end address (zero length).
+ if ( symbol->iStartAddress != symbol->iEndAddress )
+ m_vRomSymbols.push_back( symbol );
+ else
+ delete symbol;
+ }
+ } catch(...)
+ {
+ // Catch all possible exception here so analyze will succeed even rom file invalid.
+ m_sErrorMessage.append( "Unhandled exception parsing rom symbol file.\n" );
+ // Close and delete reader.
+ reader->Close();
+ delete reader;
+ return false;
+ }
+ }
+ // Close and delete reader.
+ reader->Close();
+ delete reader;
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATRomSymbol::ReadRofsFile
+// Read given rofs file
+// -----------------------------------------------------------------------------
+bool CATRomSymbol::ReadRofsFile( const string& sFile )
+{
+ LOG_FUNC_ENTRY("CATRomSymbol::ReadRofsFile");
+ // open/read rofs file.
+ CATFileReader* reader = new CATFileReader();
+ // Show progress message if flag set.
+ if ( m_bShowProgressMessages )
+ cout << AT_MSG << "Reading rofs symbol file: " << sFile << "..." << endl;
+ if ( ! reader->Open( sFile.c_str() ) )
+ {
+ reader->Close();
+ delete reader;
+ return false;
+ }
+
+ // Show progress message if flag set.
+ if ( m_bShowProgressMessages )
+ cout << AT_MSG << "Parsing rofs symbol file: " << sFile << "..." << endl;
+
+ // Loop thrue lines.
+ string sLine("");
+ string sBinary("");
+ RofsBinary* rb = NULL;
+ while( reader->GetLine( sLine ) )
+ {
+ try {
+ if ( sLine.size() < 2 )
+ {
+ continue;
+ }
+ else if ( sLine.at(0) == 'F' )
+ {
+ if ( rb != NULL )
+ {
+ // Check last binary if no symbols in it dont add it.
+ if ( rb->vSymbols.size() == 0 )
+ {
+ delete rb;
+ rb = NULL;
+ }
+ else
+ m_vRofsBinaries.push_back( rb );
+ }
+ // new binary name.
+ size_t i = sLine.rfind("\\");
+ sLine.erase(0, i+1);
+ rb = new RofsBinary( sLine );
+
+ }
+ else if ( sLine.at(0) == '0' )
+ {
+ // Cannot pickup symbols if no binary defined.
+ if ( rb == NULL )
+ continue;
+ // Create new item.
+ Symbol* symbol = new Symbol();
+ ParseSymbolFromLine( sLine, symbol);
+ // Ignore symbols which have same start & end address (zero length).
+ if ( symbol->iStartAddress != symbol->iEndAddress )
+ rb->vSymbols.push_back( symbol );
+ else
+ delete symbol;
+ }
+ } catch(...)
+ {
+ // Catch all possible exception here so analyze will succeed even rofs file invalid.
+ m_sErrorMessage.append( "Unhandled exception parsing rofs symbol file.\n" );
+ // Close and delete reader.
+ reader->Close();
+ delete reader;
+ return false;
+ }
+ }
+ // Last added binary.
+ if ( rb != NULL )
+ {
+ if ( rb->vSymbols.size() == 0 )
+ {
+ delete rb;
+ rb = NULL;
+ }
+ else
+ m_vRofsBinaries.push_back( rb );
+ }
+ // Close and delete reader.
+ reader->Close();
+ delete reader;
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATRomSymbol::ParseSymbolFromLine
+// Parses given line into given symbol.
+// -----------------------------------------------------------------------------
+void CATRomSymbol::ParseSymbolFromLine( const string& sLine, Symbol* pSymbol )
+{
+ LOG_LOW_FUNC_ENTRY("CATRomSymbol::ParseSymbolFromLine");
+ if ( pSymbol == NULL )
+ return;
+ size_t s,x;
+ string temp;
+ // address.
+ x = sLine.find( ' ' );
+ temp = sLine.substr( 0, x );
+ pSymbol->iStartAddress = CATBase::_httoi( temp.c_str() );
+ // "Erase spaces" move starting point.
+ s = x;
+ s = sLine.find_first_not_of( ' ', s );
+ // length.
+ x = sLine.find( ' ', s );
+ temp = sLine.substr(s,x-s);
+ unsigned long length = CATBase::_httoi( temp.c_str() );
+ pSymbol->iEndAddress = pSymbol->iStartAddress + length;
+ // "Erase spaces" move starting point.
+ s = x;
+ s = sLine.find_first_not_of( ' ', s);
+ // function. Function might have spaces so we find 2 spaces which indicates end of it.
+ x = sLine.find( " ", s );
+ temp = sLine.substr( s, x-s );
+ pSymbol->sFunction = temp;
+}
+
+// -----------------------------------------------------------------------------
+// CATRomSymbol::GetError
+// Get error string if error occured in other methods.
+// -----------------------------------------------------------------------------
+string CATRomSymbol::GetError( void )
+{
+ LOG_FUNC_ENTRY("CATRomSymbol::GetError");
+ return m_sErrorMessage;
+}
+
+// -----------------------------------------------------------------------------
+// CATRomSymbol::Close
+// Close (stop using).
+// -----------------------------------------------------------------------------
+bool CATRomSymbol::Close( void )
+{
+ LOG_FUNC_ENTRY("CATRomSymbol::Close");
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+// CATRomSymbol::AddressToLine
+// Try locate binary and function name for given memory address.
+// -----------------------------------------------------------------------------
+bool CATRomSymbol::AddressToLine( CATMemoryAddress* result )
+{
+ LOG_LOW_FUNC_ENTRY("CATRomSymbol::AddressToLine");
+ // Have symbols been read.
+ if ( ! m_bSymbolsRead )
+ return false;
+ // check that its lenght > 2
+ if ( result->GetAddressString().size() < 2 )
+ return false;
+ /* Check first is address in range of rom */
+ if ( result->GetAddress() < m_iRomStartAddress
+ || result->GetAddress() > m_iRomEndAddress )
+ {
+ return AddressToLineRofs( result );
+ }
+ return AddressToLineRom( result );
+}
+
+// -----------------------------------------------------------------------------
+// CATRomSymbol::AddressToLineRom
+// Locate function from rom address range.
+// -----------------------------------------------------------------------------
+bool CATRomSymbol::AddressToLineRom( CATMemoryAddress* result )
+{
+ LOG_LOW_FUNC_ENTRY( "CATRomSymbol::AddressToLineRom" );
+ // Address to find in integer & string.
+ unsigned long iAddressToFind = result->GetAddress();
+ string sAddressToFind = result->GetAddressString();
+
+ // Find symbol.
+ Symbol* pFound = NULL;
+
+ // Check from cache first.
+ vector<Symbol*>::iterator it;
+ for ( it = m_vRomCache.begin(); it != m_vRomCache.end(); it++ )
+ {
+ if ( iAddressToFind >= (*it)->iStartAddress
+ && (*it)->iEndAddress > iAddressToFind )
+ {
+ pFound = *it;
+ break;
+ }
+ }
+
+ if ( pFound == NULL )
+ {
+ // From all symbols.
+ bool reverse = false;
+ int offSetFromStart = iAddressToFind - m_iRomStartAddress;
+ int offSetFromEnd = m_iRomEndAddress - iAddressToFind;
+ if ( offSetFromEnd < offSetFromStart )
+ reverse = true;
+
+ if ( reverse )
+ {
+ // Iterate vector in reverse.
+ vector<Symbol*>::reverse_iterator it;
+ for ( it = m_vRomSymbols.rbegin(); it != m_vRomSymbols.rend(); ++it )
+ {
+ if ( iAddressToFind >= (*it)->iStartAddress
+ && (*it)->iEndAddress > iAddressToFind )
+ {
+ pFound = *it;
+ break;
+ }
+ }
+ }
+ else
+ {
+ // Iterate vector normal direction.
+ vector<Symbol*>::iterator it;
+ for ( it = m_vRomSymbols.begin(); it != m_vRomSymbols.end(); it++ )
+ {
+ if ( iAddressToFind >= (*it)->iStartAddress
+ && (*it)->iEndAddress > iAddressToFind )
+ {
+ pFound = *it;
+ break;
+ }
+ }
+ }
+ }
+
+ // Set result if found.
+ if ( pFound != NULL )
+ {
+ result->SetFunctionName( pFound->sFunction );
+ result->SetAddressToLineState( CATMemoryAddress::SYMBOL );
+ // Add found symbols pointer to cache.
+ m_vRomCache.push_back( pFound );
+ return true;
+ }
+ return false;
+}
+
+// -----------------------------------------------------------------------------
+// CATRomSymbol::AddressToLineRofs
+// Locate function from rofs address range.
+// -----------------------------------------------------------------------------
+bool CATRomSymbol::AddressToLineRofs( CATMemoryAddress* result)
+{
+ LOG_LOW_FUNC_ENTRY("CATRomSymbol::AddressToLineRofs");
+ // Check that binary name is defined in memory address.
+ string sBinary = result->GetModuleName();
+ if ( sBinary.empty() )
+ return false;
+ // Try find that named module.
+ vector<RofsBinary*>::iterator rofs = m_vRofsBinaries.begin();
+ while( rofs != m_vRofsBinaries.end() )
+ {
+ if ( (*rofs)->m_sBinary.compare( sBinary ) == 0 )
+ break;
+ rofs++;
+ }
+ if ( rofs == m_vRofsBinaries.end() )
+ return false;
+
+ // Offset what we are looking from binary
+ unsigned long offSet = result->GetAddress();
+ offSet -= result->GetModuleStartAddress();
+ for( vector<Symbol*>::iterator it = (*rofs)->vSymbols.begin() ;
+ it != (*rofs)->vSymbols.end(); it++ )
+ {
+ if ( (*it)->iStartAddress <= offSet && offSet < (*it)->iEndAddress )
+ {
+ result->SetFunctionName( (*it)->sFunction );
+ result->SetAddressToLineState( CATMemoryAddress::SYMBOL );
+ return true;
+ }
+ }
+ return false;
+}
+
+//EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/helps.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,180 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Contains help texts for CLE.
+*
+*/
+#include "../inc/ATCommonDefines.h"
+
+//Function declarations
+void print_help( void );
+void print_syntax_examples( void );
+
+/**
+* Print help info.
+*/
+void print_help( void )
+{
+ cout<< "AnalyzeTool v";
+ cout<< ATOOL_VERSION;
+ cout<< " - ";
+ cout<< ATOOL_DATE;
+ cout<< "\n";
+ cout<< "Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).\nAll rights reserved.\n\n";
+ cout<< "Usage:\n";
+ cout<< "atool -e [optional parameters] abld [abld parameters]\n";
+ cout<< " -me [optional parameters] abld [abld parameters]\n";
+ cout<< " -mi [optional parameters] [-f data-file] sbs [sbs parameters]\n";
+ cout<< " -a data-file [output-file] [-s symbol-file] [-l#]\n";
+ cout<< " -p data-file output-file\n";
+ cout<< " -c\n";
+ cout<< " -v\n";
+ cout<< " -help\n";
+ cout<< "\n";
+ cout<< "Mandatory parameter to choose:\n";
+ cout<< " -e Build project for analysis using external data gathering.\n";
+ cout<< " -me Build project for analysis using monitored external\n";
+ cout<< " data gathering.\n";
+ cout<< " -mi Build project for analysis using monitored internal\n";
+ cout<< " data gathering.\n";
+ cout<< " abld... Use SBS v.1 build system with defined build command,\n";
+ cout<< " which includes supported platform and build type.\n";
+ cout<< " sbs... Use SBS v.2 (Raptor) build system with defined sbs build\n";
+ cout<< " command, which includes supported platform and build type.\n";
+ cout<< " -a Analyze report file.\n";
+ cout<< " -c Clear AnalyzeTool changes, temporary files and releasable(s).\n";
+ cout<< " -p Parse trace file to data file.\n";
+ cout<< " -help Show full help including syntax examples.\n";
+ cout<< " -v Print version info.\n";
+ cout<< "\n";
+
+ cout<< "Optional parameters:\n";
+ cout<< " -acs size Specifies the call stack size gathered when memory\n";
+ cout<< " is allocated. Size can be between 0-256.\n";
+ cout<< " -fcs size Specifies the call stack size gathered when memory is freed.\n";
+ cout<< " Size can be between 0-256.\n";
+ cout<< " -f data file Specifies the filename for monitored internal data gathering\n";
+ cout<< " (50 chars max). Cannot contain path.\n";
+ cout<< " output-file Specifies the results data file name.\n";
+ cout<< " -l Logging level of analyze report(0,1,2,3), default 3.\n";
+ cout<< " -s symbol-file Specifies rom/rofs symbol file(s) to be used in analyze.\n";
+ cout<< " Multiple -s options can be given.\n";
+ cout<< " -nobuild Instruments the project.\n";
+ //cout<< " -show_debug Print debug messages to console.\n";
+ //cout<< " -show_debug_all Print debug messages to console (all).\n";
+ //cout<< " -show_dbgview Print debug messages to windows debug api.\n";
+ //cout<< " -show_dbgview_all Print debug messages to windows debug api (all).\n";
+
+ /*
+ * Old style parameters, just for notes.
+ printf("Usage:\n");
+ printf("atool -m [mmp-file] [mode] [data-file] [-variant variant-name] [build] [-sbs2] [-e]\n");
+ printf(" -i [mmp-file] [mode] [data-file] [-variant variant-name] [build] [-sbs2] [-e]\n");
+ printf(" -a [mmp-file | target-name] data-file [-s symbol-file]\n");
+ printf(" [output-file] [-l#]\n");
+ printf(" -p data-file [output-file]\n");
+ printf(" -c\n");
+ //printf(" -u\n");
+ printf(" -v\n");
+ printf(" -help\n");
+ printf("\n");
+ printf("Mandatory option to choose:\n");
+ printf(" -m Build project for analysis.\n");
+ printf(" -i Instrument project.\n");
+ printf(" -a Analyze report file.\n");
+ //printf(" -u Create listing & map files.\n");
+ printf(" -c Clear AnalyzeTool changes and temporary files.\n");
+ printf(" -p Parse trace file.\n");
+ printf(" -help Show full help including syntax examples.\n");
+ printf("\n");
+
+ printf("Optional options:\n");
+ printf(" mmp-file Specifies one of the component from bld.inf which is used.\n");
+ printf(" target-name Specifies the target name of binary to which create\n");
+ printf(" analyze report.\n");
+ printf(" mode Logging mode (trace or S60), default trace.\n");
+ printf(" data-file Specifies the user defined data file name (50 chars max).\n");
+ printf(" build Build target (udeb or urel), default udeb.\n");
+ printf(" output-file Specifies the results data file name.\n");
+ printf(" -l Logging level of analyze report(0,1,2,3), default 3.\n");
+ printf(" -variant Specifies Symbian binary variant to be used.\n");
+ printf(" variant-name Specifies the variant name to be used.\n");
+ printf(" -s Specifies rom symbol file be used in analyze.\n");
+ printf(" symbol-file Full path to rom symbol file used in analyze.\n");
+ printf(" -sbs2 Use Symbian Build System v.2.\n");
+ printf(" -winscw Build project for emulator (winscw platform).\n");
+ printf(" -v Print version info.\n");
+ */
+}
+
+void print_syntax_examples( void )
+{
+//Helper line showing width of 80 chars.
+//80cout<< "12345678901234567890123456789012345678901234567890123456789012345678901234567890";
+ cout<< endl;
+ cout<< "Building syntax examples:" << endl;
+ cout<< "Cmd Description" << endl;
+
+ cout<< "atool -e abld build armv5 udeb" << endl;
+ cout<< " Hooks every component from bld.inf. Using external data gathering," << endl;
+ cout<< " udeb build type and armv5 platform." << endl;
+
+ cout<< "atool -mi -acs 5 sbs -c winscw_udeb" << endl;
+ cout<< " Hooks every component from bld.inf. Using Symbian Build System v.2" << endl;
+ cout<< " Using monitored internal data gathering, call stack size of 5" << endl;
+ cout<< " in allocations, udeb build type and winscw platform." << endl;
+
+ cout<< "atool -me abld build armv5 udeb foobar" << endl;
+ cout<< " Hooks only foobar.mmp component from bld.inf. Using monitored" << endl;
+ cout<< " external data gathering, udeb build type and armv5 platform." << endl;
+
+ cout<< "atool -e -acs 0 -fcs 0 abld build armv5.default udeb" << endl;
+ cout<< " Hooks every component from bld.inf. Using default binary variant," << endl;
+ cout<< " external data gathering, 0 sized callstacks in allocation(s)/free(s)," << endl;
+ cout<< " udeb build type and armv5 platform." << endl;
+
+ cout<< "atool -e sbs -b bld.inf -c armv5_udeb" << endl;
+ cout<< " Hooks every component from bld.inf. Using Symbian Build System v.2" << endl;
+ cout<< " , external data gathering, udeb build type and armv5 platform." << endl;
+
+ cout<< "atool -me sbs -s system.xml --config=winscw_udeb" << endl;
+ cout<< " Hooks every layer defined in system.xml system model. Using Symbian Build" << endl;
+ cout<< " System v.2, external data gathering, udeb build type and winscw platform." << endl;
+
+ cout<< endl;
+ cout<< "Instrumenting syntax examples:" << endl;
+ cout<< "Cmd Description" << endl;
+ cout<< "atool -e -nobuild abld build winscw udeb" << endl;
+ cout<< " Instruments every component from bld.inf. Using external data gathering,"<<endl;
+ cout<< " udeb build target and winscw platform." << endl;
+ cout<< " After project is instrumented, it needs to compiled using same platform and" << endl;
+ cout<< " build type as given to instrumenting. Use -c parameter to remove changes." << endl;
+
+ cout<< endl;
+ cout<< "Analyzing syntax examples:" << endl;
+ cout<< "Cmd Description" << endl;
+ cout<< "atool -a foo.dat" << endl;
+ cout<< " Create analyze report from foo.dat device data file." << endl;
+ cout<< "atool -a foo.trace" << endl;
+ cout<< " Create analyze report from foo.trace raw data file." << endl;
+ cout<< "atool -a foo.dat -s my_rom.symbol -s my_rofs1.symbol" << endl;
+ cout<< " Create analyze report from foo.dat using also rom and rofs symbol files." << endl;
+
+ cout<< endl;
+ cout<< "Parsing syntax examples:" << endl;
+ cout<< "Cmd Description" << endl;
+ cout<< "atool -p foo.trace foo.dat" << endl;
+ cout<< " Parse foo.trace raw data file to foo.dat device data file." << endl;
+ }
+
+//EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/librarychecks.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,193 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Contains functions to check AT libraries.
+*
+*/
+#include "../inc/ATCommonDefines.h"
+#include "../inc/CATBase.h"
+
+// Function declarations
+bool CheckATLibrariesArmv5( string sEpocRoot );
+bool CheckATLibrariesArmv5Abiv2( string sEpocRoot );
+bool CheckATLibrariesWinscw( string sEpocRoot );
+
+// Error msg to user if missing lib
+const char cMissingAToolLibs[] = "\nCan not find AnalyzeTool libraries from current SDK\n\nInstall libraries first\n";
+
+// List of libraries what AnalyzeTool needs when compiled applications on armv5 platform
+const string cAToolLibsArmv5[] = {
+ "epoc32\\RELEASE\\armv5\\LIB\\AToolMemoryHook.lib",
+ "epoc32\\RELEASE\\armv5\\udeb\\AtoolStaticLib.lib",
+ "epoc32\\RELEASE\\armv5\\urel\\AtoolStaticLib.lib"
+};
+
+// List of libraries what AnalyzeTool needs when compiled applications on armv5 platform (using sbs2 / ABIV2 binaries)
+const string cAToolLibsArmv5Abiv2[] = {
+ "epoc32\\RELEASE\\armv5\\LIB\\AToolMemoryHook.dso",
+ "epoc32\\RELEASE\\armv5\\udeb\\AtoolStaticLib.lib",
+ "epoc32\\RELEASE\\armv5\\urel\\AtoolStaticLib.lib"
+};
+
+// List of libraries what AnalyzeTool needs when compiled applications on winscw platform
+const string cAToolLibsWinscw[] = {
+ "epoc32\\RELEASE\\winscw\\udeb\\AToolMemoryHook.lib",
+ "epoc32\\RELEASE\\winscw\\udeb\\AtoolStaticLib.lib",
+ "epoc32\\RELEASE\\winscw\\urel\\AtoolStaticLib.lib"
+};
+
+/**
+* CheckATLibrariesArmv5
+* Checks that armv5 libraries are in sEpocRoot
+* @param sEpocRoot, epoc root where to search libs
+* @return bool true if they are found otherwise false
+*/
+bool CheckATLibrariesArmv5(string sEpocRoot )
+{
+ LOG_FUNC_ENTRY("CheckATLibrariesArmv5");
+
+ // check that epocroot is set
+ if ( sEpocRoot.length() <= 0 )
+ {
+ LOG_FUNC_EXIT("CheckATLibrariesArmv5 Error, EpocRoot not set");
+ return false;
+ }
+
+ // add trailing '\' if root path is missing it
+ if ( sEpocRoot.at( sEpocRoot.length() -1 ) != '\\' )
+ sEpocRoot.append( "\\" );
+
+ // return boolean value
+ bool bReturn = true;
+
+ int arraySize = sizeof( cAToolLibsArmv5 ) / sizeof( string );
+ for ( int i=0 ; i < arraySize ; i++ )
+ {
+ // append epocroot to file
+ string sFileToCheck = sEpocRoot;
+ sFileToCheck.append( cAToolLibsArmv5[i] );
+ // check does it exists
+ if ( ! CATBase::FileExists( sFileToCheck.c_str() ) )
+ {
+ bReturn = false;
+ cout << AT_MSG << "Missing library file: " << sFileToCheck << endl;
+ LOG_STRING("Missing library file: " << sFileToCheck);
+ }
+ }
+
+ if ( ! bReturn )
+ {
+ // print error msg to user
+ cout << cMissingAToolLibs;
+
+ }
+ return bReturn;
+}
+
+/**
+* CheckATLibrariesArmv5Abiv2
+* Checks that armv5 abiv2 libraries are in sEpocRoot
+* @param sEpocRoot, epoc root where to search libs
+* @return bool true if they are found otherwise false
+*/
+bool CheckATLibrariesArmv5Abiv2(string sEpocRoot )
+{
+ LOG_FUNC_ENTRY("CheckATLibrariesArmv5Abiv2");
+
+ // check that epocroot is set
+ if ( sEpocRoot.length() <= 0 )
+ {
+ LOG_FUNC_EXIT("CheckATLibrariesArmv5Abiv2 Error, EpocRoot not set");
+ return false;
+ }
+
+ // add trailing '\' if root path is missing it
+ if ( sEpocRoot.at( sEpocRoot.length() -1 ) != '\\' )
+ sEpocRoot.append( "\\" );
+
+ // return boolean value
+ bool bReturn = true;
+
+ int arraySize = sizeof( cAToolLibsArmv5Abiv2 ) / sizeof( string );
+ for ( int i=0 ; i < arraySize ; i++ )
+ {
+ // append epocroot to file
+ string sFileToCheck = sEpocRoot;
+ sFileToCheck.append( cAToolLibsArmv5Abiv2[i] );
+ // check does it exists
+ if ( ! CATBase::FileExists( sFileToCheck.c_str() ) )
+ {
+ bReturn = false;
+ cout << AT_MSG << "Missing library file: " << sFileToCheck << endl;
+ LOG_STRING("Missing library file: " << sFileToCheck);
+ }
+ }
+
+ if ( ! bReturn )
+ {
+ // print error msg to user
+ cout << cMissingAToolLibs;
+
+ }
+ return bReturn;
+}
+
+/**
+* CheckATLibrariesWinscw
+* Checks that winscw libraries are in sEpocRoot
+* @param sEpocRoot, epoc root where to search libs
+* @return bool true if they are found otherwise false
+*/
+bool CheckATLibrariesWinscw(string sEpocRoot )
+{
+ LOG_FUNC_ENTRY("CheckATLibrariesWinscw");
+
+ // check that epocroot is set
+ if ( sEpocRoot.length() <= 0 )
+ {
+ LOG_FUNC_EXIT("CheckATLibrariesArmv5Abiv2 Error, EpocRoot not set");
+ return false;
+ }
+
+ // add trailing '\' if root path is missing it
+ if ( sEpocRoot.at( sEpocRoot.length() -1 ) != '\\' )
+ sEpocRoot.append( "\\" );
+
+ // return boolean value
+ bool bReturn = true;
+
+ int arraySize = sizeof( cAToolLibsWinscw ) / sizeof( string );
+ for ( int i=0 ; i < arraySize ; i++ )
+ {
+ // append epocroot to file
+ string sFileToCheck = sEpocRoot;
+ sFileToCheck.append( cAToolLibsWinscw[i] );
+ // check does it exists
+ if ( ! CATBase::FileExists( sFileToCheck.c_str() ) )
+ {
+ bReturn = false;
+ cout << AT_MSG << "Missing library file: " << sFileToCheck << endl;
+ LOG_STRING("Missing library file: " << sFileToCheck);
+ }
+ }
+
+ if ( ! bReturn )
+ {
+ // print error msg to user
+ cout << cMissingAToolLibs;
+
+ }
+ return bReturn;
+}
+
+//EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/stdafx.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,20 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include "../inc/stdafx.h"
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/utility.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,38 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Miscellaneous utility functions.
+*
+*/
+#include "../inc/ATCommonDefines.h"
+#include "../inc/CATBase.h"
+#include "../inc/CATProject.h"
+
+//Analyze report logging level.
+#define MAX_LOG_LEVEL 3
+
+//Function declarations.
+bool CheckSBS2Folder( void );
+
+/**
+* Helper function which checks does current dir contain atool_temp\build folder which
+* is used in sbs2 support
+*/
+bool CheckSBS2Folder( void )
+{
+ LOG_FUNC_ENTRY("CheckSBS2Folder");
+ if ( CATBase::DirectoryExists( RAPTOR_MAKEFILE_DIR ) )
+ return true;
+ return false;
+}
+//EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/commandlineengine/src/version.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,258 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Show / Check atool version.
+*
+*/
+#include "../inc/ATCommonDefines.h"
+#include "../inc/CATBase.h"
+
+//Function declarations.
+int showVersionInfo( void );
+int showCoreVersionInfo( void );
+bool readCoreVersionInfo( const string& sFile, string& sVersion );
+string findAnalyzeToolHeader( void );
+int showDbgHelpVersionInfo( bool showVersion );
+int getDllVersion( LPCTSTR libName, WORD *majorVersion, WORD *minorVersion, WORD *buildNumber, WORD *revisionNumber );
+
+//External GetEpocRoot function
+extern bool GetEpocRoot( string &sEpocRoot );
+
+void convertWriteTimeToLocalTime( FILETIME ftWrite, LPSTR lpszString );
+
+int showCoreVersionInfo( void )
+{
+ LOG_FUNC_ENTRY( "version.cpp::showCoreVersionInfo" );
+ // Try find header from environment where to locate version info.
+ string sHeaderFile = findAnalyzeToolHeader();
+ if ( sHeaderFile.empty() )
+ return 0;
+ string sVersion("");
+ if ( readCoreVersionInfo( sHeaderFile, sVersion ) )
+ {
+ cout << "AnalyzeTool SDK binaries version: "
+ << sVersion
+ << endl;
+ }
+ return 0;
+}
+
+
+/**
+* Find analyzetool.h header file
+* @return string containing full path to file or empty string if not found.
+*/
+string findAnalyzeToolHeader( void )
+{
+ LOG_FUNC_ENTRY( "version.cpp::findAnalyzeToolHeader" );
+ string sEpocRoot;
+ if ( ! CATBase::GetEpocRoot( sEpocRoot ) )
+ return string("");
+ int iC = sizeof( AT_CORE_INCLUDE_FILE_WITH_VERSION_NUMBER ) / sizeof ( string );
+ for( int i = 0 ; i < iC ; i++ )
+ {
+ string sCheck( sEpocRoot );
+ sCheck.append( AT_CORE_INCLUDE_FILE_WITH_VERSION_NUMBER[i] );
+ if ( CATBase::FileExists( sCheck.c_str() ) )
+ return sCheck;
+ }
+ return string("");
+}
+/**
+* Read core version string.
+* @param sVersion string will contain version info if funtion returns true.
+* @return true if successful.
+*/
+bool readCoreVersionInfo( const string& sFile, string& sVersion )
+{
+ LOG_FUNC_ENTRY( "version.cpp::readCoreVersionInfo" );
+ try {
+ ifstream in;
+ in.open( sFile.c_str() );
+ if ( ! in.good() )
+ return false;
+ char cBuff[MAX_LINE_LENGTH];
+ while ( in.good() )
+ {
+ in.getline( cBuff, MAX_LINE_LENGTH );
+ string s( cBuff );
+ if ( s.find( AT_CORE_VERSION_NUMBER_TAG ) != string::npos )
+ {
+ // Find spot after first space (ignore first 3 chars).
+ size_t t = s.find_first_of( ' ', 3 )+1;
+ sVersion = s.substr( t, s.size()-t );
+ return true;
+ }
+ }
+ }
+ catch(...)
+ {
+ LOG_STRING(AT_MSG << "Exception reading core version info.");
+ }
+ return false;
+}
+
+/**
+* Print version information of atool.exe binary.
+*/
+int showVersionInfo( void )
+{
+ LOG_FUNC_ENTRY( "version.cpp::showVersionInfo" );
+ string sTemp( "Version: " );
+ sTemp.append( ATOOL_VERSION );
+ sTemp.append( "\n" );
+ //Print atool version
+ printf( sTemp.c_str() );
+
+ //atool.exe:s path + filename
+ char buffer[MAX_PATH];
+
+ GetModuleFileName( NULL, buffer, MAX_PATH );
+
+ printf( "Path: %s\n", buffer );
+
+ WIN32_FIND_DATA FindFileData;
+ HANDLE hFind;
+ //Get file handle
+ hFind = FindFirstFile( buffer, &FindFileData );
+
+ if( hFind == INVALID_HANDLE_VALUE )
+ {
+ printf( "Can not find file:%s", buffer );
+ return 0;
+ }
+
+ convertWriteTimeToLocalTime( FindFileData.ftLastWriteTime , buffer );
+ printf( "Modified: %s\n", buffer );
+
+ // Show core version information.
+ showCoreVersionInfo();
+ return 0;
+}
+
+// Convert the last-write time to local time.
+void convertWriteTimeToLocalTime( FILETIME ftWrite, LPSTR lpszString )
+{
+ LOG_FUNC_ENTRY( "version.cpp::convertWriteTimeToLocalTime" );
+ SYSTEMTIME stUTC, stLocal;
+ // Convert the last-write time to local time.
+ FileTimeToSystemTime(&ftWrite, &stUTC);
+ SystemTimeToTzSpecificLocalTime(NULL, &stUTC, &stLocal);
+
+ // Build a string showing the date and time.
+ wsprintf(lpszString, "%02d/%02d/%d %02d:%02d:%02d",
+ stLocal.wDay, stLocal.wMonth, stLocal.wYear,
+ stLocal.wHour, stLocal.wMinute, stLocal.wSecond);
+}
+
+/**
+* Print version information of dbghelp.dll.
+*/
+int showDbgHelpVersionInfo( bool showVersion )
+{
+ LOG_FUNC_ENTRY( "version.cpp::showDbgHelpVersionInfo" );
+
+ WORD majorVersion;
+ WORD minorVersion;
+ WORD buildNumber;
+ WORD revisionNumber;
+
+ if(getDllVersion( _T(DBGHELP_DLL_NAME), &majorVersion, &minorVersion, &buildNumber, &revisionNumber))
+ {
+ //Check if current dll version is lower than latest version
+ if((majorVersion < DBGHELP_VERSION_MAJ) ||
+ (majorVersion == DBGHELP_VERSION_MAJ && minorVersion < DBGHELP_VERSION_MIN) ||
+ (majorVersion == DBGHELP_VERSION_MAJ && minorVersion == DBGHELP_VERSION_MIN && buildNumber < DBGHELP_VERSION_BUILD) ||
+ (majorVersion == DBGHELP_VERSION_MAJ && minorVersion == DBGHELP_VERSION_MIN && buildNumber == DBGHELP_VERSION_BUILD && revisionNumber < DBGHELP_VERSION_REVIS))
+ {
+ cout << "WARNING: Version of your dbghelp.dll is "
+ << majorVersion << "."
+ << minorVersion << "."
+ << buildNumber << "."
+ << revisionNumber << ".\n";
+
+ cout << "Source code pinpointing for winscw may not work properly with this version."
+ << endl
+ << "Please, update it to at least version "
+ << DBGHELP_VERSION_MAJ << "."
+ << DBGHELP_VERSION_MIN << "."
+ << DBGHELP_VERSION_BUILD << "."
+ << DBGHELP_VERSION_REVIS << ".\n"
+ << "dbghelp.dll file is included in Debugging Tools from Microsoft. "
+ << "You can download and install it from\n"
+ << "http://www.microsoft.com/whdc/devtools/debugging/\n";
+
+ return 1;
+ }
+ else
+ {
+ if( showVersion )
+ {
+ cout << "Version of your dbghelp.dll is "
+ << majorVersion << "."
+ << minorVersion << "."
+ << buildNumber << "."
+ << revisionNumber << "."
+ << endl;
+ cout << "No need for update.\n";
+ }
+ }
+ }
+
+ return 0;
+}
+
+/**
+* Get dll version.
+* @param libName library name.
+* @param majorVersion will contain major version if funtion returns true.
+* @param minorVersion will contain minor version if funtion returns true.
+* @param buildNumber will contain build number if funtion returns true.
+* @param revisionNumber will contain revision number if funtion returns true.
+* @return true if successful.
+*/
+int getDllVersion( LPCTSTR libName, WORD *majorVersion, WORD *minorVersion, WORD *buildNumber, WORD *revisionNumber )
+{
+ LOG_FUNC_ENTRY( "version.cpp::getDllVersion" );
+
+ DWORD dwHandle, dwLen;
+ UINT BufLen;
+ LPTSTR lpData;
+ VS_FIXEDFILEINFO *pFileInfo;
+ dwLen = GetFileVersionInfoSize( libName, &dwHandle );
+ if (!dwLen)
+ return 0;
+
+ lpData = (LPTSTR) malloc (dwLen);
+ if (!lpData)
+ return 0;
+
+ if( !GetFileVersionInfo( libName, dwHandle, dwLen, lpData ) )
+ {
+ free (lpData);
+ return 0;
+ }
+
+ if( VerQueryValue( lpData, _T("\\"), (LPVOID *) &pFileInfo, (PUINT)&BufLen ) )
+ {
+ *majorVersion = HIWORD(pFileInfo->dwFileVersionMS);
+ *minorVersion = LOWORD(pFileInfo->dwFileVersionMS);
+ *buildNumber = HIWORD(pFileInfo->dwFileVersionLS);
+ *revisionNumber = LOWORD(pFileInfo->dwFileVersionLS);
+ return 1;
+ }
+ free (lpData);
+ return 0;
+}
+
+//EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/bwins/atoolmemoryhooku.def Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,10 @@
+EXPORTS
+ ?Alloc@RAnalyzeToolAllocator@@UAEPAXH@Z @ 1 NONAME ; void * RAnalyzeToolAllocator::Alloc(int)
+ ?Alloc@RAnalyzeToolMainAllocator@@UAEPAXH@Z @ 2 NONAME ; void * RAnalyzeToolMainAllocator::Alloc(int)
+ ?Exit@CustomUser@@SAXH@Z @ 3 NONAME ; void CustomUser::Exit(int)
+ ?InstallAllocator@CustomUser@@CAAAVRAllocator@@HABV?$TBuf@$0BAA@@@KKKK@Z @ 4 NONAME ; class RAllocator & CustomUser::InstallAllocator(int, class TBuf<256> const &, unsigned long, unsigned long, unsigned long, unsigned long)
+ ?Panic@CustomUser@@SAXABVTDesC16@@H@Z @ 5 NONAME ; void CustomUser::Panic(class TDesC16 const &, int)
+ ?SetCritical@CustomUser@@SAHW4TCritical@User@@@Z @ 6 NONAME ; int CustomUser::SetCritical(enum User::TCritical)
+ ?SetProcessCritical@CustomUser@@SAHW4TCritical@User@@@Z @ 7 NONAME ; int CustomUser::SetProcessCritical(enum User::TCritical)
+ ?SetupThreadHeap@CustomUser@@SAHHAAUSStdEpocThreadCreateInfo@@ABV?$TBuf@$0BAA@@@KKABV?$TBuf@$0BE@@@KKV?$TRefByValue@$$CBVTDesC16@@@@ZZ @ 8 NONAME ; int CustomUser::SetupThreadHeap(int, struct SStdEpocThreadCreateInfo &, class TBuf<256> const &, unsigned long, unsigned long, class TBuf<20> const &, unsigned long, unsigned long, class TRefByValue<class TDesC16 const >, ...)
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/eabi/atoolmemoryhooku.def Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,16 @@
+EXPORTS
+ _ZN10CustomUser11SetCriticalEN4User9TCriticalE @ 1 NONAME
+ _ZN10CustomUser15SetupThreadHeapEiR24SStdEpocThreadCreateInfoRK4TBufILi256EEmmRKS2_ILi20EEmm11TRefByValueIK7TDesC16Ez @ 2 NONAME
+ _ZN10CustomUser16InstallAllocatorEiRK4TBufILi256EEmmmm @ 3 NONAME
+ _ZN10CustomUser18SetProcessCriticalEN4User9TCriticalE @ 4 NONAME
+ _ZN10CustomUser4ExitEi @ 5 NONAME
+ _ZN10CustomUser5PanicERK7TDesC16i @ 6 NONAME
+ _ZTI20CLibraryEventHandler @ 7 NONAME ; #<TI>#
+ _ZTI21RAnalyzeToolAllocator @ 8 NONAME ; #<TI>#
+ _ZTI25RAnalyzeToolMainAllocator @ 9 NONAME ; #<TI>#
+ _ZTI27RAnalyzeToolMemoryAllocator @ 10 NONAME ; #<TI>#
+ _ZTV20CLibraryEventHandler @ 11 NONAME ; #<VT>#
+ _ZTV21RAnalyzeToolAllocator @ 12 NONAME ; #<VT>#
+ _ZTV25RAnalyzeToolMainAllocator @ 13 NONAME ; #<VT>#
+ _ZTV27RAnalyzeToolMemoryAllocator @ 14 NONAME ; #<VT>#
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/group/atoolmemoryhook.mmp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,68 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: The .mmp file for AToolMemoryHook.
+*
+*/
+
+#include <platform_paths.hrh>
+#include "../../symbian_version.hrh"
+
+TARGET atoolmemoryhook.dll
+TARGETTYPE dll
+UID 0x1000008d 0x2001242F
+CAPABILITY ALL -TCB
+
+#if ( SYMBIAN_VERSION_SUPPORT >= SYMBIAN_3 )
+EPOCALLOWDLLDATA
+#endif
+
+SMPSAFE
+
+SOURCEPATH ../src
+
+SOURCE analyzetooleventhandler.cpp
+SOURCE codeblock.cpp
+SOURCE threadstack.cpp
+SOURCE customuser.cpp
+SOURCE analyzetoolmemoryallocator.cpp
+SOURCE analyzetoolmainallocator.cpp
+SOURCE analyzetoolallocator.cpp
+SOURCE analyzetoolfastlog.cpp
+
+SOURCEPATH ../../storageserver/server/src
+SOURCE atdriveinfo.cpp
+
+USERINCLUDE ../inc
+USERINCLUDE ../../inc
+USERINCLUDE ../../storageserver/inc
+USERINCLUDE ../../storageserver/server/inc
+
+#ifdef WINSCW
+APP_LAYER_SYSTEMINCLUDE
+#endif
+
+OS_LAYER_SYSTEMINCLUDE
+
+LIBRARY efsrv.lib
+LIBRARY euser.lib
+LIBRARY atoolstorageserverclnt.lib
+LIBRARY flogger.lib
+LIBRARY charconv.lib
+LIBRARY platformenv.lib
+
+#if ( SYMBIAN_VERSION_SUPPORT >= SYMBIAN_3 )
+MACRO USE_CLEANER_DLL
+#endif
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/group/bld.inf Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,26 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+PRJ_PLATFORMS
+ARMV5 WINSCW
+
+PRJ_MMPFILES
+atoolmemoryhook.mmp
+
+PRJ_TESTMMPFILES
+../internal/tsrc/group/analyzetoolmemoryhooktest.mmp
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/inc/analyzetoolallocator.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,247 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Declaration of the class RAnalyzeToolAllocator.
+*
+*/
+
+
+#ifndef ANALYZETOOLALLOCATOR_H
+#define ANALYZETOOLALLOCATOR_H
+
+// INCLUDES
+#include <u32std.h>
+#include "codeblock.h"
+#include "threadstack.h"
+#include "analyzetoolmemoryallocator.h"
+#include <analyzetool/atstorageserverclnt.h>
+#include <analyzetool/analyzetool.h>
+#include <analyzetool/atcommon.h>
+
+// CLASS DECLARATION
+
+/**
+* Class which overloads the RAlloctor functions and provides access to
+* the overloaded functions
+*/
+class RAnalyzeToolAllocator : public RAnalyzeToolMemoryAllocator
+ {
+
+ public:
+
+ /**
+ * C++ default constructor.
+ * @param aNotFirst Is this first thread using this heap
+ * @param aStorageServer A reference to the
+ * <code>RATStorageServer</code> which is
+ * used to store kernel events
+ * @param aCodeblocks A reference to array of code segments
+ * @param aMutex A reference to mutex for schedule access to the
+ * shared resources
+ * @param aProcessId A reference to the observed process id
+ * @param aAnalyzeTool Reference to device driver
+ * @param aStorageServerOpen Variable to check if Storage server is connected
+ * @param aLogOption The logging option for storage server
+ * @param aAllocCallStackSize Max number of stored callstack items when memory allocated
+ * @param aFreeCallStackSize Max number of stored callstack items when memory freed
+ */
+ RAnalyzeToolAllocator( TBool aNotFirst,
+ RATStorageServer& aStorageServer,
+ RArray<TCodeblock>& aCodeblocks,
+ RMutex& aMutex,
+ TUint aProcessId,
+ RAnalyzeTool& aAnalyzeTool,
+ TBool aStorageServerOpen,
+ TUint32 aLogOption,
+ TUint32 aAllocCallStackSize,
+ TUint32 aFreeCallStackSize );
+ /**
+ * Destructor.
+ */
+ ~RAnalyzeToolAllocator();
+
+ /**
+ * Allocates a cell of specified size from the heap.
+ * @param aSize The size of the cell to be allocated from the heap.
+ * @return TAny* A pointer to the allocated cell.
+ */
+ TAny* Alloc( TInt aSize );
+
+ /**
+ * Frees the specified cell and returns it to the heap.
+ * @param aPtr A pointer to a cell to be freed.
+ */
+ void Free( TAny* aPtr );
+
+ /**
+ * Increases or decreases the size of an existing cell.
+ * @param aPtr A pointer to the cell to be reallocated.
+ * @param aSize The new size of the cell. This may be bigger
+ * or smaller than the size of the original cell.
+ * @param aMode Flags controlling the reallocation.
+ * @return TAny* A pointer to the reallocated cell. This may be the
+ * same as the original pointer supplied through aCell.
+ */
+ //lint --e{1735} suppress "Virtual function has default parameter"
+ TAny* ReAlloc( TAny* aPtr, TInt aSize, TInt aMode = 0 );
+
+ /**
+ * Gets the length of the available space in the specified
+ * allocated cell.
+ * @param aCell A pointer to the allocated cell.
+ * @return TInt The length of the available space in the allocated cell.
+ */
+ TInt AllocLen( const TAny* aCell ) const;
+
+ #ifndef __KERNEL_MODE__
+
+ /**
+ * Opens this heap for shared access. Opening the heap increases
+ * the heap's access count by one.
+ */
+ TInt Open();
+
+ /**
+ * Closes this shared heap. Closing the heap decreases the heap's
+ * access count by one.
+ */
+ void Close();
+
+ /**
+ * The function frees excess committed space from the top of the heap.
+ * The size of the heap is never reduced below the minimum size
+ * specified during creation of the heap.
+ * @return TInt The space reclaimed. If no space can be reclaimed,
+ then this value is zero.
+ */
+ TInt Compress();
+
+ /**
+ * Frees all allocated cells on this heap.
+ */
+ void Reset();
+
+ /**
+ * Gets the number of cells allocated on this heap, and
+ * the total space allocated to them.
+ * @param aTotalAllocSize On return, contains the total
+ * space allocated to the cells.
+ * @return TInt The number of cells allocated on this heap.
+ */
+ TInt AllocSize( TInt& aTotalAllocSize ) const;
+
+ /**
+ * Gets the total free space currently available on the heap and the
+ * space available in the largest free block. The space available
+ * represents the total space which can be allocated. Note that
+ * compressing the heap may reduce the total free space available
+ * and the space available in the largest free block.
+ * @param aBiggestBlock On return, contains the space available
+ * in the largest free block on the heap.
+
+ * @return TInt The total free space currently available on the heap.
+
+ */
+ TInt Available( TInt& aBiggestBlock ) const;
+
+ #endif
+
+ /**
+ * Invocates specified debug funtionality.
+ * @param aFunc The debug function
+ * @param a1 Debug function specific paramenter.
+ * @param a2 Debug function specific paramenter.
+ * @return TInt Returns KErrNone, if successful otherwise one
+ * of the other system-wide error codes.
+ */
+ //lint --e{1735} suppress "Virtual function has default parameter"
+ TInt DebugFunction( TInt aFunc, TAny* a1 = NULL, TAny* a2 = NULL );
+
+ protected:
+
+ /**
+ * Extension function
+ * @param aExtensionId The extension id
+ * @param a0 Extension specific paramenter.
+ * @param a1 Extension specific paramenter.
+ * @return TInt Returns KErrNone, if successful otherwise one
+ * of the other system-wide error codes.
+ */
+ TInt Extension_( TUint aExtensionId, TAny*& a0, TAny* a1 );
+
+ public: // from RAnalyzeToolMemoryAllocator
+
+ /**
+ * Installs the RTraceAllocator allocator
+ */
+ void Uninstall();
+
+ /**
+ * Shares the heap
+ */
+ void ShareHeap();
+
+ private:
+
+ /**
+ * Find the current thread which is using the heap
+ * @param aStackStart A reference where the stack start is stored
+ * @return TBool ETrue if a thread can be found, EFalse otherwise
+ */
+ TBool FindCurrentThreadStack( TUint32& aStackStart );
+
+ private:
+
+ /* Handle to the storage server*/
+ RATStorageServer& iStorageServer;
+
+ /* A reference to codeblocks of the observed process */
+ RArray<TCodeblock>& iCodeblocks;
+
+ /* The mutex for serializing access to the shared resources */
+ RMutex& iMutex;
+
+ /* The process id */
+ TUint iProcessId;
+
+ /* Array for storing the callstack */
+ TFixedArray<TUint32, KATMaxCallstackLength> iCallStack;
+
+ /* Array for storing the reallocation callstack */
+ TFixedArray <TUint32, KATMaxCallstackLength> iReCallStack;
+
+ /* Array for storing the reallocation callstack */
+ TFixedArray<TUint32, KATMaxFreeCallstackLength> iFreeCallStack;
+
+ /* Array of threads using this heap */
+ RArray<TThreadStack> iThreadArray;
+
+ RAnalyzeTool& iAnalyzeTool;
+
+ /* A flag for indicating that the RATStorageServer is open */
+ TBool iStorageServerOpen;
+
+ /* Log option */
+ TUint32 iLogOption;
+
+ /* Max items on stored call stack when memory allocated */
+ TUint32 iAllocMaxCallStack;
+
+ /* Max items on stored call stack when memory freed */
+ TUint32 iFreeMaxCallStack;
+
+ };
+
+#endif // ANALYZETOOLALLOCATOR_H
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/inc/analyzetooleventhandler.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,122 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Declaration of the class CLibraryEventHandler.
+*
+*/
+
+
+#ifndef ANALYZETOOLEVENTHANDLER_H
+#define ANALYZETOOLEVENTHANDLER_H
+
+// INCLUDES
+#include <e32cmn.h>
+#include "codeblock.h"
+#include <analyzetool/atstorageserverclnt.h>
+#include <analyzetool/analyzetool.h>
+
+// FORWARD DECLARATIONS
+class MAnalyzeToolEventhandlerNotifier;
+
+// CLASS DECLARATION
+
+/**
+* Class for receiving library load/unlaod events from the kernel
+*/
+class CLibraryEventHandler : public CActive
+ {
+
+ public:
+
+ /**
+ * C++ default constructor.
+ * @param aAnalyzeTool A reference to the <code>RAnalyzeTool</code>
+ which is used to observe kernel events
+ * @param aCodeblocks A reference to array of code segments
+ * @param aStorageServer A reference to the
+ * <code>RATStorageServer</code> which is
+ * used to store kernel events
+ * @param aProcessId A reference to the observed process id
+ * @param aMutex A reference to mutex to schedule access to the
+ * shared resources
+ * @param aNotifier A reference to notifier object which is used to
+ * inform killed threads
+ * @param aLogOption Current used log option on allocator.
+ */
+ CLibraryEventHandler( RAnalyzeTool& aAnalyzeTool,
+ RArray<TCodeblock>& aCodeblocks,
+ RATStorageServer& aStorageServer,
+ TUint aProcessId,
+ RMutex& aMutex,
+ MAnalyzeToolEventhandlerNotifier& aNotifier,
+ TUint32 aLogOption );
+
+ /**
+ * Destructor.
+ */
+ ~CLibraryEventHandler();
+
+ /* Start receiving events from the kernel */
+ void Start();
+
+ /**
+ * Returns eventhandler's state.
+ * @return TBool ETrue if eventhandler is started, EFalse otherwise
+ */
+ TBool IsStarted();
+
+ protected: // Functions from base classes
+
+ /**
+ * Process active object's task
+ */
+ void RunL();
+
+ /**
+ * Cancels active object's task
+ */
+ void DoCancel();
+
+ private: // Member variables
+
+ /* Handle to the analyze tool device driver*/
+ RAnalyzeTool& iAnalyzeTool;
+
+ /* A reference to codeblocks of the observed process */
+ RArray<TCodeblock>& iCodeblocks;
+
+ /* Handle to the storage server*/
+ RATStorageServer& iStorageServer;
+
+ /* The observered process id */
+ TUint iProcessId;
+
+ /* The library info */
+ TLibraryEventInfo iLibraryInfo;
+
+ /* The mutex for serializing access to the shared resources */
+ RMutex& iMutex;
+
+ /* Inform if handler is started */
+ TBool iStarted;
+
+ /* A reference to event handler notifier */
+ MAnalyzeToolEventhandlerNotifier& iNotifier;
+
+ /* Current used log option */
+ TUint32 iLogOption;
+ };
+
+#endif // ANALYZETOOLEVENTHANDLER_H
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/inc/analyzetooleventhandlernotifier.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,45 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Declaration of the class MAnalyzeToolEventhandlerNotifier
+*
+*/
+
+
+#ifndef ANALYZETOOLEVENTHANDLERNOTIFIER_H
+#define ANALYZETOOLEVENTHANDLERNOTIFIER_H
+
+// INCLUDES
+#include <e32base.h>
+
+// CLASS DECLARATION
+
+/**
+* MAnalyzeToolEventhandlerNotifier class
+* An interface class for informing killed thread.
+*/
+class MAnalyzeToolEventhandlerNotifier
+ {
+ public: // New functions
+
+ /**
+ * Inform when thread killed.
+ * @param aThreadId - Killed thread Id.
+ */
+ virtual void RemoveKilledThread( const TUint aThreadId ) = 0;
+
+ };
+
+#endif // ANALYZETOOLEVENTHANDLERNOTIFIER_H
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/inc/analyzetoolfastlog.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,96 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef __ANALYZETOOLFASTLOG_H__
+#define __ANALYZETOOLFASTLOG_H__
+
+// INCLUDES
+#include <e32base.h>
+#include <analyzetool/atcommon.h>
+#include <analyzetool/analyzetooltraceconstants.h>
+
+// Function prototypes.
+
+/**
+ * TBD
+ * @param aProcessName The name of the new process started. The length of this
+ * descriptor must not be greater than KMaxProcessName.
+ * @param aProcessId The ID of the process started.
+ * @param aIsDebug Determines whether a binary is UDEB or UREL
+ * @return KErrNone.
+*/
+GLREF_C TInt ATFastLogProcessStarted( const TDesC8& aProcessName,
+ TUint aProcessId,
+ TUint32 aIsDebug );
+
+/**
+ * TBD
+ * @param aProcessId The ID number of the process ended.
+ * @param aHandleLeakCount Number of handles open.
+ * @return KErrNone, if successful; otherwise one of the other
+ * system-wide error codes.
+ */
+GLREF_C TInt ATFastLogProcessEnded( TUint aProcessId,
+ TUint aHandleLeakCount );
+
+/**
+ * TBD
+ * @param aProcessId The ID number of the process ended.
+ * @param aDllName The name of the new DLL loaded. The length of this descriptor
+ * must not be greater than KMaxLibraryName.
+ * @param aStartAddress The start address of the DLL loaded.
+ * @param aEndAddress The end address of the DLL loaded.
+ * @return KErrNone.
+*/
+GLREF_C TInt ATFastLogDllLoaded( TUint aProcessId, const TDesC8& aDllName, TUint32 aStartAddress,
+ TUint32 aEndAddress );
+
+/**
+ * TBD
+ * @param aProcessId The ID number of the process ended.
+ * @param aDllName The name of the DLL to be unloaded. The length of this
+ * descriptor must not be greater than KMaxLibraryName.
+ * @param aStartAddress The start address of the DLL to be unloaded.
+ * @param aEndAddress The end address of the DLL to be unloaded.
+ * @return KErrNone.
+*/
+GLREF_C TInt ATFastLogDllUnloaded( TUint aProcessId, const TDesC8& aDllName, TUint32 aStartAddress,
+ TUint32 aEndAddress );
+
+/**
+ * TBD
+ * @param aProcessId The ID number of the process ended.
+ * @param aMemAddress The memory location where memory has been allocated.
+ * @param aCallstack An array including the current call stack.
+ * @param aSize The size of the newly allocated memory chunk.
+ * @return KErrNone.
+*/
+GLREF_C TInt ATFastLogMemoryAllocated( TUint aProcessId, TUint32 aMemAddress,
+ TFixedArray<TUint32, KATMaxCallstackLength>& aCallstack,
+ TInt aSize );
+
+/**
+ * TBD
+ * @param aProcessId The ID number of the process ended.
+ * @param aMemAddress The memory location where memory has been deallocated.
+ * @param aFreeCallstack An array including the current call stack.
+ * @return KErrNone.
+*/
+GLREF_C TInt ATFastLogMemoryFreed( TUint aProcessId, TUint32 aMemAddress,
+ TFixedArray<TUint32, KATMaxFreeCallstackLength>& aFreeCallstack );
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/inc/analyzetoolmainallocator.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,329 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Declaration of the class RAnalyzeToolMainAllocator.
+*
+*/
+
+
+#ifndef ANALYZETOOLMAINALLOCATOR_H
+#define ANALYZETOOLMAINALLOCATOR_H
+
+// INCLUDES
+#include <u32std.h>
+#include "codeblock.h"
+#include <analyzetool/atstorageserverclnt.h>
+#include <analyzetool/analyzetool.h>
+#include <analyzetool/atcommon.h>
+#include "analyzetoolmemoryallocator.h"
+#include "analyzetooleventhandlernotifier.h"
+
+// FORWARD DECLARATIONS
+class CLibraryEventHandler;
+
+// CLASS DECLARATION
+
+/**
+* Class which overloads the RAlloctor functions and provides access to
+* the overloaded functions
+*/
+class RAnalyzeToolMainAllocator : public RAnalyzeToolMemoryAllocator,
+ public MAnalyzeToolEventhandlerNotifier
+ {
+
+ public:
+
+ /**
+ * C++ default constructor.
+ * @param aNotFirst Is this first thread using this heap
+ * @param aFileName The name of the log file
+ * @param aLogOption The logging option for storage server
+ * @param aIsDebug Determines whether a binary is UDEB or UREL
+ * @param aAllocCallStackSize Max number of stored callstack items when memory allocated
+ * @param aFreeCallStackSize Max number of stored callstack items when memory freed
+ */
+ RAnalyzeToolMainAllocator( TBool aNotFirst,
+ const TFileName aFileName,
+ TUint32 aLogOption, TUint32 aIsDebug,
+ TUint32 aAllocCallStackSize,
+ TUint32 aFreeCallStackSize );
+
+ /**
+ * Destructor.
+ */
+ ~RAnalyzeToolMainAllocator();
+
+ /**
+ * Allocates a cell of specified size from the heap.
+ * @param aSize The size of the cell to be allocated from the heap.
+ * @return TAny* A pointer to the allocated cell.
+ */
+ TAny* Alloc( TInt aSize );
+
+ /**
+ * Frees the specified cell and returns it to the heap.
+ * @param aPtr A pointer to a cell to be freed.
+ */
+ void Free( TAny* aPtr );
+
+ /**
+ * Increases or decreases the size of an existing cell.
+ * @param aPtr A pointer to the cell to be reallocated.
+ * @param aSize The new size of the cell. This may be bigger
+ * or smaller than the size of the original cell.
+ * @param aMode Flags controlling the reallocation.
+ * @return TAny* A pointer to the reallocated cell. This may be the
+ * same as the original pointer supplied through aCell.
+ */
+ TAny* ReAlloc( TAny* aPtr, TInt aSize, TInt aMode = 0 );
+
+ /**
+ * Gets the length of the available space in the specified
+ * allocated cell.
+ * @param aCell A pointer to the allocated cell.
+ * @return TInt The length of the available space in the allocated cell.
+ */
+ TInt AllocLen(const TAny* aCell) const;
+
+ #ifndef __KERNEL_MODE__
+
+ /**
+ * Opens this heap for shared access. Opening the heap increases
+ * the heap's access count by one.
+ */
+ TInt Open();
+
+ /**
+ * Closes this shared heap. Closing the heap decreases the heap's
+ * access count by one.
+ */
+ void Close();
+
+ /**
+ * The function frees excess committed space from the top of the heap.
+ * The size of the heap is never reduced below the minimum size
+ * specified during creation of the heap.
+ * @return TInt The space reclaimed. If no space can be reclaimed,
+ then this value is zero.
+ */
+ TInt Compress();
+
+ /**
+ * Frees all allocated cells on this heap.
+ */
+ void Reset();
+
+ /**
+ * Gets the number of cells allocated on this heap, and
+ * the total space allocated to them.
+ * @param aTotalAllocSize On return, contains the total
+ * space allocated to the cells.
+ * @return TInt The number of cells allocated on this heap.
+ */
+ TInt AllocSize( TInt& aTotalAllocSize ) const;
+
+ /**
+ * Gets the total free space currently available on the heap and the
+ * space available in the largest free block. The space available
+ * represents the total space which can be allocated. Note that
+ * compressing the heap may reduce the total free space available
+ * and the space available in the largest free block.
+ * @param aBiggestBlock On return, contains the space available
+ * in the largest free block on the heap.
+
+ * @return TInt The total free space currently available on the heap.
+
+ */
+ TInt Available( TInt& aBiggestBlock ) const;
+
+ #endif
+
+ /**
+ * Invocates specified debug funtionality.
+ * @param aFunc The debug function
+ * @param a1 Debug function specific paramenter.
+ * @param a2 Debug function specific paramenter.
+ * @return TInt Returns KErrNone, if successful otherwise one
+ * of the other system-wide error codes.
+ */
+ TInt DebugFunction( TInt aFunc, TAny* a1 = NULL, TAny* a2 = NULL );
+
+ // From MAnalyzeToolEventhandlerNotifier
+
+ /**
+ * Remove killed thread from threads array.
+ * @param aThreadId - Thread Id
+ */
+ void RemoveKilledThread( const TUint aThreadId );
+
+ protected:
+
+ /**
+ * Extension function
+ * @param aExtensionId The extension id
+ * @param a0 Extension specific paramenter.
+ * @param a1 Extension specific paramenter.
+ * @return TInt Returns KErrNone, if successful otherwise one
+ * of the other system-wide error codes.
+ */
+ TInt Extension_( TUint aExtensionId, TAny*& a0, TAny* a1 );
+
+ public: // from RAnalyzeToolMemoryAllocator
+
+ /**
+ * Installs the RTraceAllocator allocator
+ */
+ void Uninstall();
+
+ /**
+ * Shares the heap
+ */
+ void ShareHeap();
+
+ public: // inlines
+
+ /**
+ * Acquires the open RATStorageServer handle
+ * @return RATStorageServer& The open RATStorageServer handle
+ */
+ inline RATStorageServer& StorageServer();
+
+ /**
+ * Acquires the codeblocks of the process
+ * @return RArray<TCodeblock>& The process codeblocks
+ */
+ inline RArray<TCodeblock>& Codeblocks();
+
+ /**
+ * Acquires the mutex used to access shared objects
+ * @return RMutex& A reference to open mutex
+ */
+ inline RMutex& Mutex();
+
+ /**
+ * Acquires the current process id
+ * @return TInt The process id
+ */
+ inline TInt ProcessId();
+
+ /**
+ * Acquires the logical channel handle
+ * @return RAnalyzeTool A reference to logical channel
+ */
+ inline RAnalyzeTool& AnalyzeTool();
+
+ /**
+ * Acquires information if storage server is open
+ * @return TBool iStorageServerOpen
+ */
+ inline TBool StorageServerOpen();
+
+ /**
+ * Acquires the log option type
+ * @return TUint32 iLogOption
+ */
+ inline TUint32 LogOption();
+
+ /**
+ * Acquires the max size of call stack when memory allocated
+ * @return TUint32 iAllocMaxCallStack
+ */
+ inline TUint32 AllocMaxCallStack();
+
+ /**
+ * Acquires the max size of call stack when memory freed
+ * @return TUint32 iFreeMaxCallStack
+ */
+ inline TUint32 FreeMaxCallStack();
+
+ private: // private functions
+
+ /**
+ * Log the process initial information
+ * @param aFileName The name of the log file
+ * @param aLogOption The logging option for storage serve
+ * @param aIsDebug Determines whether a binary is UDEB or UREL
+ */
+ void LogProcessInformation( const TFileName aFileName, TUint32 aLogOption,
+ TUint32 aIsDebug );
+
+ /**
+ * Find the current thread which is using the heap
+ * @param aStackStart A reference where the stack start is stored
+ * @return TBool ETrue if a thread can be found, EFalse otherwise
+ */
+ TBool FindCurrentThreadStack( TUint32& aStackStart );
+
+ /**
+ * Installs the eventhandler, if possible
+ */
+ void InstallEventHandler();
+
+ private: // member variables
+
+ /* Handle to the RATStorageServer */
+ RATStorageServer iStorageServer;
+
+ /* Handle to the RAnalyzeTool */
+ RAnalyzeTool iAnalyzeTool;
+
+ /* A flag for indicating that the RAnalyzeTool is open */
+ TBool iAnalyzeToolOpen;
+
+ /* A flag for indicating that the device driver is loaded */
+ TBool iDeviceDriverLoaded;
+
+ /* The codeblocks of the process */
+ RArray<TCodeblock> iCodeblocks;
+
+ /* The handler for kerner events */
+ CLibraryEventHandler* iEventHandler;
+
+ /* The mutex for serializing access to the shared resources */
+ mutable RMutex iMutex;
+
+ /* Array for storing the callstack */
+ TFixedArray <TUint32, KATMaxCallstackLength> iCallStack;
+
+ /* Array for storing the reallocation callstack */
+ TFixedArray <TUint32, KATMaxCallstackLength> iReCallStack;
+
+ /* Array for storing the reallocation callstack */
+ TFixedArray<TUint32, KATMaxFreeCallstackLength> iFreeCallStack;
+
+ /* Array of threads using this heap */
+ RArray<TThreadStack> iThreadArray;
+
+ /* A flag for indicating that the RATStorageServer is open */
+ TBool iStorageServerOpen;
+
+ /* Log option */
+ TUint32 iLogOption;
+
+ /* The process id */
+ TUint iProcessId;
+
+ /* Max items on stored call stack when memory allocated */
+ TUint32 iAllocMaxCallStack;
+
+ /* Max items on stored call stack when memory freed */
+ TUint32 iFreeMaxCallStack;
+
+ };
+
+// INLINES
+#include "analyzetoolmainallocator.inl"
+
+#endif // ANALYZETOOLMAINALLOCATOR_H
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/inc/analyzetoolmainallocator.inl Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,109 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Definition for the inline functions of RAnalyzeToolMainAllocator.
+*
+*/
+
+
+#include "analyzetoolmemoryallocator.h"
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::StorageServer()
+// Acquires reference to open RATStorageServer
+// -----------------------------------------------------------------------------
+//
+inline RATStorageServer& RAnalyzeToolMainAllocator::StorageServer()
+ {
+ return iStorageServer;
+ }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::Codeblocks()
+// Acquires reference to process used codeblocks
+// -----------------------------------------------------------------------------
+//
+inline RArray<TCodeblock>& RAnalyzeToolMainAllocator::Codeblocks()
+ {
+ return iCodeblocks;
+ }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::Mutex()
+// Acquires reference to mutex which is used to share resources
+// -----------------------------------------------------------------------------
+//
+inline RMutex& RAnalyzeToolMainAllocator::Mutex()
+ {
+ return iMutex;
+ }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::ProcessId()
+// Acquires the process id
+// -----------------------------------------------------------------------------
+//
+inline TInt RAnalyzeToolMainAllocator::ProcessId()
+ {
+ return iProcessId;
+ }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::AnalyzeTool()
+// Acquires the logical channel handle
+// -----------------------------------------------------------------------------
+//
+inline RAnalyzeTool& RAnalyzeToolMainAllocator::AnalyzeTool()
+ {
+ return iAnalyzeTool;
+ }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::StorageServerOpen()
+// Acquires the iStorageServerOpen variable
+// -----------------------------------------------------------------------------
+//
+inline TBool RAnalyzeToolMainAllocator::StorageServerOpen()
+ {
+ return iStorageServerOpen;
+ }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::LogOption()
+// Acquires the iLogOption variable
+// -----------------------------------------------------------------------------
+//
+inline TUint32 RAnalyzeToolMainAllocator::LogOption()
+ {
+ return iLogOption;
+ }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::AllocMaxCallStack()
+// Acquires the iAllocMaxCallStack variable
+// -----------------------------------------------------------------------------
+//
+inline TUint32 RAnalyzeToolMainAllocator::AllocMaxCallStack()
+ {
+ return iAllocMaxCallStack;
+ }
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::FreeMaxCallStack()
+// Acquires the iFreeMaxCallStack variable
+// -----------------------------------------------------------------------------
+//
+inline TUint32 RAnalyzeToolMainAllocator::FreeMaxCallStack()
+ {
+ return iFreeMaxCallStack;
+ }
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/inc/analyzetoolmemoryallocator.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,94 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Declaration of the class RAnalyzeToolMemoryAllocator.
+*
+*/
+
+
+#ifndef ANALYZETOOLMEMORYALLOCATOR_H
+#define ANALYZETOOLMEMORYALLOCATOR_H
+
+// INCLUDES
+#include <u32std.h>
+#include "threadstack.h"
+#include "../../symbian_version.hrh"
+
+// CONSTANTS
+#if ( SYMBIAN_VERSION_SUPPORT >= SYMBIAN_3 )
+ #ifndef __WINS__
+ const TInt KDummyHandle = -1000;
+ #endif
+#endif
+
+// CLASS DECLARATION
+
+/**
+* Abstract class for basic RAnalyzeToolMemoryAllocator funtions
+*/
+class RAnalyzeToolMemoryAllocator : public RAllocator
+ {
+ public:
+
+ /**
+ * C++ default constructor.
+ * @param aNotFirst Is this first thread using this heap
+ */
+ RAnalyzeToolMemoryAllocator( TBool aNotFirst );
+
+ /**
+ * Destructor.
+ */
+ //lint -e{1510} suppress "base class 'RAllocator' has no destructor"
+ virtual ~RAnalyzeToolMemoryAllocator();
+
+ /**
+ * Uninstall the RAnalyzeToolMemoryAllocator
+ */
+ virtual void Uninstall() = 0;
+
+ /**
+ * Shares the heap for another thread
+ */
+ virtual void ShareHeap() = 0;
+
+ protected:
+
+ /**
+ * Switch original allocator in use.
+ * Switches original allocator in use if not already.
+ */
+ void SwitchOriginalAllocator();
+
+ /**
+ * Checks is the given address in loaded code memory area.
+ */
+ inline bool IsAddressLoadedCode( TUint32& aAddress );
+
+ /* The original thread RAllocator */
+ RAllocator* iAllocator;
+
+ /* Is this the first thread using this heap */
+ TBool iNotFirst;
+
+ /* Memorymodel */
+ TUint32 iMemoryModel;
+
+ };
+
+// INLINES
+#include "analyzetoolmemoryallocator.inl"
+
+#endif // ANALYZETOOLMEMORYALLOCATOR_H
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/inc/analyzetoolmemoryallocator.inl Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,54 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Definition for the inline functions of RAnalyzeToolMemoryAllocator.
+*
+*/
+
+
+
+#include <analyzetool/atcommon.h>
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMemoryAllocator::IsAddressLoadedCode()
+// Checks is the given address in loaded code memory area.
+// -----------------------------------------------------------------------------
+//
+inline bool RAnalyzeToolMemoryAllocator::IsAddressLoadedCode( TUint32& aAddress )
+ {
+ // Debug log strings in this function are not used because
+ // this is called so many times.
+ /*
+ * TMemModelAttributes models.
+ * EMemModelTypeDirect // direct memory model on hardware
+ * EMemModelTypeMoving=1 // moving memory model on hardware
+ * EMemModelTypeMultiple=2 // multiple memory model on hardware
+ * EMemModelTypeEmul=3 // emulation using single host process
+ * Flexible ?
+ */
+ switch( iMemoryModel )
+ {
+ case EMemModelTypeMultiple:
+ // Use low & high limits which define rofs loading->rom area
+ // in multiple memory model.
+ if ( aAddress < KATMultipleMemoryModelLowLimit
+ || aAddress > KATMultipleMemoryModelHighLimit )
+ return false;
+ return true;
+ default:
+ return true;
+ }
+ }
+
+// End of File
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/inc/analyzetoolpanics.pan Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Panic codes and definition of a panic function for the Memory Hook
+*
+*/
+
+
+#ifndef ANALYZETOOLPANICS_PAN_H
+#define ANALYZETOOLPANICS_PAN_H
+
+_LIT( KAnalyzeToolName, "AnalyzeTool" );
+
+/** AnalyzeTool application panic codes */
+enum TAnalyzeToolPanics
+ {
+ ENoMemory = 1,
+ EFailedToCreateHeap,
+ ECantOpenHandle,
+ ECantLoadDevice,
+ ECantAppendToTheArray,
+ ECantFindRightThread,
+ ECantConnectStorageServer,
+ ECantShareStorageServer,
+ ECantCreateMutex,
+ ECantLoadDeviceDriver,
+ ECantConnectDeviceDriver
+ // add further panics here
+ };
+
+inline void AssertPanic(TAnalyzeToolPanics aReason)
+ {
+ User::Panic( KAnalyzeToolName, aReason );
+ }
+
+#endif // ANALYZETOOLPANICS_PAN_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/inc/codeblock.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,74 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Declaration of the class TCodeblock.
+*
+*/
+
+
+#ifndef CODEBLOCK_H
+#define CODEBLOCK_H
+
+// INCLUDES
+#include <u32std.h>
+
+/**
+* Stores information of process loaded code segments
+*/
+class TCodeblock
+ {
+
+ public: // Constructors
+
+ /**
+ * C++ default constructor.
+ * @param aRunAddress Start address of the memory block.
+ * @param aSize The size of the memory block.
+ * @param aName The name of the library
+ */
+ TCodeblock( TLinAddr aRunAddress, TUint32 aSize, TBuf8<KMaxLibraryName>& aName );
+
+ public: // New functions
+
+ /**
+ * Checks if the given address is in this memory block area
+ * @param aAddress A address to be checked.
+ * @return TBool Returns ETrue if the given address is in this
+ * memory block area, EFalse otherwise
+ */
+ TBool CheckAddress( TUint32 aAddress );
+
+ /**
+ * Matches if the given parameters represents this memory block
+ * @param aName The name of the library
+ * @return TBool Returns ETrue if the given parameters represents
+ * this memory block, EFalse otherwise
+ */
+ TBool Match( TBuf8<KMaxLibraryName>& aName );
+
+ private: // Member variables
+
+ /* Start address of the memory block */
+ TLinAddr iStartAddress;
+
+ /* End address of the memory block */
+ TLinAddr iEndAddress;
+
+ /* End address of the memory block */
+ TBuf8<KMaxLibraryName> iName;
+ };
+
+#endif // CODEBLOCK_H
+
+// End of File
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/inc/customuser.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,207 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Declaration of the class CustomUser containing overloaded User static functions.
+*
+*/
+
+
+#ifndef CUSTOMUSER_H
+#define CUSTOMUSER_H
+
+// INCLUDES
+#include <u32std.h>
+
+// CONSTANTS
+const TInt KATVersionLength = 20;
+const TInt KATDefaultLogOption = 0;
+const TInt KATDefaultDebug = 1;
+const TInt KATDefaultAllocCallStackSize = 40;
+const TInt KATDefaultFreeCallStackSize = 0;
+
+// TYPEDEFS
+typedef TBuf<KATVersionLength> TATVersion;
+
+// Argument list for SetupThreadHeap function parameters. (currently not used)
+// When needed, update the argument type directly inside _LIT macro.
+_LIT( KATArgumentList, "%i%i" ); //etc.
+
+// CLASS DECLARATION
+
+/**
+* Class which overloads the User functions and provides access to
+* the overloaded functions
+*/
+class CustomUser
+ {
+ public: // Enumerations
+ enum TATOptions
+ {
+ /** Acquiring the log filename */
+ ELogFileName = 1,
+ /** Acquiring the version number */
+ EVersion,
+ /** Acquiring logging option */
+ ELogOption,
+ /** Acquiring UDEB/UREL information */
+ EDebug,
+ /** Acquiring max allocation call stack size */
+ EAllocCallStackSize,
+ /** Acquiring max free call stack size */
+ EFreeCallStackSize
+ };
+
+ public:
+
+ /**
+ * Overloaded version of User::Exit()
+ * Terminates the current thread, specifying a reason. All child
+ * threads are terminated and all resources are cleaned up.If the
+ * current thread is the main thread in a process, the process is
+ * also terminated.
+ * @param aReason The reason code.
+ */
+ IMPORT_C static void Exit( TInt aReason );
+
+ /**
+ * Overloaded version of User::Panic()
+ * Panics the current thread, specifying a category name and panic
+ * number. Keep the length of the category name small;
+ * a length of 16 is ideal.
+ * @param aCategory A reference to the descriptor containing the text
+ * that defines the category for this panic.
+ * @param aReason The panic number.
+ */
+ IMPORT_C static void Panic( const TDesC& aCategory, TInt aReason );
+
+ /**
+ * Overloaded version of UserHeap::SetupThreadHeap()
+ * Setups the threads heap.
+ * @param aNotFirst Is this first thread using specified heap
+ * @param aInfo Specifies the thread heap properties
+ * @param aFileName The name of the log file
+ * @param aLogOption The logging option for storage server
+ * @param aIsDebug Determines whether a binary is UDEB or UREL
+ * @param aVersion Atool version number
+ * @param aAllocCallStackSize Max number of stored callstack items when memory allocated
+ * @param aFreeCallStackSize Max number of stored callstack items when memory freed
+ * @param aFmt A descriptor containing the format string
+ * @return TInt KErrNone, if the insertion is successful, otherwise
+ * one of the system wide error codes.
+ */
+ IMPORT_C static TInt SetupThreadHeap(
+ TBool aNotFirst,
+ SStdEpocThreadCreateInfo& aInfo,
+ const TFileName& aFileName,
+ TUint32 aLogOption, TUint32 aIsDebug,
+ const TATVersion& aVersion,
+ TUint32 aAllocCallStackSize,
+ TUint32 aFreeCallStackSize,
+ TRefByValue<const TDesC> aFmt, ... );
+
+ /**
+ * Overloaded version of UserHeap::SetCritical()
+ * Sets up or changes the effect that termination of the current
+ * thread has, either on its owning process, or on the whole system.
+ * The precise effect of thread termination is defined by the following
+ * specific values of the TCritical enum:
+ * ENotCritical
+ * EProcessCritical
+ * EProcessPermanent
+ * ESystemCritical
+ * ESystemPermanent
+ * Notes: The enum value EAllThreadsCritical cannot be set using this
+ * function. It is associated with a process, not a thread, and, if
+ * appropriate, should be set using User::SetProcessCritical().
+ * The states associated with ENotCritical, EProcessCritical,
+ * EProcessPermanent, ESystemCritical and ESystemPermanent are all
+ * mutually exclusive, i.e. the thread can only be in one of these
+ * states at any one time.
+ * @param aCritical The state to be set.
+ * @return TInt KErrNone, if successful; KErrArgument, if
+ * EAllThreadsCritical is passed - this is a state associated with a
+ * process, and you use User::SetProcessCritical() to set it.
+ */
+ IMPORT_C static TInt SetCritical( User::TCritical aCritical );
+
+ /**
+ * Overloaded version of UserHeap::SetCritical()
+ * Sets up or changes the effect that termination of subsequently
+ * created threads will have, either on the owning process,
+ * or on the whole system. It is important to note that we are not
+ * referring to threads that have already been created, but threads
+ * that will be created subsequent to a call to this function.
+ * The precise effect of thread termination is defined by the following
+ * specific values of the TCritical enum:
+ * ENotCritical
+ * EAllThreadsCritical
+ * ESystemCritical
+ * ESystemPermanent
+ * Notes:
+ * The enum values EProcessCritical and EProcessPermanent cannot be set
+ * using this function. They are states associated with a thread, not a
+ * process, and, if appropriate, should be set using
+ * User::SetCritical(). The states associated with ENotCritical,
+ * EAllThreadsCritical, ESystemCritical and ESystemPermanent are all
+ * mutually exclusive, i.e. the process can only be in one of these
+ * states at any one time.
+ * @param aCritical The state to be set.
+ * @return TInt KErrNone, if successful; KErrArgument, if either
+ * EProcessCritical or EProcessPermanent is passed - these are states
+ * associated with a thread, and you use User::SetCritical()
+ * to set them.
+ */
+ IMPORT_C static TInt SetProcessCritical( User::TCritical aCritical );
+
+ private: // Private functions
+
+ /**
+ * Factory function for creating RAllocator instances.
+ * @param aNotFirst Is this first thread using specified heap
+ * @param aLogOption The logging option for storage server
+ * @param aFileName The name of the logging file
+ * @param aIsDebug Determines whether a binary is UDEB or UREL
+ * @param aAllocCallStackSize Max number of stored callstack items when memory allocated
+ * @param aFreecallStackSize Max number of stored callstack items when memory freed
+ * @return RAllocator& A reference to created allocator
+ */
+ static RAllocator& InstallAllocator( TBool aNotFirst,
+ const TFileName& aFileName,
+ TUint32 aLogOption, TUint32 aIsDebug,
+ TUint32 aAllocCallStackSize,
+ TUint32 aFreeCallStackSize );
+
+ /**
+ * Check atool version
+ * @param aVersion - Atool version number.
+ * @param aToolVersion The atool version number
+ * @return KErrNone if correct version found, otherwise one of the system wide
+ * error codes.
+ */
+ static TInt CheckVersion( const TATVersion& aVersion, TDes& aToolVersion );
+
+ /**
+ * Function for showing incorrect version information (file or debug channel).
+ * @param aLogOption The logging option
+ * @param aFileName The name of the log file
+ * @param aToolVersion The atool version number
+ */
+ static void ReportIncorrectVersion( const TUint32 aLogOption,
+ const TFileName& aFileName,
+ const TDes& aToolVersion );
+
+ };
+
+#endif // CUSTOMUSER_H
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/inc/threadstack.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,70 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Declaration of the class TThreadStack.
+*
+*/
+
+
+#ifndef THREADSTACK_H
+#define THREADSTACK_H
+
+// INCLUDES
+#include <u32std.h>
+
+// CLASS DECLARATION
+
+/**
+* Stores thread id and the start of the thread's callstack
+*/
+class TThreadStack
+ {
+ public:
+
+ /**
+ * C++ default constructor.
+ * @param aId The thread id
+ * @param aStackStart The start of thread's stack
+ */
+ TThreadStack( TThreadId aId, TUint32 aStackStart );
+
+ /**
+ * Checks if this is the current thread and if this is the current
+ * thread assings value to the given parameter
+ * @param aStackStart& A reference to stack start
+ * @return TBool The start of thread's stack
+ */
+ TBool ThreadStackStart( TUint32& aStackStart );
+
+ /**
+ * Checks if this the the current thread
+ * @param aThreadId A thread id
+ * @return TBool ETrue it this is the current thread, EFalse otherwise
+ */
+ TBool Match( const TUint aThreadId = 0 );
+
+ private: // Member variables
+
+ /* The id of the thread */
+ TThreadId iId;
+
+ /* The start addess of this thread */
+ TUint32 iStackStart;
+ };
+
+
+#endif // THREADSTACK_H
+
+// End of File
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/sis/analyzetoolmemoryhook.pkg Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,34 @@
+;
+; Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+; All rights reserved.
+; This component and the accompanying materials are made available
+; under the terms of "Eclipse Public License v1.0"
+; which accompanies this distribution, and is available
+; at the URL "http://www.eclipse.org/legal/epl-v10.html".
+;
+; Initial Contributors:
+; Nokia Corporation - initial contribution.
+;
+; Contributors:
+;
+; Description:
+;
+
+;Language - standard language definitions
+&EN
+
+; standard SIS file header
+#{"AnalyzeToolMemoryHook"},(0xEDF5A8B1),1,8,1
+
+;Localised Vendor name
+%{"Vendor-EN"}
+
+;Unique Vendor name
+:"Vendor"
+
+;Supports Series 60 v 3.0
+[0x101F7961], 0, 0, 0, {"Series60ProductID"}
+
+; 1 File to install
+"\epoc32\release\armv5\urel\atoolmemoryhook.dll"-"!:\sys\bin\atoolmemoryhook.dll"
+"\epoc32\release\armv5\urel\atoolcleaner.dll" -"!:\sys\bin\atoolcleaner.dll"
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/src/analyzetoolallocator.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,1014 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Definitions for the class RAnalyzeToolAllocator.
+*
+*/
+
+
+#include "analyzetoolallocator.h"
+#include "analyzetoolmemoryallocator.h"
+#include "atlog.h"
+#include "analyzetoolpanics.pan"
+#include "analyzetoolfastlog.h"
+#include <e32svr.h>
+
+// CONSTANTS
+
+// Length of the callstack address
+const TUint32 KAddressLength = 4;
+
+// Thread count
+const TInt KThreadCount = 1;
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::RAnalyzeToolAllocator()
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+RAnalyzeToolAllocator::RAnalyzeToolAllocator( TBool aNotFirst,
+ RATStorageServer& aStorageServer,
+ RArray<TCodeblock>& aCodeblocks,
+ RMutex& aMutex,
+ TUint aProcessId,
+ RAnalyzeTool& aAnalyzeTool,
+ TBool aStorageServerOpen,
+ TUint32 aLogOption,
+ TUint32 aAllocCallStackSize,
+ TUint32 aFreeCallStackSize ) :
+ RAnalyzeToolMemoryAllocator( aNotFirst ),
+ iStorageServer( aStorageServer ),
+ iCodeblocks( aCodeblocks ),
+ iMutex( aMutex ),
+ iProcessId( aProcessId ),
+ iThreadArray( KATMaxCallstackLength ),
+ iAnalyzeTool( aAnalyzeTool ),
+ iStorageServerOpen( aStorageServerOpen ),
+ iLogOption( aLogOption ),
+ iAllocMaxCallStack( aAllocCallStackSize ),
+ iFreeMaxCallStack( aFreeCallStackSize )
+ {
+ LOGSTR1( "ATMH RAnalyzeToolAllocator::RAnalyzeToolAllocator()" );
+
+ // Append thread to array of the users of this allocator
+ TThreadParamsBuf params;
+ params().iThreadId = RThread().Id().operator TUint();
+ TInt error = iAnalyzeTool.ThreadStack( params );
+ if ( KErrNone == error )
+ {
+ LOGSTR2( "ATMH Thread stack address: %x", params().iStackAddress );
+ LOGSTR2( "ATMH Thread stack size: %x", params().iStackSize );
+ error = iThreadArray.Append( TThreadStack( RThread().Id(),
+ params().iStackAddress + params().iStackSize ) );
+ }
+
+ __ASSERT_ALWAYS( KErrNone == error, AssertPanic( ECantAppendToTheArray ) );
+ }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::~RAnalyzeToolAllocator()
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+RAnalyzeToolAllocator::~RAnalyzeToolAllocator()
+ {
+ LOGSTR1( "ATMH RAnalyzeToolAllocator::~RAnalyzeToolAllocator()" );
+
+ // Close the thread array
+ iThreadArray.Close();
+ }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::Uninstall()
+// Uninstalls the current allocator
+// -----------------------------------------------------------------------------
+//
+void RAnalyzeToolAllocator::Uninstall()
+ {
+ LOGSTR1( "ATMH RAnalyzeToolAllocator::Uninstall()" );
+
+ // Switch back to the original allocator
+ SwitchOriginalAllocator();
+
+ // Check if this is shared allocator between threads
+ if ( iThreadArray.Count() > KThreadCount )
+ {
+ // Close the shared allocator
+ Close();
+ return;
+ }
+
+#if ( SYMBIAN_VERSION_SUPPORT >= SYMBIAN_3 )
+ #ifndef __WINS__
+ // Remove dummy Tls handle
+ UserSvr::DllFreeTls( KDummyHandle );
+ #endif
+#endif
+
+ // Since this is the last thread using this allocator it can be deleted
+ delete this;
+ }
+
+#ifdef __WINS__
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::Alloc() WINS version
+// Allocates a cell of specified size from the heap.
+// -----------------------------------------------------------------------------
+//
+UEXPORT_C TAny* RAnalyzeToolAllocator::Alloc( TInt aSize )
+ {
+ LOGSTR1( "ATMH RAnalyzeToolAllocator::Alloc()" );
+
+ // Acquire the mutex
+ iMutex.Wait();
+
+ // Alloc memory from the original allocator
+ TAny* p = iAllocator->Alloc( aSize );
+
+ LOGSTR3( "ATMH RAnalyzeToolAllocator::Alloc() - aSize: %i, address: %x",
+ aSize, (TUint32) p );
+
+ // Don't collect call stack and log data
+ // if storage server not open or logging mode not fast.
+ if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
+ {
+ // Reset the callstack
+ iCallStack.Reset();
+
+ // Find the current thread callstack start address
+ TUint32 stackstart( 0 );
+ TBool found( FindCurrentThreadStack( stackstart ) );
+ LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found );
+
+ TUint32 _sp;
+ __asm
+ {
+ mov [_sp], esp
+ }
+
+ // Get codeblocks count
+ TInt blocksCount( iCodeblocks.Count() );
+ TInt error( KErrNone );
+ TUint arrayCounter = 0;
+
+ for ( TUint32 i = _sp; i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
+ {
+ TUint32 addr = (TUint32) *( (TUint32*) i );
+ if ( ! IsAddressLoadedCode( addr ) )
+ continue;
+ for ( TInt j = 0; j < blocksCount; j++ )
+ {
+ if ( iCodeblocks[j].CheckAddress( addr ) )
+ {
+ // To avoid recursive call to ReAlloc specifying granularity
+ // Add address to the callstack
+ iCallStack[arrayCounter] = ( addr );
+ arrayCounter++;
+ break;
+ }
+ }
+ if ( arrayCounter == KATMaxCallstackLength ||
+ arrayCounter == iAllocMaxCallStack )
+ {
+ LOGSTR2( "ATMH > Wanted CallStack items ready( %i )", arrayCounter );
+ break;
+ }
+ }
+ // Log the memory allocation information
+ if ( iLogOption == EATLogToTraceFast )
+ {
+ // Using fast mode.
+ ATFastLogMemoryAllocated( iProcessId, (TUint32) p, iCallStack, aSize );
+ }
+ else
+ {
+ // Using storage server.
+ error = iStorageServer.LogMemoryAllocated( (TUint32) p,
+ iCallStack,
+ aSize );
+ if ( KErrNone != error )
+ {
+ LOGSTR2( "ATMH LogMemoryAllocated error %i", error );
+ switch ( error )
+ {
+ case KErrNoMemory:
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Alloc() - KErrNoMemory case" );
+ if ( iStorageServerOpen )
+ {
+ iStorageServerOpen = EFalse;
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Alloc() - close iStorageServer" );
+ iStorageServer.Close();
+ }
+ break;
+ }
+ }
+ }
+ }
+ // Release the mutex
+ iMutex.Signal();
+
+ return p;
+ }
+#else
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::Alloc() ARMV5 version
+// Allocates a cell of specified size from the heap.
+// -----------------------------------------------------------------------------
+//
+TAny* RAnalyzeToolAllocator::Alloc( TInt aSize )
+ {
+ LOGSTR1( "ATMH RAnalyzeToolAllocator::Alloc()" );
+
+ // Acquire the mutex
+ iMutex.Wait();
+
+ // Alloc memory from the original allocator
+ TAny* p = iAllocator->Alloc( aSize );
+
+ // Don't collect call stack and log data
+ // if storage server not open or logging mode not fast.
+ if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
+ {
+ // Reset the callstack
+ iCallStack.Reset();
+
+ // Find the current thread callstack start address
+ TUint32 stackstart( 0 );
+ TBool found( FindCurrentThreadStack( stackstart ) );
+ LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found );
+
+ // Get codeblocks count
+ TInt blocksCount( iCodeblocks.Count() );
+ TInt error( KErrNone );
+ TUint arrayCounter = 0;
+
+ for ( TUint32 i = __current_sp(); i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
+ {
+ TUint32 addr = (TUint32) *( (TUint32*) i );
+ if ( ! IsAddressLoadedCode( addr ) )
+ continue;
+ for ( TInt j = 0; j < blocksCount; j++ )
+ {
+ if ( iCodeblocks[j].CheckAddress( addr ) )
+ {
+ // To avoid recursive call to ReAlloc specifying granularity
+ // Add address to the callstack
+ iCallStack[arrayCounter] = ( addr );
+ arrayCounter++;
+ break;
+ }
+ }
+ if ( arrayCounter == KATMaxCallstackLength ||
+ arrayCounter == iAllocMaxCallStack )
+ {
+ LOGSTR2( "ATMH > Wanted CallStack items ready( %i )", arrayCounter );
+ break;
+ }
+ }
+ // Log the memory allocation information
+ if ( iLogOption == EATLogToTraceFast )
+ {
+ // Fast mode.
+ ATFastLogMemoryAllocated( iProcessId, (TUint32) p, iCallStack, aSize );
+ }
+ else
+ {
+ // Using storage server.
+ error = iStorageServer.LogMemoryAllocated( (TUint32) p,
+ iCallStack,
+ aSize );
+ if ( KErrNone != error )
+ {
+ LOGSTR2( "ATMH LogMemoryAllocated error %i", error );
+ switch ( error )
+ {
+ case KErrNoMemory:
+ LOGSTR1( "ATMH RAnalyzeToolAllocator::Alloc() - KErrNoMemory case" );
+ if ( iStorageServerOpen )
+ {
+ iStorageServerOpen = EFalse;
+ LOGSTR1( "ATMH RAnalyzeToolAllocator::Alloc() - close iStorageServer" );
+ iStorageServer.Close();
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ // Release the mutex
+ iMutex.Signal();
+
+ // Return the allocatated memory
+ return p;
+ }
+#endif // __WINS__
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::Free()
+// Frees the allocated memory
+// -----------------------------------------------------------------------------
+//
+TAny RAnalyzeToolAllocator::Free( TAny* aPtr )
+ {
+ LOGSTR1( "ATMH RAnalyzeToolAllocator::Free()" );
+
+ // Acquire the mutex
+ iMutex.Wait();
+
+ // Don't collect or log data if storage server not open or logging mode not fast.
+ if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
+ {
+ // Reset the callstack
+ iFreeCallStack.Reset();
+
+ // Check if trace logging mode because free call stack is not used in other log options.
+ if ( (iLogOption == EATUseDefault || iLogOption == EATLogToTrace || iLogOption == EATLogToTraceFast )
+ && iFreeMaxCallStack > 0 )
+ {
+ // Find the current thread callstack start address
+ TUint32 stackstart( 0 );
+ TBool found( FindCurrentThreadStack( stackstart ) );
+ LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found );
+ TUint32 _sp;
+
+ #ifdef __WINS__
+ __asm
+ {
+ mov [_sp], esp
+ }
+ #else
+ _sp = __current_sp();
+ #endif
+
+ // Get codeblocks count
+ TInt blocksCount( iCodeblocks.Count() );
+ TUint arrayCounter = 0;
+
+ for ( TUint32 i = _sp; i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
+ {
+ TUint32 addr = (TUint32) *( (TUint32*) i );
+ if ( ! IsAddressLoadedCode( addr ) )
+ continue;
+ for ( TInt j = 0; j < blocksCount; j++ )
+ {
+ if ( iCodeblocks[j].CheckAddress( addr ) )
+ {
+ // To avoid recursive call to ReAlloc specifying granularity
+ // Add address to the callstack
+ iFreeCallStack[arrayCounter] = addr;
+ arrayCounter++;
+ break;
+ }
+ }
+ if ( arrayCounter == KATMaxFreeCallstackLength ||
+ arrayCounter == iFreeMaxCallStack )
+ {
+ break;
+ }
+ }
+ LOGSTR2( "ATMH > iFreeCallStack count ( %i )", arrayCounter );
+ }
+
+ // Log freed memory.
+ if ( iLogOption == EATLogToTraceFast )
+ {
+ // Using fast mode.
+ ATFastLogMemoryFreed( iProcessId, (TUint32) aPtr, iFreeCallStack );
+ }
+ else
+ {
+ // Using storage server.
+ TInt err( iStorageServer.LogMemoryFreed( (TUint32) aPtr, iFreeCallStack ) );
+ if ( err != KErrNone )
+ {
+ LOGSTR2( "ATMH > LogMemoryFreed err( %i )", err );
+ }
+ }
+ }
+
+ // Free the memory using original allocator
+ iAllocator->Free( aPtr );
+
+ LOGSTR2( "ATMH RAnalyzeToolAllocator::Free() - aPtr: %x", (TUint32)aPtr );
+
+ // Release the mutex
+ iMutex.Signal();
+ }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::Open()
+// Opens this heap for shared access. Opening the heap increases
+// the heap's access count by one.
+// -----------------------------------------------------------------------------
+//
+TInt RAnalyzeToolAllocator::Open()
+ {
+ LOGSTR1( "ATMH RAnalyzeToolAllocator::Open()");
+
+ // Acquire the mutex
+ iMutex.Wait();
+
+ // Share the memory using original allocator
+ TInt error = iAllocator->Open();
+
+ // If everything is OK add thread to the array which use this allocator
+ if ( KErrNone == error )
+ {
+ TThreadParamsBuf params;
+ params().iThreadId = RThread().Id().operator TUint();
+ error = iAnalyzeTool.ThreadStack( params );
+
+ __ASSERT_ALWAYS( KErrNone == error, AssertPanic( ECantAppendToTheArray ) );
+
+ if ( KErrNone == error )
+ {
+ LOGSTR2( "ATMH Thread stack address: %x", params().iStackAddress );
+ LOGSTR2( "ATMH Thread stack size: %x", params().iStackSize );
+ iThreadArray.Append( TThreadStack( RThread().Id(),
+ params().iStackAddress + params().iStackSize ) );
+ }
+ }
+
+ // Release the mutex
+ iMutex.Signal();
+
+ // Return the error code
+ return error;
+ }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::Close()
+// Closes this shared heap. Closing the heap decreases the heap's
+// access count by one.
+// -----------------------------------------------------------------------------
+//
+void RAnalyzeToolAllocator::Close()
+ {
+ LOGSTR1( "ATMH RAnalyzeToolAllocator::Close()" );
+
+ // Acquire the mutex
+ iMutex.Wait();
+
+ // Close the memory using original allocator
+ iAllocator->Close();
+
+ TInt count = iThreadArray.Count();
+
+ // Iterate through array of threads to remove current thread
+ for ( TInt i = 0; i < count; i++ )
+ {
+ // Check if this is current thread
+ if ( iThreadArray[ i ].Match() )
+ {
+ // Remove the thread
+ iThreadArray.Remove( i );
+ break;
+ }
+ }
+
+ // Release the mutex
+ iMutex.Signal();
+ }
+
+#ifdef __WINS__
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::ReAlloc()
+// Increases or decreases the size of an existing cell.
+// -----------------------------------------------------------------------------
+//
+TAny* RAnalyzeToolAllocator::ReAlloc( TAny* aPtr, TInt aSize, TInt aMode )
+ {
+ LOGSTR1( "ATMH RAnalyzeToolAllocator::ReAlloc()" );
+
+ // Acquire the mutex
+ iMutex.Wait();
+
+ // Realloc the memory using original allocator
+ TAny* ptr = iAllocator->ReAlloc( aPtr, aSize, aMode );
+
+ // NULL addresses are not in a process under test
+ if ( ptr && !( aMode & ENeverMove ) )
+ {
+ LOGSTR3( "ATMH RAnalyzeToolAllocator::ReAlloc() - aPtr: %x, ptr: %x",
+ (TUint32)aPtr, (TUint32)ptr );
+ LOGSTR3( "ATMH RAnalyzeToolAllocator::ReAlloc() - aSize: %i, aMode: %i",
+ aSize, aMode );
+
+ // Don't collect or log data if storage server not open or logging mode fast.
+ if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
+ {
+ // Reset the callstack
+ iReCallStack.Reset();
+
+ // Find the current thread callstack start address
+ TUint32 stackstart( 0 );
+ TBool found( FindCurrentThreadStack( stackstart ) );
+ LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found );
+
+ // Get current sp
+ TUint32 _sp( 0 );
+ __asm
+ {
+ mov [_sp], esp
+ }
+
+ // Get codeblocks count
+ TInt blocksCount( iCodeblocks.Count() );
+ TInt error( KErrNone );
+ TUint arrayCounter = 0;
+
+ for ( TUint32 i = _sp; i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
+ {
+ TUint32 addr = (TUint32) *( (TUint32*) i );
+ if ( ! IsAddressLoadedCode( addr ) )
+ continue;
+ for ( TInt j = 0; j < blocksCount; j++ )
+ {
+ if ( iCodeblocks[j].CheckAddress( addr ) )
+ {
+ // To avoid recursive call to ReAlloc specifying granularity
+ // Add address to the callstack
+ iReCallStack[arrayCounter] = addr;
+ arrayCounter++;
+ break;
+ }
+ }
+ if ( arrayCounter == KATMaxCallstackLength ||
+ arrayCounter == iAllocMaxCallStack )
+ {
+ LOGSTR2( "ATMH > Wanted CallStack items ready( %i )", arrayCounter );
+ break;
+ }
+ }
+
+ // No need to report free if the aPtr was NULL
+ if ( aPtr != NULL )
+ {
+ // Reset the free callstack
+ iFreeCallStack.Reset();
+
+ // if trace logging mode(s) we also log call stack in free.
+ if ( ( iLogOption == EATUseDefault || iLogOption == EATLogToTrace || iLogOption == EATLogToTraceFast )
+ && iFreeMaxCallStack > 0 )
+ {
+ for ( TInt i = 0; i < arrayCounter; i++ )
+ {
+ if ( i == KATMaxFreeCallstackLength || i == iFreeMaxCallStack )
+ {
+ break;
+ }
+ iFreeCallStack[i] = iReCallStack[i];
+ }
+ }
+
+ // Try to remove old address from the storage server's
+ // leak array. If found it's removed from the array because system frees
+ // old address directly in the RHeap in ReAlloc case.
+ if ( iLogOption == EATLogToTraceFast )
+ {
+ ATFastLogMemoryFreed( iProcessId, (TUint32) aPtr, iFreeCallStack );
+ }
+ else
+ {
+ iStorageServer.LogMemoryFreed( (TUint32) aPtr, iFreeCallStack );
+ }
+ }
+
+ // Log the memory allocation information
+ if ( iLogOption == EATLogToTraceFast )
+ {
+ // Using fast mode.
+ ATFastLogMemoryAllocated( iProcessId, (TUint32) ptr, iFreeCallStack, aSize);
+ }
+ else
+ {
+ // Using storage server.
+ error = iStorageServer.LogMemoryAllocated( (TUint32) ptr,
+ iReCallStack,
+ aSize );
+ if ( KErrNone != error )
+ {
+ LOGSTR2( "ATMH LogMemoryAllocated ReAlloc error %i", error );
+ switch ( error )
+ {
+ case KErrNoMemory:
+ LOGSTR1( "ATMH RAnalyzeToolAllocator::ReAlloc() - KErrNoMemory case" );
+ if ( iStorageServerOpen )
+ {
+ iStorageServerOpen = EFalse;
+ LOGSTR1( "ATMH RAnalyzeToolAllocator::ReAlloc() - close iStorageServer" );
+ iStorageServer.Close();
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // Release the mutex
+ iMutex.Signal();
+
+ // Return pointer to the reallocated cell
+ return ptr;
+ }
+
+#else
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::ReAlloc()
+// Increases or decreases the size of an existing cell.
+// -----------------------------------------------------------------------------
+//
+TAny* RAnalyzeToolAllocator::ReAlloc( TAny* aPtr, TInt aSize, TInt aMode )
+ {
+ LOGSTR1( "ATMH RAnalyzeToolAllocator::ReAlloc()" );
+
+ // Acquire the mutex
+ iMutex.Wait();
+
+ // Realloc the memory using original allocator
+ TAny* ptr = iAllocator->ReAlloc( aPtr, aSize, aMode );
+
+ // NULL addresses are not in a process under test
+ if ( ptr && !( aMode & ENeverMove ) )
+ {
+ LOGSTR3( "ATMH RAnalyzeToolAllocator::ReAlloc() - aPtr: %x, ptr: %x",
+ (TUint32)aPtr, (TUint32)ptr );
+ LOGSTR3( "ATMH RAnalyzeToolAllocator::ReAlloc() - aSize: %i, aMode: %i",
+ aSize, aMode );
+
+ // Don't collect or log data if storage server not open or logging mode fast.
+ if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
+ {
+ // Reset the callstack
+ iReCallStack.Reset();
+
+ // Find the current thread callstack start address
+ TUint32 stackstart( 0 );
+ TBool found( FindCurrentThreadStack( stackstart ) );
+ LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found );
+
+ // Get codeblocks count
+ TInt blocksCount( iCodeblocks.Count() );
+ TInt error( KErrNone );
+ TUint arrayCounter = 0;
+
+ for ( TUint32 i = __current_sp(); i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
+ {
+ TUint32 addr = (TUint32) *( (TUint32*) i );
+ if ( ! IsAddressLoadedCode( addr ) )
+ continue;
+ for ( TInt j = 0; j < blocksCount; j++ )
+ {
+ if ( iCodeblocks[j].CheckAddress( addr ) )
+ {
+ // To avoid recursive call to ReAlloc specifying granularity
+ // Add address to the callstack
+ iReCallStack[arrayCounter] = ( addr );
+ arrayCounter++;
+ break;
+ }
+ }
+ if ( arrayCounter == KATMaxCallstackLength ||
+ arrayCounter == iAllocMaxCallStack )
+ {
+ LOGSTR2( "ATMH > Wanted CallStack items ready( %i )", arrayCounter );
+ break;
+ }
+ }
+
+ // No need to report free if the aPtr was NULL
+ if ( aPtr != NULL )
+ {
+ // Reset the free callstack
+ iFreeCallStack.Reset();
+
+ // if trace logging mode(s) we also log call stack with free.
+ if ( ( iLogOption == EATUseDefault || iLogOption == EATLogToTrace || iLogOption == EATLogToTraceFast )
+ && iFreeMaxCallStack > 0 )
+ {
+ for ( TInt i = 0; i < arrayCounter; i++ )
+ {
+ if ( i == iFreeCallStack.Count() )
+ {
+ break;
+ }
+ iFreeCallStack[i] = iReCallStack[i];
+ }
+ }
+
+ // Try to remove old address from the storage server's
+ // leak array. If found it's removed from the array because system frees
+ // old address directly in the RHeap in ReAlloc case.
+ if ( iLogOption == EATLogToTraceFast )
+ {
+ ATFastLogMemoryFreed( iProcessId, (TUint32) aPtr, iFreeCallStack );
+ }
+ else
+ {
+ iStorageServer.LogMemoryFreed( (TUint32) aPtr, iFreeCallStack );
+ }
+ }
+
+ // Log the memory allocation information
+ if ( iLogOption == EATLogToTraceFast )
+ {
+ // Using fast mode.
+ ATFastLogMemoryAllocated( iProcessId, (TUint32) ptr, iReCallStack, aSize );
+ }
+ else
+ {
+ // Using storage server.
+ error = iStorageServer.LogMemoryAllocated( (TUint32) ptr,
+ iReCallStack,
+ aSize );
+ if ( KErrNone != error )
+ {
+ LOGSTR2( "ATMH LogMemoryAllocated ReAlloc error %i", error );
+ switch ( error )
+ {
+ case KErrNoMemory:
+ LOGSTR1( "ATMH RAnalyzeToolAllocator::ReAlloc() - KErrNoMemory case" );
+ if ( iStorageServerOpen )
+ {
+ iStorageServerOpen = EFalse;
+ LOGSTR1( "ATMH RAnalyzeToolAllocator::ReAlloc() - close iStorageServer" );
+ iStorageServer.Close();
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // Release the mutex
+ iMutex.Signal();
+
+ // Return pointer to the reallocated cell
+ return ptr;
+ }
+
+#endif // __WINS__
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::Compress()
+// The function frees excess committed space from the top of the heap.
+// The size of the heap is never reduced below the minimum size
+// specified during creation of the heap.
+// -----------------------------------------------------------------------------
+//
+TInt RAnalyzeToolAllocator::Compress()
+ {
+ LOGSTR1( "ATMH RAnalyzeToolAllocator::Compress()" );
+
+ // Acquire the mutex
+ iMutex.Wait();
+
+ // Compress the memory using original allocator
+ TInt compress = iAllocator->Compress();
+
+ // Release the mutex
+ iMutex.Signal();
+
+ // Return the space reclaimed
+ return compress;
+ }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::Reset()
+// Frees all allocated cells on this heap.
+// -----------------------------------------------------------------------------
+//
+void RAnalyzeToolAllocator::Reset()
+ {
+ LOGSTR1( "ATMH RAnalyzeToolAllocator::Reset()" );
+
+ // Acquire the mutex
+ iMutex.Wait();
+
+ // Reset the memory using original allocator
+ iAllocator->Reset();
+
+ // Release the mutex
+ iMutex.Signal();
+ }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::AllocSize()
+// Gets the number of cells allocated on this heap, and
+// the total space allocated to them.
+// -----------------------------------------------------------------------------
+//
+TInt RAnalyzeToolAllocator::AllocSize( TInt& aTotalAllocSize ) const
+ {
+ LOGSTR1( "ATMH RAnalyzeToolAllocator::AllocSize()" );
+
+ // Acquire the mutex
+ iMutex.Wait();
+
+ // Acquire the memory information using original allocator
+ TInt size = iAllocator->AllocSize( aTotalAllocSize );
+
+ // Release the mutex
+ iMutex.Signal();
+
+ // Return the number of cells allocated on this heap.
+ return size;
+ }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::Available()
+// Gets the total free space currently available on the heap and the
+// space available in the largest free block. The space available
+// represents the total space which can be allocated. Note that
+// compressing the heap may reduce the total free space available
+// and the space available in the largest free block.
+// -----------------------------------------------------------------------------
+//
+TInt RAnalyzeToolAllocator::Available( TInt& aBiggestBlock ) const
+ {
+ LOGSTR1( "ATMH RAnalyzeToolAllocator::Available()" );
+
+ // Acquire the mutex
+ iMutex.Wait();
+
+ // Acquire the memory information using original allocator
+ TInt available = iAllocator->Available( aBiggestBlock );
+
+ // Release the mutex
+ iMutex.Signal();
+
+ // Return the total free space currently available on the heap
+ return available;
+ }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::AllocLen()
+// Gets the length of the available space in the specified
+// allocated cell.
+// -----------------------------------------------------------------------------
+//
+TInt RAnalyzeToolAllocator::AllocLen( const TAny* aCell ) const
+ {
+ LOGSTR1( "ATMH RAnalyzeToolAllocator::AllocLen()" );
+
+ // Acquire the mutex
+ iMutex.Wait();
+
+ // Acquire the memory information using original allocator
+ TInt len = iAllocator->AllocLen( aCell );
+
+ // Release the mutex
+ iMutex.Signal();
+
+ // Return the length of the available space in the allocated cell.
+ return len;
+ }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::DebugFunction()
+// Invocates specified debug funtionality.
+// -----------------------------------------------------------------------------
+//
+TInt RAnalyzeToolAllocator::DebugFunction( TInt aFunc, TAny* a1, TAny* a2 )
+ {
+ LOGSTR2( "ATMH RAnalyzeToolAllocator::DebugFunction() %i", aFunc );
+
+ // Acquire the mutex
+ iMutex.Wait();
+
+ // Invocate debug funtion using original allocator
+ TInt debug = iAllocator->DebugFunction( aFunc, a1, a2 );
+
+ switch( aFunc )
+ {
+ case EMarkEnd:
+ {
+ // Disables the __UHEAP_MARKEND macro
+ LOGSTR1( "ATMH __UHEAP_MARKEND macro called" );
+ if ( debug > 0 )
+ {
+ LOGSTR2( "ATMH __UHEAP_MARKEND detects leaks: %d", debug );
+ // Because there is leaks the alloc panic will occur but
+ // lets return a zero to pretend that everything is OK
+ debug = 0;
+ }
+ }
+ break;
+
+ default:
+ {
+ }
+ break;
+ }
+
+ // Release the mutex
+ iMutex.Signal();
+
+ // Return information of the debug function success
+ return debug;
+ }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::Extension_()
+// Extension function
+// -----------------------------------------------------------------------------
+//
+TInt RAnalyzeToolAllocator::Extension_( TUint aExtensionId, TAny*& a0,
+ TAny* a1 )
+ {
+ LOGSTR1( "ATMH RAnalyzeToolAllocator::Extension_()" );
+
+ // Acquire the mutex
+ iMutex.Wait();
+
+ // Invocate extension funtion using original allocator
+ TInt ext = RAllocator::Extension_( aExtensionId, a0, a1 );
+
+ // Release the mutex
+ iMutex.Signal();
+
+ // Return information of the extension function success
+ return ext;
+ }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::ShareHeap()
+// Share heap with other thread
+// -----------------------------------------------------------------------------
+//
+void RAnalyzeToolAllocator::ShareHeap()
+ {
+ LOGSTR1( "ATMH RAnalyzeToolAllocator::ShareHeap()" );
+
+ // Call the overwrited Open function
+ Open();
+ }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolAllocator::FindCurrentThreadStack()
+// Find the current thread which is using the heap
+// -----------------------------------------------------------------------------
+//
+TBool RAnalyzeToolAllocator::FindCurrentThreadStack( TUint32& aStackStart )
+ {
+ LOGSTR2( "ATMH RAnalyzeToolAllocator::FindCurrentThreadStack(), count( %i )",
+ iThreadArray.Count() );
+
+ // Flag for indicating that right thread has been found
+ TBool found( EFalse );
+ // If threre is only one thread it must be the right thread
+ if ( iThreadArray.Count() == KThreadCount )
+ {
+ if ( !iThreadArray[ 0 ].ThreadStackStart( aStackStart ) )
+ {
+ // This MUST BE the right thread
+ //__ASSERT_ALWAYS( EFalse, AssertPanic( ECantFindRightThread ) );
+ }
+ else if ( iThreadArray[ 0 ].ThreadStackStart( aStackStart ) )
+ {
+ found = ETrue;
+ }
+ }
+ else
+ {
+ // Iterate through array to find right thread
+ TInt count( iThreadArray.Count() );
+
+ for ( TInt i = 0; i < count; i++ )
+ {
+ // Check if this is the right thread
+ if ( iThreadArray[ i ].ThreadStackStart( aStackStart ) )
+ {
+ // Right thread found. Mark the flag
+ found = ETrue;
+ break;
+ }
+ }
+ // If right thread was not found the panic must be raised
+ if ( !found )
+ {
+ //__ASSERT_ALWAYS( EFalse, AssertPanic( ECantFindRightThread ) );
+ }
+ }
+ return found;
+ }
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/src/analyzetooleventhandler.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,230 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Definitions for the class CLibraryEventHandler.
+*
+*/
+
+
+// INCLUDE FILES
+#include "atlog.h"
+#include "analyzetooleventhandler.h"
+#include "analyzetooleventhandlernotifier.h"
+#include "analyzetoolmemoryallocator.h"
+#include "analyzetoolfastlog.h"
+
+// -----------------------------------------------------------------------------
+// CLibraryEventHandler::~CLibraryEventHandler()
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+CLibraryEventHandler::~CLibraryEventHandler()
+ {
+ LOGSTR1( "ATMH CLibraryEventHandler::~CLibraryEventHandler()" );
+ Cancel();
+ }
+
+// -----------------------------------------------------------------------------
+// CLibraryEventHandler::RunL()
+// Process active object's task
+// -----------------------------------------------------------------------------
+//
+void CLibraryEventHandler::RunL()
+ {
+ LOGSTR1( "ATMH CLibraryEventHandler::RunL()" );
+
+ if ( KErrNone != iStatus.Int() )
+ {
+ LOGSTR2( "ATMH RunL error: %i", iStatus.Int() );
+ return;
+ }
+ // Acquire the mutex
+ iMutex.Wait();
+
+ // Check that this is observed process
+ if ( iLibraryInfo.iEventType == TLibraryEventInfo::ELibraryAdded )
+ {
+ LOGSTR1( "ATMH CLibraryEventHandler::RunL() - TLibraryEventInfo::ELibraryAdded" );
+ if ( iLibraryInfo.iProcessId == iProcessId )
+ {
+ TInt error( KErrNone );
+
+ // Log library load event.
+ if ( iLogOption == EATLogToTraceFast )
+ {
+ LOGSTR1( "ATMH CLibraryEventHandler::RunL() - ATFastLog.LogDllLoaded() " );
+ ATFastLogDllLoaded( iProcessId,
+ iLibraryInfo.iLibraryName,
+ iLibraryInfo.iRunAddress,
+ iLibraryInfo.iRunAddress + iLibraryInfo.iSize );
+ }
+ else
+ {
+ LOGSTR1( "ATMH CLibraryEventHandler::RunL() - iStorageServer.LogDllLoaded() " );
+ error = iStorageServer.LogDllLoaded(
+ iLibraryInfo.iLibraryName,
+ iLibraryInfo.iRunAddress,
+ iLibraryInfo.iRunAddress + iLibraryInfo.iSize );
+ LOGSTR2( "ATMH StorageServer error: %i", error );
+ }
+ if ( KErrNone == error )
+ {
+ iCodeblocks.Append( TCodeblock( iLibraryInfo.iRunAddress,
+ iLibraryInfo.iSize,
+ iLibraryInfo.iLibraryName ) );
+ }
+ }
+ }
+ else if ( iLibraryInfo.iEventType == TLibraryEventInfo::ELibraryRemoved )
+ {
+ LOGSTR1( "ATMH CLibraryEventHandler::RunL() - TLibraryEventInfo::ELibraryRemoved " );
+ TInt count = iCodeblocks.Count();
+ LOGSTR2( "ATMH count of code blocks: %i", count );
+ for ( TInt i = 0; i < count; i++ )
+ {
+ if ( iCodeblocks[ i ].Match( iLibraryInfo.iLibraryName ) )
+ {
+ TBuf8<KMaxLibraryName> libraryName;
+ libraryName.Copy( iLibraryInfo.iLibraryName );
+
+ // Log library unloaded event
+ if ( iLogOption == EATLogToTraceFast )
+ {
+ LOGSTR1( "ATMH CLibraryEventHandler::RunL() - ATFastLogDllUnloaded() " );
+ ATFastLogDllUnloaded( iProcessId,
+ libraryName,
+ iLibraryInfo.iRunAddress,
+ iLibraryInfo.iRunAddress + iLibraryInfo.iSize );
+ }
+ else
+ {
+ LOGSTR1( "ATMH CLibraryEventHandler::RunL() - iStorageServer.LogDllUnloaded() " );
+ #ifdef LOGGING_ENABLED
+ TInt error = iStorageServer.LogDllUnloaded(
+ libraryName/*iLibraryInfo.iLibraryName*/,
+ iLibraryInfo.iRunAddress,
+ iLibraryInfo.iRunAddress + iLibraryInfo.iSize );
+
+ LOGSTR2( "ATMH StorageServer error: %i", error );
+ #else
+ iStorageServer.LogDllUnloaded(
+ libraryName/*iLibraryInfo.iLibraryName*/,
+ iLibraryInfo.iRunAddress,
+ iLibraryInfo.iRunAddress + iLibraryInfo.iSize );
+ #endif
+ }
+ iCodeblocks.Remove( i );
+ break;
+ }
+ }
+ }
+ else if ( iLibraryInfo.iEventType == TLibraryEventInfo::EKillThread )
+ {
+ LOGSTR1( "ATMH CLibraryEventHandler::RunL() - TLibraryEventInfo::EKillThread" );
+
+ iNotifier.RemoveKilledThread( iLibraryInfo.iThreadId );
+ }
+
+ Start();
+
+ // Release the mutex
+ iMutex.Signal();
+ }
+
+// -----------------------------------------------------------------------------
+// CLibraryEventHandler::DoCancel()
+// Cancels active object's task
+// -----------------------------------------------------------------------------
+//
+void CLibraryEventHandler::DoCancel()
+ {
+ LOGSTR1( "ATMH CLibraryEventHandler::DoCancel()" );
+ // Cancel the subscription of the library events
+ if ( IsActive() )
+ {
+ iStarted = EFalse;
+
+ iAnalyzeTool.CancelLibraryEvent();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CLibraryEventHandler::Start()
+// Creates CActiveScheduler and variables for the child thread
+// -----------------------------------------------------------------------------
+//
+void CLibraryEventHandler::Start()
+ {
+ LOGSTR1( "ATMH CLibraryEventHandler::Start()" );
+
+ // Acquire the mutex
+ iMutex.Wait();
+
+ if ( !IsAdded() )
+ {
+ CActiveScheduler::Add( this );
+ }
+
+ // Cancel current subscribetion
+ if ( IsActive() )
+ {
+ iStarted = EFalse;
+ Cancel();
+ }
+
+ iStatus = KErrNone;
+ iAnalyzeTool.LibraryEvent( iStatus, iLibraryInfo );
+ SetActive();
+
+ iStarted = ETrue;
+ // Release the mutex
+ iMutex.Signal();
+ }
+
+// -----------------------------------------------------------------------------
+// CLibraryEventHandler::CLibraryEventHandler()
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CLibraryEventHandler::CLibraryEventHandler( RAnalyzeTool& aAnalyzeTool,
+ RArray<TCodeblock>& aCodeblocks, RATStorageServer& aStorageServer,
+ TUint aProcessId, RMutex& aMutex,
+ MAnalyzeToolEventhandlerNotifier& aNotifier,
+ TUint32 aLogOption )
+ : CActive( EPriorityNormal ),
+ iAnalyzeTool( aAnalyzeTool ),
+ iCodeblocks( aCodeblocks ),
+ iStorageServer( aStorageServer ),
+ iProcessId( aProcessId ),
+ iMutex( aMutex ),
+ iStarted( EFalse ),
+ iNotifier( aNotifier ),
+ iLogOption( aLogOption )
+ {
+ LOGSTR1( "ATMH CLibraryEventHandler::CLibraryEventHandler()" );
+ }
+
+// -----------------------------------------------------------------------------
+// CLibraryEventHandler::IsStarted()
+// Returns eventhandler's state.
+// -----------------------------------------------------------------------------
+//
+TBool CLibraryEventHandler::IsStarted()
+ {
+ LOGSTR2( "ATMH CLibraryEventHandler::IsStarted(%i)", iStarted );
+
+ return iStarted;
+ }
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/src/analyzetoolfastlog.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,298 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <e32debug.h> // RDebug
+#include <analyzetool/analyzetooltraceconstants.h>
+#include "analyzetoolfastlog.h"
+#include "atlog.h"
+
+// Local time function.
+TInt64 CurrentTime()
+ {
+ LOGSTR1( "ATFL CurrentTime()" );
+ TTime time;
+ time.UniversalTime();
+ return time.Int64() - KMicroSecondsAt1970;
+ }
+
+TInt ATFastLogProcessStarted( const TDesC8& aProcessName,
+ TUint aProcessId,
+ TUint32 aIsDebug )
+ {
+ LOGSTR1( "ATFL ATFastLogProcessStarted()" );
+ // Convert process name to 16-bit descriptor.
+ TBuf<KMaxProcessName> processName;
+ processName.Copy( aProcessName );
+ // Buffer to trace.
+ TBuf<KProcessStartBufLength> buffer;
+ // Format process name and id.
+ buffer.Format( KProcessStart16, &processName, aProcessId );
+ // Timestamp.
+ buffer.AppendNum( CurrentTime(), EHex ) ;
+ // Append udeb/urel information to the process start.
+ buffer.Append( KSpaceTrace );
+ buffer.AppendNum( aIsDebug, EHex );
+ // Append version number.
+ buffer.Append( KSpaceTrace );
+ buffer.AppendNum( KATTraceVersion, EHex );
+ // Log to trace.
+ RDebug::Print( KTraceMessage, aProcessId ,&buffer );
+ return KErrNone;
+ }
+
+TInt ATFastLogProcessEnded( TUint aProcessId,
+ TUint aHandleLeakCount )
+ {
+ LOGSTR1( "ATFL ATFastLogProcessEnded()" );
+ // Handle leaks.
+ if ( aHandleLeakCount > 0 )
+ {
+ // Buffer to trace.
+ TBuf<KHandleLeakBufLength> buffer2;
+ buffer2.Format( KHandleLeak16, &KUnknownModule16, aHandleLeakCount );
+ // Trace it.
+ RDebug::Print( KTraceMessage, aProcessId, &buffer2 );
+ }
+ // Process end trace.
+ TBuf<KProcessEndBufLength> buffer;
+ buffer.Format( KProcessEnd16, aProcessId );
+ buffer.AppendNum( CurrentTime(), EHex);
+ buffer.Append( KNewLineTrace );
+ RDebug::Print( KTraceMessage, aProcessId, &buffer );
+ return KErrNone;
+ }
+
+TInt ATFastLogDllLoaded( TUint aProcessId,
+ const TDesC8& aDllName,
+ TUint32 aStartAddress,
+ TUint32 aEndAddress )
+ {
+ LOGSTR1( "ATFL ATFastLogDllLoaded()" );
+ // Timestamp.
+ TInt64 time = CurrentTime();
+ // Convert dll name to 16-bit descriptor.
+ TBuf<KMaxLibraryName> dll;
+ dll.Copy( aDllName );
+ // Buffer to trace.
+ TBuf<KDllLoadBufLength> buffer;
+ buffer.Format( KDllLoad16, &dll, time, aStartAddress, aEndAddress );
+ RDebug::Print( KTraceMessage, aProcessId, &buffer );
+ return KErrNone;
+ }
+
+TInt ATFastLogDllUnloaded( TUint aProcessId, const TDesC8& aDllName, TUint32 aStartAddress,
+ TUint32 aEndAddress )
+ {
+ LOGSTR1( "ATFL ATFastLogDllUnloaded()" );
+ // Timestamp.
+ TInt64 time = CurrentTime();
+ // Convert dll name to 16-bit descriptor.
+ TBuf<KMaxLibraryName> dll;
+ dll.Copy( aDllName );
+ // Buffer to trace.
+ TBuf<KDllLoadBufLength> buffer;
+ buffer.Format( KDllUnload16, &dll, time, aStartAddress, aEndAddress );
+ RDebug::Print( KTraceMessage, aProcessId, &buffer );
+ return KErrNone;
+ }
+
+TInt ATFastLogMemoryAllocated( TUint aProcessId, TUint32 aMemAddress,
+ TFixedArray<TUint32, KATMaxCallstackLength>& aCallstack,
+ TInt aSize )
+ {
+ LOGSTR1( "ATFL ATFastLogMemoryAllocated()" );
+ // ALLOCH <Memory address> <Time stamp> <Allocation size> <Call stack address count>
+ // <Call stack address> <Call stack address> ...
+
+ // Timestamp.
+ TInt64 time = CurrentTime();
+
+ // Trace buffer and pointer to it.
+ TBufC<KMemAllocBufLength> buffer;
+ TPtr ptr( buffer.Des() );
+ // Append the tag implying a memory allocation line in the data file
+ ptr.Append( KMemoryAllocHeader );
+
+ // Append the start address of this allocation in the 32-bit (max 8 characters)
+ // hexadecimal text format.
+ ptr.AppendNum( aMemAddress, EHex );
+
+ // Append the current time in the 64-bit (max 16 characters) hexadecimal text
+ // format
+ ptr.Append( KSpaceTrace );
+ ptr.AppendNum( time, EHex );
+
+ // Append the size of the allocation in the 32-bit (max 8 characters) hexadecimal
+ // text format.
+ ptr.Append( KSpaceTrace );
+ ptr.AppendNum( aSize, EHex );
+
+ // Search call stack for address count.
+ TInt addrCount(0);
+ for ( TInt j = 0; j < aCallstack.Count() ; j++ )
+ {
+ if ( aCallstack.At(j) == 0 )
+ break;
+ addrCount++;
+ }
+ // Current position in call stack.
+ TInt addrPos( 0 );
+
+ // Append address count.
+ ptr.Append( KSpaceTrace );
+ ptr.AppendNum( addrCount, EHex );
+
+ // Calculate last item length
+ TInt lastItemLength( KTraceMessage().Length() + KHexa32Length +
+ KSpaceLength + KNewlineLength );
+
+ TUint packetNumber( 1 );
+
+ // Go through all call stack's memory addresses associated with
+ // this memory allocation
+ for ( TInt j = 0; j < addrCount; j++ )
+ {
+ // ALLOCF <Memory address> <Time stamp> <Packet number>
+ // <Call stack address> <Call stack address> ...
+ if ( ptr.Length() <= 0 )
+ {
+ // Create alloc fragment message header
+ ptr.Append( KMemoryAllocFragment );
+ ptr.AppendNum( aMemAddress, EHex );
+ ptr.Append( KSpaceTrace );
+ ptr.AppendNum( time, EHex );
+ ptr.Append( KSpaceTrace );
+ ptr.AppendNum( packetNumber, EHex );
+ // Increase packet number
+ packetNumber++;
+ }
+
+ // Append call stack address.
+ ptr.AppendFormat( KHexaNumberTrace, aCallstack.At( addrPos ) );
+
+ // Move the call stack position.
+ addrPos++;
+
+ // Check if buffer max length exceed
+ if ( lastItemLength + ptr.Length() >= KMemAllocBufLength )
+ {
+ ptr.Append( KNewLineTrace );
+ // Log through debug channel
+ RDebug::Print( KTraceMessage, aProcessId, &buffer );
+ // Empty trace buffer
+ ptr.Delete( 0, ptr.MaxLength() );
+ }
+ }
+ // Send last message if exists.
+ if ( ptr.Length() > 0 )
+ {
+ ptr.Append( KNewLineTrace );
+ RDebug::Print( KTraceMessage, aProcessId, &buffer);
+ }
+ return KErrNone;
+ }
+
+
+TInt ATFastLogMemoryFreed( TUint aProcessId, TUint32 aMemAddress,
+ TFixedArray<TUint32, KATMaxFreeCallstackLength>& aFreeCallstack )
+ {
+ LOGSTR1( "ATFL ATFastLogMemoryFreed()" );
+ // FREEH <Memory address> <Time tamp> <Call stack address count> <Call stack address>
+ // <Call stack address> ...
+
+ // Timestamp.
+ TInt64 time = CurrentTime();
+
+ // Trace buffer and pointer to it.
+ TBufC<KMemFreedBufLength> buffer;
+ TPtr ptr( buffer.Des() );
+
+ // Append the tag implying a memory allocation line in the data file
+ ptr.Append( KMemoryFreedHeader );
+
+ // Append the start address of this allocation in the 32-bit (max 8 characters)
+ // hexadecimal text format.
+ ptr.AppendNum( aMemAddress, EHex );
+
+ // Append timestamp;
+ ptr.Append( KSpaceTrace );
+ ptr.AppendNum( time, EHex);
+
+ // Search call stack for address count.
+ TInt addrCount(0);
+ for ( TInt j = 0; j < aFreeCallstack.Count() ; j++ )
+ {
+ if ( aFreeCallstack.At(j) == 0 )
+ break;
+ addrCount++;
+ }
+ // Current position in call stack.
+ TInt addrPos( 0 );
+
+ // Append address count.
+ ptr.Append( KSpaceTrace );
+ ptr.AppendNum( addrCount, EHex );
+
+ // Calculate last item length
+ TInt lastItemLength( KTraceMessage().Length() + KHexa32Length +
+ KSpaceLength + KNewlineLength );
+
+ TUint packetNumber( 1 );
+
+ // Go through all call stack's memory addresses associated with
+ // this memory allocation
+ for ( TInt j = 0; j < addrCount; j++ )
+ {
+ // ALLOCF <Memory address> <Time stamp> <Packet number>
+ // <Call stack address> <Call stack address> ...
+ if ( ptr.Length() <= 0 )
+ {
+ // Create alloc fragment message header
+ ptr.Append( KMemoryFreedFragment );
+ ptr.AppendNum( aMemAddress, EHex );
+ ptr.Append( KSpaceTrace );
+ ptr.AppendNum( packetNumber, EHex );
+ // Increase packet number
+ packetNumber++;
+ }
+
+ // Append call stack address.
+ ptr.AppendFormat( KHexaNumberTrace, aFreeCallstack.At( addrPos ) );
+
+ // Move the call stack position.
+ addrPos++;
+
+ // Check if buffer max length exceed
+ if ( lastItemLength + ptr.Length() >= KMemFreedBufLength )
+ {
+ ptr.Append( KNewLineTrace );
+ // Log through debug channel
+ RDebug::Print( KTraceMessage, aProcessId, &buffer );
+ // Empty trace buffer
+ ptr.Delete( 0, ptr.MaxLength() );
+ }
+ }
+ // Send last message if exists.
+ if ( ptr.Length() > 0 )
+ {
+ ptr.Append( KNewLineTrace );
+ RDebug::Print( KTraceMessage, aProcessId, &buffer);
+ }
+ return KErrNone;
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/src/analyzetoolmainallocator.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,1509 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Definitions for the class RAnalyzeToolMainAllocator.
+*
+*/
+
+
+#include "analyzetoolmainallocator.h"
+#include "atlog.h"
+#include "analyzetooleventhandler.h"
+#include "analyzetoolmemoryallocator.h"
+#include "analyzetoolpanics.pan"
+#include "analyzetoolfastlog.h"
+#include <e32svr.h>
+
+
+// CONSTANTS
+
+// The name of the memoryhook dll
+_LIT8( KMemoryHook, "AToolMemoryHook.dll" );
+
+// The name of the storage server dll
+_LIT8( KStorageServer, "AToolStorageServerClnt.dll" );
+
+// Length of the callstack address
+const TUint32 KAddressLength = 4;
+
+// Thread count
+const TInt KThreadCount = 1;
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::RAnalyzeToolMainAllocator()
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+RAnalyzeToolMainAllocator::RAnalyzeToolMainAllocator( TBool aNotFirst,
+ const TFileName aFileName, TUint32 aLogOption, TUint32 aIsDebug,
+ TUint32 aAllocCallStackSize, TUint32 aFreeCallStackSize ) :
+ RAnalyzeToolMemoryAllocator( aNotFirst ),
+ iAnalyzeToolOpen( EFalse ),
+ iDeviceDriverLoaded( EFalse ),
+ iCodeblocks( KATMaxCallstackLength ),
+ iThreadArray( KATMaxCallstackLength ),
+ iLogOption( aLogOption ),
+ iProcessId( RProcess().Id().operator TUint() ),
+ iAllocMaxCallStack( aAllocCallStackSize ),
+ iFreeMaxCallStack( aFreeCallStackSize )
+ {
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::RAnalyzeToolMainAllocator()" );
+
+ // Basic error variable used in method.
+ TInt error( KErrNone );
+
+ // Connect to the storage server if logging mode not fast trace.
+ if ( iLogOption != EATLogToTraceFast )
+ {
+ error = iStorageServer.Connect();
+
+ LOGSTR2( "ATMH Opening RATStorageServer error %i", error );
+
+ if ( KErrNone == error )
+ {
+ iStorageServerOpen = ETrue;
+ }
+ else
+ {
+ iStorageServerOpen = EFalse;
+ }
+
+ if ( KErrNone == error )
+ {
+ // Make the storage server handle shared between threads
+ error = iStorageServer.ShareAuto();
+ }
+
+ LOGSTR2( "ATMH Sharing RATStorageServer error %i", error );
+ }
+
+ // Create mutex for schedule access to shared resources
+ error = iMutex.CreateLocal();
+
+ __ASSERT_ALWAYS( KErrNone == error, AssertPanic( ECantCreateMutex ) );
+
+ LOGSTR2( "ATMH Creating mutex error %i", error );
+
+ // Load the kernel side device driver
+ error = User::LoadLogicalDevice( KAnalyzeToolLddName );
+
+ if ( error != KErrNone && error != KErrAlreadyExists )
+ {
+ __ASSERT_ALWAYS( EFalse, AssertPanic( ECantLoadDeviceDriver ) );
+ }
+ else
+ {
+ iDeviceDriverLoaded = ETrue;
+ }
+
+ LOGSTR2( "ATMH Loading device driver error %i", error );
+
+ // Open handle to the kernel sidedevice driver
+ error = iAnalyzeTool.Open();
+
+ __ASSERT_ALWAYS( KErrNone == error, AssertPanic( ECantConnectDeviceDriver ) );
+
+ if ( KErrNone == error )
+ {
+ iAnalyzeToolOpen = ETrue;
+ }
+
+ LOGSTR2( "ATMH Opening RAnalyzeTool handle %i error", error );
+
+ // Set memory model by asking kernel side device driver
+ if ( iAnalyzeToolOpen )
+ {
+ TATMemoryModelBuf model;
+ if ( KErrNone == iAnalyzeTool.GetMemoryModel( model ) )
+ {
+ iMemoryModel = model().iMemoryModel;
+ LOGSTR2( "ATMH AnalyzeTool MemoryModel: %i", iMemoryModel );
+ }
+ else
+ LOGSTR2( "ATMH AnalyzeTool GetMemoryModel error: %i", error );
+ }
+
+ // Retrieve the initial process information
+ LogProcessInformation( aFileName, aLogOption, aIsDebug );
+
+ // Create handler for receiving kernel events
+ iEventHandler = new CLibraryEventHandler( iAnalyzeTool,
+ iCodeblocks,
+ iStorageServer,
+ iProcessId,
+ iMutex,
+ *this,
+ aLogOption);
+
+ __ASSERT_ALWAYS( iEventHandler != NULL, AssertPanic( ENoMemory ) );
+ }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::~RAnalyzeToolMainAllocator()
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+RAnalyzeToolMainAllocator::~RAnalyzeToolMainAllocator()
+ {
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::~RAnalyzeToolMainAllocator()" );
+
+ TUint handleLeakCount( 0 );
+ if ( iAnalyzeToolOpen && iThreadArray.Count() > 0 )
+ {
+ TProcessHandleInfoBuf params;
+ params().iProcessId = iProcessId;
+ TInt error( iAnalyzeTool.GetProcessHandleInfo( params ) );
+ handleLeakCount = params().iThreadHandleCount;
+ }
+
+ // Close handle for process memory blocks
+ iCodeblocks.Close();
+
+ // Delete the eventhandler
+ delete iEventHandler;
+
+ // The count of device driver users
+ TClientCountBuf count;
+
+ // Check the flag
+ if ( iAnalyzeToolOpen )
+ {
+ TInt error = iAnalyzeTool.ClientCount( count );
+ LOGSTR2( "ATMH closing analyze tool handle error: %i", error );
+ iAnalyzeTool.Close();
+ }
+
+ // Check the flag
+ if ( iDeviceDriverLoaded )
+ {
+ LOGSTR2( "ATMH device driver client count: %i", count().iClientCount );
+
+ // Check if there is another user for device driver
+ if ( count().iClientCount <= 1 )
+ {
+ // There was no other users -> unload the device driver
+ TInt error = User::FreeLogicalDevice( KAnalyzeToolLddName );
+ LOGSTR2( "ATMH Unloading ldd error: %i", error );
+ }
+ }
+
+ // Close the thread array
+ iThreadArray.Close();
+
+ if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
+ {
+ if ( iLogOption == EATLogToTraceFast )
+ {
+ LOGSTR1( "ATMH ATFastLogProcessEnded()" );
+ ATFastLogProcessEnded( iProcessId, handleLeakCount );
+ }
+ else
+ {
+ iStorageServerOpen = EFalse;
+ // Inform that process has ended and close the handle
+ LOGSTR1( "ATMH iStorageServer.LogProcessEnded()" );
+ iStorageServer.LogProcessEnded( iProcessId, handleLeakCount );
+ // Close the handle
+ iStorageServer.Close();
+ }
+ }
+
+ // Close the mutex
+ iMutex.Close();
+ }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::ShareHeap()
+// Share heap with other thread
+// -----------------------------------------------------------------------------
+//
+void RAnalyzeToolMainAllocator::ShareHeap()
+ {
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::ShareHeap()" );
+
+ // Call the overwrited Open function
+ Open();
+ }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::Uninstall()
+// Uninstalls the current allocator
+// -----------------------------------------------------------------------------
+//
+void RAnalyzeToolMainAllocator::Uninstall()
+ {
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Uninstall()" );
+
+ // Acquire the mutex
+ iMutex.Wait();
+
+ TMainThreadParamsBuf params;
+ params().iProcessId = iProcessId;
+ iAnalyzeTool.MainThreadAlloctor( params );
+
+ // Release the mutex
+ iMutex.Signal();
+
+ // Check if this is shared allocator between threads
+ if ( iThreadArray.Count() > KThreadCount && !params().iAlone )
+ {
+ // Close the shared allocator
+ Close();
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Uninstall() - Close called" );
+ return;
+ }
+
+#if ( SYMBIAN_VERSION_SUPPORT >= SYMBIAN_3 )
+ #ifndef __WINS__
+ // Remove dummy Tls handle
+ UserSvr::DllFreeTls( KDummyHandle );
+ #endif
+#endif
+
+ // Since this is the last thread using this allocator it can be deleted
+ delete this;
+ }
+
+#ifdef __WINS__
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::Alloc() WINS version
+// Allocates a cell of specified size from the heap.
+// -----------------------------------------------------------------------------
+//
+UEXPORT_C TAny* RAnalyzeToolMainAllocator::Alloc( TInt aSize )
+ {
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Alloc()" );
+
+ // Acquire the mutex
+ iMutex.Wait();
+
+ // Alloc memory from the original allocator
+ TAny* p = iAllocator->Alloc( aSize );
+
+ LOGSTR3( "ATMH RAnalyzeToolMainAllocator::Alloc() - aSize: %i, address: %x",
+ aSize, (TUint32) p );
+
+ // Don't collect or log data if storage server not open or logging mode fast.
+ if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
+ {
+ TInt error( KErrNone );
+
+ // Check if eventhandler is started already
+ if ( !iEventHandler->IsStarted() )
+ {
+ // Install the eventhandler if needed
+ InstallEventHandler();
+ }
+
+ // Reset the callstack
+ iCallStack.Reset();
+
+ // If we don't want any call stack to be saved skip the next part
+ if( iAllocMaxCallStack > 0 )
+ {
+ // Find the current thread callstack start address
+ TUint32 stackstart( 0 );
+ TBool found( FindCurrentThreadStack( stackstart ) );
+ LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found );
+
+ // Returns the value of the stack pointer at the
+ // current point in your program.
+ TUint32 _sp;
+ __asm
+ {
+ mov [_sp], esp
+ }
+
+ // Get process loaded code segments count
+ TInt blocksCount( iCodeblocks.Count() );
+ TUint arrayCounter = 0;
+
+ // Iterate through callstack to find wanted callstack addresses
+ // - Start: current stack address
+ // - Stop: stack start address(Run-address of user stack)
+ // - Add: address length(The word size in the current system is 32 bits, which is 4 bytes)
+ for ( TUint32 i = _sp; i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
+ {
+ TUint32 addr = (TUint32) *( (TUint32*) i );
+
+ // Checks is the given address in loaded code memory area.
+ if ( !IsAddressLoadedCode( addr ) )
+ continue;
+
+ // Iterate through array of code blocks to check if address is in code segment area
+ for ( TInt j = 0; j < blocksCount; j++ )
+ {
+ // Checks if the given address is in this memory block area
+ if ( iCodeblocks[j].CheckAddress( addr ) )
+ {
+ // To avoid recursive call to ReAlloc specifying granularity
+ // Add address to the callstack
+ iCallStack[arrayCounter] = ( addr );
+ arrayCounter++;
+ break;
+ }
+ }
+
+ // Checks if the wanted callstack items are gathered
+ if ( arrayCounter == KATMaxCallstackLength ||
+ arrayCounter == iAllocMaxCallStack )
+ {
+ LOGSTR2( "ATMH > Wanted CallStack items ready( %i )", arrayCounter );
+ break;
+ }
+ }
+ }
+
+ // Log the memory allocation information
+ if ( iLogOption == EATLogToTraceFast )
+ {
+ // Using fast mode.
+ ATFastLogMemoryAllocated( iProcessId, (TUint32) p , iCallStack, aSize );
+ }
+ else
+ {
+ // Using storage server.
+ error = iStorageServer.LogMemoryAllocated( (TUint32) p,
+ iCallStack,
+ aSize );
+ if ( KErrNone != error )
+ {
+ switch ( error )
+ {
+ case KErrNoMemory:
+ {
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Alloc() - KErrNoMemory case" );
+ // Check if eventhandler is active
+ if ( iEventHandler->IsActive() )
+ {
+ // Cancel iEventHandler because not needed anymore
+ iEventHandler->Cancel();
+ }
+ if ( iStorageServerOpen )
+ {
+ // Close storage server
+ iStorageServerOpen = EFalse;
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Alloc() - close iStorageServer" );
+ iStorageServer.Close();
+ }
+ break;
+ }
+ default:
+ {
+ LOGSTR2( "ATMH LogMemoryAllocated error %i", error );
+ break;
+ }
+ }
+ }
+ }
+ }
+ // Release the mutex
+ iMutex.Signal();
+
+ return p;
+ }
+#else
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::Alloc() ARMV5 version
+// Allocates a cell of specified size from the heap.
+// -----------------------------------------------------------------------------
+//
+TAny* RAnalyzeToolMainAllocator::Alloc( TInt aSize )
+ {
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Alloc()" );
+
+ // acquire the mutex
+ iMutex.Wait();
+
+ // Alloc memory from the original allocator
+ TAny* p = iAllocator->Alloc( aSize );
+
+ LOGSTR3( "ATMH RAnalyzeToolMainAllocator::Alloc() - aSize: %i, address: %x",
+ aSize, (TUint32) p );
+
+ TInt error( KErrNone );
+
+ if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
+ {
+ // Check if eventhandler is active already
+ // IsActive might return false value if a tested software has created many
+ // threads which install own CActiveScheduler.
+ if ( !iEventHandler->IsStarted() )
+ {
+ // Install the eventhandler if needed
+ InstallEventHandler();
+ }
+
+ // Reset the callstack
+ iCallStack.Reset();
+
+ // If we don't want any call stack to be saved skip the next part
+ if( iAllocMaxCallStack > 0 )
+ {
+ // Find the current thread callstack start address
+ TUint32 stackstart( 0 );
+ TBool found( FindCurrentThreadStack( stackstart ) );
+ LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found );
+
+ // Get process loaded code segments count
+ TInt blocksCount( iCodeblocks.Count() );
+ TUint arrayCounter = 0;
+
+ // Iterate through callstack to find wanted callstack addresses
+ // - Start: current stack address(__current_sp(): Returns the value of the
+ // stack pointer at the current point in your program.)
+ // - Stop: stack start address(Run-address of user stack)
+ // - Add: address length(The word size in the current system is 32 bits, which is 4 bytes)
+ for ( TUint32 i = __current_sp(); i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
+ {
+ TUint32 addr = (TUint32) *( (TUint32*) i );
+
+ // Checks is the given address in loaded code memory area.
+ if ( !IsAddressLoadedCode( addr ) )
+ continue;
+
+ // Iterate through array of code blocks to check if address is in code segment area
+ for ( TInt j = 0; j < blocksCount; j++ )
+ {
+ // Checks if the given address is in this memory block area
+ if ( iCodeblocks[j].CheckAddress( addr ) )
+ {
+ // To avoid recursive call to ReAlloc specifying granularity
+ // Add address to the callstack
+ iCallStack[arrayCounter] = ( addr );
+ arrayCounter++;
+ break;
+ }
+ }
+
+ // Checks if the wanted callstack items are gathered
+ if ( arrayCounter == KATMaxCallstackLength ||
+ arrayCounter == iAllocMaxCallStack )
+ {
+ LOGSTR2( "ATMH > Wanted CallStack items ready( %i )", arrayCounter );
+ break;
+ }
+ }
+ }
+ // Log the memory allocation information
+ if ( iLogOption == EATLogToTraceFast )
+ {
+ // Using fast mode.
+ ATFastLogMemoryAllocated( iProcessId, (TUint32) p, iCallStack, aSize );
+ }
+ else
+ {
+ // Using storage server.
+ error = iStorageServer.LogMemoryAllocated( (TUint32) p,
+ iCallStack,
+ aSize );
+ if ( KErrNone != error )
+ {
+ switch ( error )
+ {
+ case KErrNoMemory:
+ {
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Alloc() - KErrNoMemory case" );
+ // Check if eventhandler is active
+ if ( iEventHandler->IsActive() )
+ {
+ // Cancel ieventhandler because not needed anymore
+ iEventHandler->Cancel();
+ }
+ if ( iStorageServerOpen )
+ {
+ // Close storage server
+ iStorageServerOpen = EFalse;
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Alloc() - close iStorageServer" );
+ iStorageServer.Close();
+ }
+ break;
+ }
+ default:
+ {
+ LOGSTR2( "ATMH LogMemoryAllocated error %i", error );
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // Release the mutex
+ iMutex.Signal();
+
+ // Return the allocatated memory
+ return p;
+ }
+#endif // __WINS__
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::Free()
+// Frees the allocated memory
+// -----------------------------------------------------------------------------
+//
+void RAnalyzeToolMainAllocator::Free( TAny* aPtr )
+ {
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Free()" );
+
+ // Acquire the mutex
+ iMutex.Wait();
+
+ if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
+ {
+ // Reset the callstack
+ iFreeCallStack.Reset();
+
+ // Check if trace logging mode
+ // Also if we don't want any call stack to be stored skip the next part
+ if ( (iLogOption == EATUseDefault || iLogOption == EATLogToTrace || iLogOption == EATLogToTraceFast )
+ && iFreeMaxCallStack > 0 )
+ {
+ // Find the current thread callstack start address
+ TUint32 stackstart( 0 );
+ TBool found( FindCurrentThreadStack( stackstart ) );
+ LOGSTR3( "ATMH > stackstart: %x , found = %i", stackstart, found );
+ TUint32 _sp;
+
+ // Returns the value of the stack pointer at the
+ // current point in your program.
+ #ifdef __WINS__
+ __asm
+ {
+ mov [_sp], esp
+ }
+ #else
+ _sp = __current_sp();
+ #endif
+
+ // Get process loaded code segments count
+ TInt blocksCount( iCodeblocks.Count() );
+ TUint arrayCounter = 0;
+
+ // Iterate through callstack to find wanted callstack addresses
+ // - Start: current stack address
+ // - Stop: stack start address(Run-address of user stack)
+ // - Add: address length(The word size in the current system is 32 bits, which is 4 bytes)
+ for ( TUint32 i = _sp; i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
+ {
+ TUint32 addr = (TUint32) *( (TUint32*) i );
+ // Checks is the given address in loaded code memory area.
+ if ( ! IsAddressLoadedCode( addr ) )
+ continue;
+
+ // Iterate through array of code blocks to check if address is in code segment area
+ for ( TInt j = 0; j < blocksCount; j++ )
+ {
+ // Checks if the given address is in this memory block area
+ if ( iCodeblocks[j].CheckAddress( addr ) )
+ {
+ // To avoid recursive call to ReAlloc specifying granularity
+ // Add address to the callstack
+ iFreeCallStack[arrayCounter] = addr;
+ arrayCounter++;
+ break;
+ }
+ }
+ // Checks if the wanted callstack items are gathered
+ if ( arrayCounter == KATMaxFreeCallstackLength ||
+ arrayCounter == iFreeMaxCallStack )
+ {
+ break;
+ }
+ }
+ LOGSTR2( "ATMH > iFreeCallStack count ( %i )", arrayCounter );
+ }
+ // Log the memory free information.
+ if ( iLogOption == EATLogToTraceFast )
+ {
+ // Using fast mode.
+ ATFastLogMemoryFreed( iProcessId, (TUint32) aPtr, iFreeCallStack );
+ }
+ else
+ {
+ // Using storage server.
+ TInt err( iStorageServer.LogMemoryFreed( (TUint32) aPtr, iFreeCallStack ) );
+ if ( err != KErrNone )
+ {
+ LOGSTR2( "ATMH > LogMemoryFreed err( %i )", err );
+ }
+ }
+ }
+
+ // Free the memory using original allocator
+ iAllocator->Free( aPtr );
+
+ LOGSTR2( "ATMH RAnalyzeToolMainAllocator::Free() - aPtr: %x", (TUint32)aPtr );
+
+ // Release the mutex
+ iMutex.Signal();
+ }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::Open()
+// Opens this heap for shared access. Opening the heap increases
+// the heap's access count by one.
+// -----------------------------------------------------------------------------
+//
+TInt RAnalyzeToolMainAllocator::Open()
+ {
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Open() " );
+
+ // Acquire the mutex
+ iMutex.Wait();
+
+ // Share the memory using original allocator
+ TInt error = iAllocator->Open();
+
+ // If everything is OK add thread to the array which use this allocator
+ if ( KErrNone == error )
+ {
+ TThreadParamsBuf params;
+ params().iThreadId = RThread().Id().operator TUint();
+ error = iAnalyzeTool.ThreadStack( params );
+
+ __ASSERT_ALWAYS( KErrNone == error, AssertPanic( ECantAppendToTheArray ) );
+
+ if ( KErrNone == error )
+ {
+ LOGSTR2( "ATMH Thread stack address: %x", params().iStackAddress );
+ LOGSTR2( "ATMH Thread stack size: %x", params().iStackSize );
+ iThreadArray.Append( TThreadStack( RThread().Id(),
+ params().iStackAddress + params().iStackSize ) );
+ }
+ }
+
+ // Release the mutex
+ iMutex.Signal();
+
+ // Return the error code
+ return error;
+ }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::Close()
+// Closes this shared heap. Closing the heap decreases the heap's
+// access count by one.
+// -----------------------------------------------------------------------------
+//
+void RAnalyzeToolMainAllocator::Close()
+ {
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Close()" );
+
+ // Acquire the mutex
+ iMutex.Wait();
+
+ // Close the memory using original allocator
+ iAllocator->Close();
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Close() - allocator closed" );
+ TInt count = iThreadArray.Count();
+
+ // Iterate through array of threads to remove current thread
+ for ( TInt i = 0; i < count; i++ )
+ {
+ // Check if this is current thread
+ if ( iThreadArray[ i ].Match() )
+ {
+ // Remove the thread
+ iThreadArray.Remove( i );
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Close() - thread removed" );
+ break;
+ }
+ }
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Close() - about to mutex signal" );
+ // Release the mutex
+ iMutex.Signal();
+ }
+
+#ifdef __WINS__
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::ReAlloc()
+// Increases or decreases the size of an existing cell.
+// -----------------------------------------------------------------------------
+//
+TAny* RAnalyzeToolMainAllocator::ReAlloc( TAny* aPtr, TInt aSize, TInt aMode )
+ {
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::ReAlloc()" );
+
+ // Acquire the mutex
+ iMutex.Wait();
+
+ // Realloc the memory using original allocator
+ TAny* ptr = iAllocator->ReAlloc( aPtr, aSize, aMode );
+
+ // NULL addresses are not in a process under test
+ if ( ptr && !( aMode & ENeverMove ) )
+ {
+ LOGSTR3( "ATMH RAnalyzeToolMainAllocator::ReAlloc() - aPtr: %x, ptr: %x",
+ (TUint32)aPtr, (TUint32)ptr );
+ LOGSTR3( "ATMH RAnalyzeToolMainAllocator::ReAlloc() - aSize: %i, aMode: %i",
+ aSize, aMode );
+
+ // Don't collect or log data if storage server not open or logging mode is not fast.
+ if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
+ {
+ TInt error( KErrNone );
+ TUint arrayCounter = 0;
+
+ // Reset the callstack
+ iReCallStack.Reset();
+
+ // If we don't want any call stack to be saved skip the next part
+ if( iAllocMaxCallStack > 0 )
+ {
+ // Find the current thread callstack start address
+ TUint32 stackstart( 0 );
+ TBool found( FindCurrentThreadStack( stackstart ) );
+ LOGSTR3( "ATMH > stackstart: %x , find = %i", stackstart, found );
+
+ // Returns the value of the stack pointer at the
+ // current point in your program.
+ TUint32 _sp( 0 );
+ __asm
+ {
+ mov [_sp], esp
+ }
+
+ // Get process loaded code segments count
+ TInt blocksCount( iCodeblocks.Count() );
+
+ // Iterate through callstack to find wanted callstack addresses
+ // - Start: current stack address
+ // - Stop: stack start address(Run-address of user stack)
+ // - Add: address length(The word size in the current system is 32 bits, which is 4 bytes)
+ for ( TUint32 i = _sp; i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
+ {
+ TUint32 addr = (TUint32) *( (TUint32*) i );
+ // Checks is the given address in loaded code memory area.
+ if ( ! IsAddressLoadedCode( addr ) )
+ continue;
+
+ // Iterate through array of code blocks to check if address is in code segment area
+ for ( TInt j = 0; j < blocksCount; j++ )
+ {
+ // Checks if the given address is in this memory block area
+ if ( iCodeblocks[j].CheckAddress( addr ) )
+ {
+ // To avoid recursive call to ReAlloc specifying granularity
+ // Add address to the callstack
+ iReCallStack[arrayCounter] = addr;
+ arrayCounter++;
+ break;
+ }
+ }
+ // Checks if the wanted callstack items are gathered
+ if ( arrayCounter == KATMaxCallstackLength ||
+ arrayCounter == iAllocMaxCallStack )
+ {
+ LOGSTR2( "ATMH > Wanted CallStack items ready( %i )", arrayCounter );
+ break;
+ }
+ }
+ }
+
+ // No need to report free if the aPtr was NULL
+ if ( aPtr != NULL )
+ {
+ // Reset the free callstack
+ iFreeCallStack.Reset();
+
+ // Check that logging mode is trace/trace fast so we use free call stack
+ // and call stack size bigger than zero
+ if ( ( iLogOption == EATUseDefault || iLogOption == EATLogToTrace || iLogOption == EATLogToTraceFast ) && iFreeMaxCallStack > 0 )
+ {
+ for ( TInt i = 0; i < arrayCounter; i++ )
+ {
+ if ( i == KATMaxFreeCallstackLength || i == iFreeMaxCallStack )
+ {
+ break;
+ }
+ iFreeCallStack[i] = iReCallStack[i];
+ }
+ }
+ // Try to remove old address from the storage server's
+ // leak array. If found. it's removed from the array because system frees
+ // old address directly in the RHeap in ReAlloc case.
+ if ( iLogOption == EATLogToTraceFast )
+ {
+ ATFastLogMemoryFreed( iProcessId, (TUint32) aPtr, iFreeCallStack );
+ }
+ else
+ {
+ iStorageServer.LogMemoryFreed( (TUint32) aPtr, iFreeCallStack );
+ }
+ }
+ // Log the memory allocation information
+ if ( iLogOption == EATLogToTraceFast )
+ {
+ // Using fast logging mode.
+ ATFastLogMemoryAllocated( iProcessId, (TUint32) ptr, iReCallStack, aSize );
+ }
+ else
+ {
+ // Using storage server.
+ error = iStorageServer.LogMemoryAllocated( (TUint32) ptr,
+ iReCallStack,
+ aSize );
+ if ( KErrNone != error )
+ {
+ switch ( error )
+ {
+ case KErrNoMemory:
+ {
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::ReAlloc() - KErrNoMemory case" );
+ // Check if eventhandler is active
+ if ( iEventHandler->IsActive() )
+ {
+ // Cancel iEventHandler because not needed anymore
+ iEventHandler->Cancel();
+ }
+ if ( iStorageServerOpen )
+ {
+ // Close storage server
+ iStorageServerOpen = EFalse;
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::ReAlloc() - close iStorageServer" );
+ iStorageServer.Close();
+ }
+ break;
+ }
+ default:
+ {
+ LOGSTR2( "ATMH LogMemoryAllocated error %i", error );
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Release the mutex
+ iMutex.Signal();
+
+ // Return pointer to the reallocated cell
+ return ptr;
+ }
+
+#else
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::ReAlloc()
+// Increases or decreases the size of an existing cell.
+// -----------------------------------------------------------------------------
+//
+TAny* RAnalyzeToolMainAllocator::ReAlloc( TAny* aPtr, TInt aSize, TInt aMode )
+ {
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::ReAlloc()" );
+
+ // Acquire the mutex
+ iMutex.Wait();
+
+ // Realloc the memory using original allocator
+ TAny* ptr = iAllocator->ReAlloc( aPtr, aSize, aMode );
+
+ TInt error( KErrNone );
+ TUint arrayCounter = 0;
+
+ // NULL addresses are not in a process under test
+ if ( ptr && !( aMode & ENeverMove ) )
+ {
+ LOGSTR3( "ATMH RAnalyzeToolMainAllocator::ReAlloc() - aPtr: %x, ptr: %x",
+ (TUint32)aPtr, (TUint32)ptr );
+ LOGSTR3( "ATMH RAnalyzeToolMainAllocator::ReAlloc() - aSize: %i, aMode: %i",
+ aSize, aMode );
+
+ // Don't collect or log data if storage server not open or logging mode is not fast.
+ if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
+ {
+ // Reset the callstack
+ iReCallStack.Reset();
+
+ // If we don't want any call stack to be saved skip the next part
+ if( iAllocMaxCallStack > 0 )
+ {
+ // Find the current thread callstack start address
+ TUint32 stackstart( 0 );
+ TBool found( FindCurrentThreadStack( stackstart ) );
+ LOGSTR3( "ATMH > stackstart: %x , find = %i", stackstart, found );
+
+ // Get process loaded code segments count
+ TInt blocksCount( iCodeblocks.Count() );
+
+ // Iterate through callstack to find wanted callstack addresses
+ // - Start: current stack address(__current_sp(): Returns the value of the
+ // stack pointer at the current point in your program.)
+ // - Stop: stack start address(Run-address of user stack)
+ // - Add: address length(The word size in the current system is 32 bits, which is 4 bytes)
+ for ( TUint32 i = __current_sp(); i < stackstart; i = i + KAddressLength )//lint !e1055 !e526 !e628 !e348
+ {
+ TUint32 addr = (TUint32) *( (TUint32*) i );
+
+ // Checks is the given address in loaded code memory area.
+ if ( !IsAddressLoadedCode( addr ) )
+ continue;
+
+ // Iterate through array of code blocks to check if address is in code segment area
+ for ( TInt j = 0; j < blocksCount; j++ )
+ {
+ // Checks if the given address is in this memory block area
+ if ( iCodeblocks[j].CheckAddress( addr ) )
+ {
+ // To avoid recursive call to ReAlloc specifying granularity
+ // Add address to the callstack
+ iReCallStack[arrayCounter] = ( addr );
+ arrayCounter++;
+ break;
+ }
+ }
+ // Checks if the wanted callstack items are gathered
+ if ( arrayCounter == KATMaxCallstackLength ||
+ arrayCounter == iAllocMaxCallStack )
+ {
+ LOGSTR2( "ATMH > Wanted CallStack items ready( %i )", arrayCounter );
+ break;
+ }
+ }
+ }
+
+ // No need to report free if the aPtr was NULL
+ if ( aPtr != NULL )
+ {
+ // Reset the free callstack
+ iFreeCallStack.Reset();
+
+ // Check that logging mode is trace/trace fast so we use free call stack
+ // and call stack size bigger than zero
+ if ( (iLogOption == EATUseDefault || iLogOption == EATLogToTrace || iLogOption == EATLogToTraceFast )
+ && iFreeMaxCallStack > 0 )
+ {
+ for ( TInt i = 0; i < arrayCounter; i++ )
+ {
+ if ( i == KATMaxFreeCallstackLength || i == iFreeMaxCallStack )
+ {
+ break;
+ }
+ iFreeCallStack[i] = ( iReCallStack[i] );
+ }
+ }
+
+ // Try to remove old address from the storage server's
+ // leak array. If found. it's removed from the array because system frees
+ // old address directly in the RHeap in ReAlloc case.
+ if ( iLogOption == EATLogToTraceFast )
+ {
+ ATFastLogMemoryFreed( iProcessId, (TUint32) aPtr, iFreeCallStack );
+ }
+ else
+ {
+ iStorageServer.LogMemoryFreed( (TUint32) aPtr, iFreeCallStack );
+ }
+ }
+
+ // Log the memory allocation information
+ if ( iLogOption == EATLogToTraceFast )
+ {
+ // Using fast logging mode.
+ ATFastLogMemoryAllocated( iProcessId, (TUint32) ptr, iReCallStack, aSize );
+ }
+ else
+ {
+ // Using storage server.
+ error = iStorageServer.LogMemoryAllocated( (TUint32) ptr,
+ iReCallStack,
+ aSize );
+ if ( KErrNone != error )
+ {
+ switch ( error )
+ {
+ case KErrNoMemory:
+ {
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::ReAlloc() - KErrNoMemory case" );
+ // Check if eventhandler is active
+ if ( iEventHandler->IsActive() )
+ {
+ // Cancel iEventHandler because not needed anymore
+ iEventHandler->Cancel();
+ }
+ if ( iStorageServerOpen )
+ {
+ // Close storage server
+ iStorageServerOpen = EFalse;
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::ReAlloc() - close iStorageServer" );
+ iStorageServer.Close();
+ }
+ break;
+ }
+ default:
+ {
+ LOGSTR2( "ATMH LogMemoryAllocated error %i", error );
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Release the mutex
+ iMutex.Signal();
+
+ // Return pointer to the reallocated cell
+ return ptr;
+ }
+
+#endif // __WINS__
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::Compress()
+// The function frees excess committed space from the top of the heap.
+// The size of the heap is never reduced below the minimum size
+// specified during creation of the heap.
+// -----------------------------------------------------------------------------
+//
+TInt RAnalyzeToolMainAllocator::Compress()
+ {
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Compress()" );
+
+ // Acquire the mutex
+ iMutex.Wait();
+
+ // Compress the memory using original allocator
+ TInt compress = iAllocator->Compress();
+
+ // Release the mutex
+ iMutex.Signal();
+
+ // Return the space reclaimed
+ return compress;
+ }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::Reset()
+// Frees all allocated cells on this heap.
+// -----------------------------------------------------------------------------
+//
+void RAnalyzeToolMainAllocator::Reset()
+ {
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Reset()" );
+
+ // Acquire the mutex
+ iMutex.Wait();
+
+ // Reset the memory using original allocator
+ iAllocator->Reset();
+
+ // Release the mutex
+ iMutex.Signal();
+ }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::AllocSize()
+// Gets the number of cells allocated on this heap, and
+// the total space allocated to them.
+// -----------------------------------------------------------------------------
+//
+TInt RAnalyzeToolMainAllocator::AllocSize( TInt& aTotalAllocSize ) const
+ {
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::AllocSize()" );
+
+ // Acquire the mutex
+ iMutex.Wait();
+
+ // Acquire the memory information using original allocator
+ TInt size = iAllocator->AllocSize( aTotalAllocSize );
+
+ // Release the mutex
+ iMutex.Signal();
+
+ // Return the number of cells allocated on this heap.
+ return size;
+ }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::Available()
+// Gets the total free space currently available on the heap and the
+// space available in the largest free block. The space available
+// represents the total space which can be allocated. Note that
+// compressing the heap may reduce the total free space available
+// and the space available in the largest free block.
+// -----------------------------------------------------------------------------
+//
+TInt RAnalyzeToolMainAllocator::Available( TInt& aBiggestBlock ) const
+ {
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Available()" );
+
+ // Acquire the mutex
+ iMutex.Wait();
+
+ // Acquire the memory information using original allocator
+ TInt available = iAllocator->Available( aBiggestBlock );
+
+ // Release the mutex
+ iMutex.Signal();
+
+ // Return the total free space currently available on the heap
+ return available;
+ }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::AllocLen()
+// Gets the length of the available space in the specified
+// allocated cell.
+// -----------------------------------------------------------------------------
+//
+TInt RAnalyzeToolMainAllocator::AllocLen( const TAny* aCell ) const
+ {
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::AllocLen()" );
+
+ // Acquire the mutex
+ iMutex.Wait();
+
+ // Acquire the memory information using original allocator
+ TInt len = iAllocator->AllocLen( aCell );
+
+ // Release the mutex
+ iMutex.Signal();
+
+ // Return the length of the available space in the allocated cell.
+ return len;
+ }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::DebugFunction()
+// Invocates specified debug funtionality.
+// -----------------------------------------------------------------------------
+//
+TInt RAnalyzeToolMainAllocator::DebugFunction( TInt aFunc, TAny* a1, TAny* a2 )
+ {
+ LOGSTR2( "ATMH RAnalyzeToolMainAllocator::DebugFunction() %i", aFunc );
+
+ // Acquire the mutex
+ iMutex.Wait();
+
+ // Invocate debug funtion using original allocator
+ TInt debug = iAllocator->DebugFunction( aFunc, a1, a2 );
+
+ switch( aFunc )
+ {
+ case EMarkEnd:
+ {
+ // Disables the __UHEAP_MARKEND macro
+ LOGSTR1( "ATMH __UHEAP_MARKEND macro called" );
+ if ( debug > 0 )
+ {
+ LOGSTR2( "ATMH __UHEAP_MARKEND detects leaks: %d", debug );
+ // Because there is leaks the alloc panic will occur but
+ // lets return a zero to pretend that everything is OK
+ debug = 0;
+ }
+ }
+ break;
+
+ default:
+ {
+ }
+ break;
+ }
+
+ // Release the mutex
+ iMutex.Signal();
+
+ // Return information of the debug function success
+ return debug;
+ }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::RemoveKilledThread()
+// Remove killed thread from threads array.
+// -----------------------------------------------------------------------------
+//
+void RAnalyzeToolMainAllocator::RemoveKilledThread( const TUint aThreadId )
+ {
+ LOGSTR2( "ATMH RAnalyzeToolMainAllocator::RemoveKilledThread(%i)",
+ aThreadId );
+
+ // Acquire the mutex
+ iMutex.Wait();
+
+ // Iterate through array of threads to remove current thread
+ TInt count( iThreadArray.Count() );
+ LOGSTR2( "ATMH > iThreadArray.Count() %i", count );
+
+ for ( TInt i = 0; i < count; i++ )
+ {
+ // Check if this is current thread
+ if ( iThreadArray[ i ].Match( aThreadId ) )
+ {
+ // Remove the thread
+ iThreadArray.Remove( i );
+ LOGSTR1( "ATMH > thread removed" );
+ break;
+ }
+ }
+
+ // Release the mutex
+ iMutex.Signal();
+ }
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::Extension_()
+// Extension function
+// -----------------------------------------------------------------------------
+//
+TInt RAnalyzeToolMainAllocator::Extension_( TUint aExtensionId, TAny*& a0,
+ TAny* a1)
+ {
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::Extension_()" );
+
+ // Acquire the mutex
+ iMutex.Wait();
+
+ // Invocate extension funtion using original allocator
+ TInt ext = RAllocator::Extension_( aExtensionId, a0, a1 );
+
+ // Release the mutex
+ iMutex.Signal();
+
+ // Return information of the extension function success
+ return ext;
+ }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::LogProcessInformation()
+// Retrieve and log the process initial information
+// -----------------------------------------------------------------------------
+//
+void RAnalyzeToolMainAllocator::LogProcessInformation( const TFileName aFileName,
+ TUint32 aLogOption, TUint32 aIsDebug )
+ {
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::LogProcessInformation()" );
+
+ // Create local variable and retrieve the process information
+ TProcessIdentityParamsBuf params;
+ params().iProcessId = iProcessId;
+ params().iThreadId = RThread().Id().operator TUint();
+ TInt error = iAnalyzeTool.GetProcessInfo( params );
+
+ LOGSTR2( "ATMH GetProcessInfo %i error", error );
+
+ if ( KErrNone == error )
+ {
+ LOGSTR2( "ATMH Process %i", iProcessId );
+
+ // Store stack start address
+ LOGSTR2( "ATMH Thread stack address: %x", params().iStackAddress );
+ LOGSTR2( "ATMH Thread stack size: %x", params().iStackSize );
+
+ // Append thread to array of the users of this allocator
+ error = iThreadArray.Append(
+ TThreadStack( RThread().Id(), params().iStackAddress + params().iStackSize) );
+
+ __ASSERT_ALWAYS( KErrNone == error, AssertPanic( ECantAppendToTheArray ) );
+
+ // Log process information
+ if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
+ {
+ if ( iLogOption == EATLogToTraceFast )
+ {
+ // Using fast logging mode.
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::LogProcessInformation() - ATFastLogProcessStarted() #1" );
+ ATFastLogProcessStarted( params().iProcessName, iProcessId, aIsDebug );
+ }
+ else
+ {
+ // Using storage server.
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::LogProcessInformation() - iStorageServerOpen #1" );
+ error = iStorageServer.LogProcessStarted(
+ aFileName,
+ params().iProcessName,
+ iProcessId,
+ aLogOption,
+ aIsDebug );
+ }
+ }
+
+ LOGSTR2( "ATMH LogProcessStarted error %i", error );
+
+ // Iterate through process codesegments
+ for( TInt i = 0; i < params().iCodesegCount; i++ )
+ {
+ // Create local variable and retrieve codesegment info
+ TCodesegInfoBuf codeinfo;
+ codeinfo().iProcessId = iProcessId;
+ codeinfo().iIndex = i;
+ error = iAnalyzeTool.GetCodesegInfo( codeinfo );
+
+ LOGSTR2( "ATMH GetCodesegInfo error %i", error );
+ if ( KErrNone == error )
+ {
+ // Don't log AnalyzeTool libraries
+ if ( 0 != codeinfo().iFullName.CompareC( KMemoryHook ) &&
+ 0 != codeinfo().iFullName.CompareC( KStorageServer ) )
+ {
+ // Log the loaded codesegment(s)
+ if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
+ {
+ if ( iLogOption == EATLogToTraceFast )
+ {
+ // Using fast logging mode.
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::LogProcessInformation() - ATFastLogDllLoaded() #2" );
+ ATFastLogDllLoaded( iProcessId,
+ codeinfo().iFullName,
+ codeinfo().iRunAddress,
+ codeinfo().iRunAddress + codeinfo().iSize );
+ }
+ else
+ {
+ // Using storage server.
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::LogProcessInformation() - iStorageServerOpen #2" );
+ error = iStorageServer.LogDllLoaded(
+ codeinfo().iFullName,
+ codeinfo().iRunAddress,
+ codeinfo().iRunAddress + codeinfo().iSize );
+ }
+ }
+
+ LOGSTR2( "ATMH LogDllLoaded error %i", error );
+
+ // Check that everything is OK
+ if ( KErrNone == error )
+ {
+ // Append the codesegment to the array
+ error = iCodeblocks.Append(
+ TCodeblock( codeinfo().iRunAddress,
+ codeinfo().iSize,
+ codeinfo().iFullName ) );
+ LOGSTR2( "ATMH Append error %i", error );
+ }
+ }
+ }
+ }
+
+ // Iterate through process dynamic codesegments
+ for ( TInt i = 0; i < params().iDynamicCount; i++ )
+ {
+ // Create local variable and retrieve codesegment info
+ TLibraryInfoBuf info;
+ info().iProcessId = iProcessId;
+ info().iIndex = i;
+ error = iAnalyzeTool.GetLibraryInfo( info );
+ LOGSTR2( "ATMH GetLibraryInfo error %i", error );
+ if ( KErrNone == error )
+ {
+ // Log the loaded dynamic codesegment(s)
+ if ( iStorageServerOpen || iLogOption == EATLogToTraceFast )
+ {
+ if ( iLogOption == EATLogToTraceFast )
+ {
+ // Using fast logging mode.
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::LogProcessInformation() - - ATFastLogDllLoaded()#3" );
+ ATFastLogDllLoaded( iProcessId,
+ info().iLibraryName,
+ info().iRunAddress,
+ info().iRunAddress + info().iSize );
+ }
+ else
+ {
+ // Using storage server.
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::LogProcessInformation() - iStorageServerOpen #3" );
+ error = iStorageServer.LogDllLoaded(
+ info().iLibraryName,
+ info().iRunAddress,
+ info().iRunAddress + info().iSize );
+ }
+ }
+
+
+ LOGSTR2( "ATMH LogDllLoaded error %i", error );
+
+ if ( KErrNone == error )
+ {
+ // Append the codesegment to the array
+ error = iCodeblocks.Append(
+ TCodeblock( info().iRunAddress,
+ info().iSize, info().iLibraryName ) );
+ LOGSTR2( "ATMH Append error %i", error );
+ }
+ }
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::FindCurrentThreadStack()
+// Find the current thread which is using the heap
+// -----------------------------------------------------------------------------
+//
+TBool RAnalyzeToolMainAllocator::FindCurrentThreadStack( TUint32& aStackStart )
+ {
+ LOGSTR2( "ATMH RAnalyzeToolMainAllocator::FindCurrentThreadStack(), count( %i )",
+ iThreadArray.Count() );
+
+ // Flag for indicating that right thread has been found
+ TBool found( EFalse );
+ // If threre is only one thread it must be the right thread
+ if ( iThreadArray.Count() == KThreadCount )
+ {
+ if ( !iThreadArray[ 0 ].ThreadStackStart( aStackStart ) )
+ {
+ // This MUST BE the right thread
+ //__ASSERT_ALWAYS( EFalse, AssertPanic( ECantFindRightThread ) );
+ }
+ else if ( iThreadArray[ 0 ].ThreadStackStart( aStackStart ) )
+ {
+ found = ETrue;
+ }
+ }
+ else
+ {
+ // Iterate through array to find right thread
+ TInt count = iThreadArray.Count();
+
+ for ( TInt i = 0; i < count; i++ )
+ {
+ // Check if this is the right thread
+ if ( iThreadArray[ i ].ThreadStackStart( aStackStart ) )
+ {
+ // Right thread found. Mark the flag
+ found = ETrue;
+ break;
+ }
+ }
+ // If right thread was not found the panic must be raised
+ if ( !found )
+ {
+ //__ASSERT_ALWAYS( EFalse, AssertPanic( ECantFindRightThread ) );
+ }
+ }
+ return found;
+ }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMainAllocator::InstallEventHandler()
+// Installs the eventhandler, if possible
+// -----------------------------------------------------------------------------
+//
+void RAnalyzeToolMainAllocator::InstallEventHandler()
+ {
+ LOGSTR1( "ATMH RAnalyzeToolMainAllocator::InstallEventHandler()" );
+
+ // Active eventhalder is not active, trying to start it
+ if ( NULL != CActiveScheduler::Current() )
+ {
+ iEventHandler->Start();
+ }
+ }
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/src/analyzetoolmemoryallocator.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,71 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Definitions for the class RAnalyzeToolMemoryAllocator.
+*
+*/
+
+
+#include "analyzetoolmemoryallocator.h"
+#include "analyzetoolpanics.pan"
+#include "atlog.h"
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMemoryAllocator::RAnalyzeToolMemoryAllocator()
+// C++ default constructor.
+// -----------------------------------------------------------------------------
+//
+RAnalyzeToolMemoryAllocator::RAnalyzeToolMemoryAllocator( TBool aNotFirst ) :
+ RAllocator(),
+ iNotFirst( aNotFirst )/*,
+ iStorageServerOpen( EFalse )*/
+ {
+ LOGSTR1( "ATMH RAnalyzeToolMemoryAllocator::RAnalyzeToolMemoryAllocator()" );
+
+ // Acquire the original allocator
+ iAllocator = &User::Allocator();
+
+ // Set memory model zero
+ iMemoryModel = 0;
+ }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMemoryAllocator::~RAnalyzeToolMemoryAllocator()
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+RAnalyzeToolMemoryAllocator::~RAnalyzeToolMemoryAllocator()
+ {
+ LOGSTR1( "ATMH RAnalyzeToolMemoryAllocator::~RAnalyzeToolMemoryAllocator()" );
+
+ // Call switching orinigal allocator back.
+ // Just in case, if uninstall was not called.
+ SwitchOriginalAllocator();
+ }
+
+// -----------------------------------------------------------------------------
+// RAnalyzeToolMemoryAllocator::SwitchOriginalAllocator()
+// Switches original allocator in use if not already.
+// -----------------------------------------------------------------------------
+//
+void RAnalyzeToolMemoryAllocator::SwitchOriginalAllocator()
+ {
+ LOGSTR1( "ATMH RAnalyzeToolMemoryAllocator::SwitchOriginalAllocator()" );
+
+ if ( iAllocator != &User::Allocator() )
+ {
+ User::SwitchAllocator( iAllocator );
+ }
+ }
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/src/codeblock.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,62 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Definitions for the class TCodeblock.
+*
+*/
+
+
+#include "codeblock.h"
+#include "atlog.h"
+
+// -----------------------------------------------------------------------------
+// TCodeblock::TCodeblock
+// C++ default constructor.
+// -----------------------------------------------------------------------------
+//
+TCodeblock::TCodeblock( TLinAddr aRunAddress,
+ TUint32 aSize,
+ TBuf8<KMaxLibraryName>& aName ) :
+ iStartAddress( aRunAddress ),
+ iEndAddress( aRunAddress + aSize )
+ {
+ LOGSTR3( "ATMH TCodeblock::TCodeblock() %x - %x", iStartAddress, iEndAddress );
+ iName.Copy( aName );
+ }
+
+// -----------------------------------------------------------------------------
+// TCodeblock::CheckAddress
+// Checks if the given address is in this memory block area
+// -----------------------------------------------------------------------------
+//
+TBool TCodeblock::CheckAddress( TUint32 aAddress )
+ {
+ if ( iStartAddress <= aAddress && aAddress <= iEndAddress )
+ {
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// TCodeblock::Match
+// Matches if the given parameters represents this memory block
+// -----------------------------------------------------------------------------
+//
+TBool TCodeblock::Match( TBuf8<KMaxLibraryName>& aName )
+ {
+ LOGSTR1( "ATMH TCodeblock::Match()" );
+ return ( 0 == iName.CompareF( aName ) ) ? ETrue : EFalse;
+ }
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/src/customuser.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,518 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Definitions for the class CustomUser.
+*
+*/
+
+#include <f32file.h>
+#include <utf.h>
+#include "customuser.h"
+#include "analyzetoolmainallocator.h"
+#include "analyzetoolallocator.h"
+#include "atlog.h"
+#include "analyzetoolmemoryallocator.h"
+#include "analyzetoolpanics.pan"
+#include "atstorageservercommon.h"
+#include "atdriveinfo.h"
+#include <analyzetool/analyzetooltraceconstants.h>
+
+#ifdef USE_CLEANER_DLL
+// Global variable to detect dll attach & detach in process.
+// Note! This is initialized after SetupThreadHeap so its not usable there.
+// This is used to store the main thread id and track when the process ends
+// to load the cleaner dll with call back feature to cleanup allocator at the
+// last possible phase.
+#include <analyzetool/analyzetoolcleaner.h>
+
+// CONSTANTS
+const TInt KAToolCleanerOrdinal = 1;
+
+class TAnalyzeToolGlobalTracker : public TAnalyzeToolCleanerBase
+ {
+public:
+ /* Main thread id */
+ TThreadId iMainId;
+
+ /* Inform if panic occured */
+ TBool iPanic;
+
+ // -----------------------------------------------------------------------------
+ // TAnalyzeToolGlobalTracker::TAnalyzeToolGlobalTracker()
+ // C++ default constructor
+ // -----------------------------------------------------------------------------
+ //
+ TAnalyzeToolGlobalTracker()
+ {
+ LOGSTR1( "ATMH TAnalyzeToolGlobalTracker::TAnalyzeToolGlobalTracker()" );
+
+ iPanic = EFalse; // no panic occured
+ iMainId = RThread().Id(); // set main thread id
+ LOGSTR2( "ATMH TAnalyzeToolGlobalTracker() > Main id set: %d",
+ iMainId.operator TUint() );
+ }
+
+ // -----------------------------------------------------------------------------
+ // TAnalyzeToolGlobalTracker::~TAnalyzeToolGlobalTracker()
+ // Destructor.
+ // -----------------------------------------------------------------------------
+ //
+ ~TAnalyzeToolGlobalTracker()
+ {
+ LOGSTR1( "ATMH TAnalyzeToolGlobalTracker::~TAnalyzeToolGlobalTracker()" );
+
+ // We dont load dll if panic has happened (uninstallation has been done).
+ if ( iPanic )
+ {
+ LOGSTR1( "ATMH ~TAnalyzeToolGlobalTracker > Panic set not loading cleaner dll." );
+ return;
+ }
+
+ LOGSTR1( "ATMH ~TAnalyzeToolGlobalTracker > about to load cleaner dll" );
+ // Load cleaner library and set a call back to our cleanup
+ RLibrary lib;
+ TInt error( lib.Load( KATCleanerDllName ) );
+ if ( error == KErrNone )
+ {
+ // Set address to point to ourself
+ TLibraryFunction func = lib.Lookup( KAToolCleanerOrdinal ); // Ordinal 1 of the dll
+ ATCLEANERTABLE* cleaner = (ATCLEANERTABLE*) func(); // Use function to get address
+ cleaner->At( 0 ) = (TUint32) this; // Set address
+ LOGSTR1( "ATMH ~TAnalyzeToolGlobalTracker() > cleaner dll loaded and call back set" );
+ }
+ else
+ {
+ // Error loading cleanup dll
+ LOGSTR2( "ATMH ~TAnalyzeToolGlobalTracker() > cleaner dll load error(%i) uninstalling allocator now!",
+ error );
+ Cleanup();
+ }
+ }
+
+ // -----------------------------------------------------------------------------
+ // TAnalyzeToolGlobalTracker::Cleanup()
+ //
+ // -----------------------------------------------------------------------------
+ //
+ void Cleanup()
+ {
+ LOGSTR1( "ATMH TAnalyzeToolGlobalTracker::Cleanup() - allocator uninstall" );
+
+ // Uninstall allocator
+ ( (RAnalyzeToolMemoryAllocator&) User::Allocator() ).Uninstall();
+ }
+
+ };
+
+// Global variable definition.
+TAnalyzeToolGlobalTracker gGlobalTracker;
+#endif
+
+// CONSTANTS
+// When needed, update the version number directly inside _LIT macro.
+// Constant for the atool API(staticlib) version.
+_LIT( KAtoolApiVersion, "1.7.5" );
+
+// Version number buffer length
+const TInt KAtoolVersionNumberLength = 10;
+
+// Wrong version error code
+const TInt KAtoolVersionError = -1999;
+
+// Version number separator
+_LIT( KVersionSeparator, ";" );
+
+// Incorrect version error strings
+_LIT( KIncorrectText, "ERROR_OCCURED INCORRECT_ATOOL_VERSION [API v.%S][ATOOL v.%S]" );
+_LIT( KIncorrectTextTrace, "PCSS " );
+
+// -----------------------------------------------------------------------------
+// CustomUser::Panic()
+// Overloaded User::Panic() function
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CustomUser::Panic( const TDesC& aCategory, TInt aReason )
+ {
+ LOGSTR3( "ATMH CustomUser::Panic() %S %i", &aCategory, aReason );
+
+#ifdef USE_CLEANER_DLL
+ // Set global tracker that panic has happened.
+ gGlobalTracker.iPanic = ETrue;
+#endif
+
+ // Uninstall thread's RAllocator
+ ( (RAnalyzeToolMemoryAllocator&) User::Allocator() ).Uninstall();
+
+ // Call the "real" User::Panic()
+ User::Panic( aCategory, aReason );
+ }
+
+// -----------------------------------------------------------------------------
+// CustomUser::Exit()
+// Overloaded User::Exit() function
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CustomUser::Exit( TInt aReason )
+ {
+ LOGSTR3( "ATMH CustomUser::Exit() %i %i", aReason, RThread().Id().Id() );
+
+ if ( aReason != KAtoolVersionError )
+ {
+#ifdef USE_CLEANER_DLL
+ // Only uninstall allocator if its not the process main/first thread.
+ LOGSTR3( "ATMH CustomUser::Exit() - Thread id: %d - Main Id: %d",
+ RThread().Id().operator TUint(), gGlobalTracker.iMainId.operator TUint() );
+
+ if ( RThread().Id() != gGlobalTracker.iMainId )
+ {
+ LOGSTR2("ATMH CustomUser::Exit() - Calling allocator uninstall in thread: %d" , RThread().Id().operator TUint() );
+ ( (RAnalyzeToolMemoryAllocator&) User::Allocator() ).Uninstall();
+ }
+#else
+ // Uninstall thread's RAllocator
+ ( (RAnalyzeToolMemoryAllocator&) User::Allocator() ).Uninstall();
+ LOGSTR1( "ATMH CustomUser::Exit() - about to User::Exit" );
+#endif
+ }
+
+ // Call the "real" User::Exit()
+ User::Exit( aReason );
+ }
+
+// -----------------------------------------------------------------------------
+// CustomUser::SetCritical()
+// Overloaded User::SetCritical() function which returns
+// KErrNone, if successful; KErrArgument, if EAllThreadsCritical is
+// passed - this is a state associated with a process, and you use
+// User::SetProcessCritical() to set it.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CustomUser::SetCritical( User::TCritical aCritical )
+ {
+ LOGSTR1( "ATMH CustomUser::SetCritical()" );
+ // Check the given User::TCritical type
+ if ( aCritical == User::EAllThreadsCritical )
+ {
+ return KErrArgument;
+ }
+ else
+ {
+ return KErrNone;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CustomUser::SetProcessCritical()
+// Overloaded User::SetProcessCritical() function
+// KErrNone, if successful; KErrArgument, if either EProcessCritical or
+// EProcessPermanent is passed - these are states associated with a
+// thread, and you use User::SetCritical() to set them.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CustomUser::SetProcessCritical( User::TCritical aCritical )
+ {
+ LOGSTR1( "ATMH CustomUser::SetProcessCritical()" );
+ // Check the given User::TCritical type
+ if ( aCritical == User::EProcessCritical ||
+ User::EProcessPermanent == aCritical )
+ {
+ return KErrArgument;
+ }
+ else
+ {
+ return KErrNone;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CustomUser::SetupThreadHeap()
+// Overloaded UserHeap::SetupThreadHeap function
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CustomUser::SetupThreadHeap( TBool aNotFirst,
+ SStdEpocThreadCreateInfo& aInfo, const TFileName& aFileName,
+ TUint32 aLogOption, TUint32 aIsDebug, const TATVersion& aVersion,
+ TUint32 aAllocCallStackSize, TUint32 aFreeCallStackSize,
+ TRefByValue<const TDesC> aFmt, ... )
+ {
+ LOGSTR1( "ATMH CustomUser::SetupThreadHeap()" );
+ LOGSTR2( "ATMH > Thread id(%d)", RThread().Id().operator TUint() );
+
+ // Add handling of the argument list here.
+
+ TInt ret( KErrNone );
+ // Check version number
+ TBuf<KAtoolVersionNumberLength> atoolVer;
+ if ( CheckVersion( aVersion, atoolVer ) != KErrNone )
+ {
+ LOGSTR1( "ATMH > Wrong API version > Inform user and Exit." );
+ ReportIncorrectVersion( aLogOption, aFileName, atoolVer );
+ return KAtoolVersionError;
+ }
+
+ // Check is this shared heap
+ if ( aInfo.iAllocator == NULL )
+ {
+ LOGSTR1( "ATMH creating a new heap" );
+ // RAllocator is NULL so heap is not shared, creating a new heap
+ ret = UserHeap::SetupThreadHeap( aNotFirst, aInfo );
+ __ASSERT_ALWAYS( KErrNone == ret, AssertPanic( EFailedToCreateHeap ) );
+
+#if ( SYMBIAN_VERSION_SUPPORT >= SYMBIAN_3 )
+ #ifndef __WINS__
+ // Set dummy Tls value
+ TAny* dummyPtr( NULL );
+ TInt setErr( UserSvr::DllSetTls( KDummyHandle, dummyPtr ) );
+ LOGSTR2( "ATMH > Set Tls err(%i)", setErr );
+ #endif
+#endif
+ // Install the RAllocator
+ aInfo.iAllocator = &InstallAllocator( aNotFirst, aFileName, aLogOption, aIsDebug,
+ aAllocCallStackSize, aFreeCallStackSize );
+ }
+ else
+ {
+ LOGSTR1( "ATMH sharing the heap" );
+ // The heap is shared. Acquire pointer to the original heap
+ RAnalyzeToolMemoryAllocator* allocator =
+ (RAnalyzeToolMemoryAllocator*) aInfo.iAllocator;
+ // Share the heap
+ allocator->ShareHeap();
+ // Switch thread heap
+ User::SwitchAllocator( allocator );
+ }
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// CustomUser::InstallAllocator
+// Installs the RAllocator
+// -----------------------------------------------------------------------------
+//
+//lint -e{429} suppress "Custodial pointer 'allocator' has not been freed or returned"
+EXPORT_C RAllocator& CustomUser::InstallAllocator( TBool aNotFirst,
+ const TFileName& aFileName, TUint32 aLogOption, TUint32 aIsDebug,
+ TUint32 aAllocCallStackSize, TUint32 aFreeCallStackSize )
+ {
+ LOGSTR1( "ATMH CustomUser::InstallAllocator()" );
+
+ // Open handle to the device driver
+ RAnalyzeTool analyzetool;
+ TInt error = analyzetool.Open();
+
+ // Check if the device driver has already loaded
+ if ( KErrNone == error )
+ {
+ LOGSTR1( "ATMH CustomUser::InstallAllocator() - analyzetool.Open() returned KErrNone" );
+ // The device driver has already loaded
+ // Get pointer to the main thread allocator
+ TMainThreadParamsBuf params;
+ params().iProcessId = RProcess().Id().operator TUint();
+ error = analyzetool.MainThreadAlloctor( params );
+
+ __ASSERT_ALWAYS( KErrNone == error, AssertPanic( ECantOpenHandle ) );
+
+ // Close handle to the device driver
+ analyzetool.Close();
+
+ // Is this the first thread of the program
+ if ( params().iAlone )
+ {
+ LOGSTR1( "ATMH CustomUser::InstallAllocator() - first thread of the program" );
+ // Only one thread in the program. Must be main thread
+ RAnalyzeToolMainAllocator* allocator =
+ new RAnalyzeToolMainAllocator( aNotFirst, aFileName, aLogOption,
+ aIsDebug, aAllocCallStackSize, aFreeCallStackSize );
+
+ __ASSERT_ALWAYS( allocator != NULL, AssertPanic( ENoMemory ) );
+
+ // Change threads allocator
+ User::SwitchAllocator( allocator );
+
+ // Return reference to the RAllocator
+ return *allocator;
+ }
+ // This is not the first thread. A new thread with a new heap created
+ else
+ {
+ LOGSTR1( "ATMH CustomUser::InstallAllocator() - create a new allocator for the new thread" );
+ // Create new RAllocator with handles from the main thread
+ RAnalyzeToolAllocator* allocator = new RAnalyzeToolAllocator(
+ aNotFirst,
+ ((RAnalyzeToolMainAllocator*)params().iAllocator)->StorageServer(),
+ ((RAnalyzeToolMainAllocator*)params().iAllocator)->Codeblocks(),
+ ((RAnalyzeToolMainAllocator*)params().iAllocator)->Mutex(),
+ ((RAnalyzeToolMainAllocator*)params().iAllocator)->ProcessId(),
+ ((RAnalyzeToolMainAllocator*)params().iAllocator)->AnalyzeTool(),
+ ((RAnalyzeToolMainAllocator*)params().iAllocator)->StorageServerOpen(),
+ ((RAnalyzeToolMainAllocator*)params().iAllocator)->LogOption(),
+ ((RAnalyzeToolMainAllocator*)params().iAllocator)->AllocMaxCallStack(),
+ ((RAnalyzeToolMainAllocator*)params().iAllocator)->FreeMaxCallStack() );
+
+ __ASSERT_ALWAYS( allocator != NULL, AssertPanic( ENoMemory ) );
+
+ // Change threads allocator
+ User::SwitchAllocator( allocator );
+
+ // Return reference to the RAllocator
+ return *allocator;
+ }
+ }
+ // The device driver does not exists so this must be the first thread
+ else
+ {
+ LOGSTR1( "ATMH CustomUser::InstallAllocator() - analyzetool.Open() returned error, creating DD" );
+ RAnalyzeToolMainAllocator* allocator =
+ new RAnalyzeToolMainAllocator( aNotFirst, aFileName, aLogOption, aIsDebug,
+ aAllocCallStackSize, aFreeCallStackSize );
+
+ __ASSERT_ALWAYS( allocator != NULL, AssertPanic( ENoMemory ) );
+
+ // Change threads allocator
+ User::SwitchAllocator( allocator );
+
+ // Return reference to the RAllocator
+ return *allocator;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CustomUser::CheckVersion
+// Check atool version
+// -----------------------------------------------------------------------------
+//
+TInt CustomUser::CheckVersion( const TATVersion& aVersion, TDes& aToolVersion )
+ {
+ LOGSTR2( "ATMH CustomUser::CheckVersion(), aVersion( %S )", &aVersion );
+
+ TFileName version;
+ version.Copy( aVersion );
+ TBuf<KAtoolVersionNumberLength> apiVer;
+
+ // Find separator place
+ TInt findplace( version.Find( KVersionSeparator() ) );
+ // Parse API version first [x.x.x;x.x.x]
+ if ( findplace >= 0 && findplace <= apiVer.MaxLength() )
+ {
+ apiVer.Copy( version.Mid( 0, findplace ) );
+ version.Delete( 0, findplace + KVersionSeparator().Length() );
+ }
+
+ if ( version.Length() <= aToolVersion.MaxLength() )
+ {
+ aToolVersion.Copy( version );
+ if ( aToolVersion.Compare( KAtoolApiVersion ) == KErrNone &&
+ apiVer.Length() == 0 )
+ {
+ // Support 1.5.0 version (Version info: [1.5.0])
+ apiVer.Copy( version );
+ }
+ }
+
+ LOGSTR3( "ATMH > API version( %S ), ATOOL version( %S )",
+ &apiVer, &aToolVersion );
+
+ // Check version numbers
+ if ( apiVer.Compare( KAtoolApiVersion ) == KErrNone )
+ {
+ return KErrNone;
+ }
+ return KErrCancel;
+ }
+
+// -----------------------------------------------------------------------------
+// CustomUser::ReportIncorrectVersion
+// Function for showing incorrect version information
+// -----------------------------------------------------------------------------
+//
+void CustomUser::ReportIncorrectVersion( const TUint32 aLogOption,
+ const TFileName& aFileName, const TDes& aToolVersion )
+ {
+ LOGSTR2( "ATMH CustomUser::ReportIncorrectVersion(), aFileName( %S )",
+ &aFileName );
+
+ switch ( aLogOption )
+ {
+ case EATLogToFile:
+ {
+ LOGSTR1( "ATMH ReportIncorrectVersion > EATLogToFile" );
+
+ // A handle to a file server session.
+ RFs fs;
+ // Creates and opens a file,
+ // and performs all operations on a single open file.
+ RFile file;
+ // Create full path buffer
+ TBuf<KMaxFileName> logFileBuf;
+ // Connects a client to the file server.
+ TInt err( fs.Connect() );
+
+ if ( !err )
+ {
+ err = TATDriveInfo::CreatePath( logFileBuf, aFileName, fs );
+
+ // Replace file if exists
+ if ( err && err != KErrAlreadyExists )
+ {
+ LOGSTR2( "ATMH > TATDriveInfo::CreatePath() err( %i )", err );
+ return;
+ }
+
+ // Replace file if exists (drive C)
+ err = file.Replace( fs, logFileBuf, EFileWrite );
+
+ // Write to file
+ if ( !err )
+ {
+ err = file.Write( KDataFileVersion );
+ // Error msg buffer
+ TBuf8<KMaxFileName> msg;
+ // Write the error code to the buffer
+ logFileBuf.Format( KIncorrectText, &KAtoolApiVersion, &aToolVersion );
+ CnvUtfConverter::ConvertFromUnicodeToUtf8( msg, logFileBuf );
+ err = file.Write( msg );
+ }
+ // Closes the file.
+ file.Close();
+ }
+
+ LOGSTR2( "ATMH > File err( %i )", err );
+ // Closes the handle.
+ fs.Close();
+ }
+ break;
+
+ case EATUseDefault:
+ case EATLogToTrace:
+ {
+ LOGSTR1( "ATMH > ReportIncorrectVersion > EATLogToTrace" );
+ // Error msg buffer
+ TBuf<KMaxFileName> msg;
+ msg.Copy( KIncorrectTextTrace );
+ msg.Append( KIncorrectText );
+ TBuf<KMaxFileName> traceMsg;
+ // Write the error code to the buffer
+ traceMsg.Format( msg, &KAtoolApiVersion, &aToolVersion );
+ RDebug::Print( traceMsg );
+ }
+ break;
+
+ default:
+ {
+ LOGSTR1( "ATMH > ReportIncorrectVersion > default" );
+ }
+ break;
+ }
+ }
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/dynamicmemoryhook/src/threadstack.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,76 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Definitions for the class TThreadStack.
+*
+*/
+
+
+#include "threadstack.h"
+#include "atlog.h"
+
+// -----------------------------------------------------------------------------
+// TThreadStack::TThreadStack()
+// C++ default constructor.
+// -----------------------------------------------------------------------------
+//
+TThreadStack::TThreadStack( TThreadId aId, TUint32 aStackStart ) :
+ iId( aId ),
+ iStackStart( aStackStart )
+ {
+ LOGSTR2( "ATMH TThreadStack::TThreadStack() aStackStart: %i", aStackStart );
+ }
+
+// -----------------------------------------------------------------------------
+// TThreadStack::ThreadStackStart()
+// Checks if this is the current thread and if this is the current
+// thread assings value to the given parameter
+// -----------------------------------------------------------------------------
+//
+TBool TThreadStack::ThreadStackStart( TUint32& aStackStart )
+ {
+ LOGSTR1( "ATMH TThreadStack::ThreadStackStart");
+
+ if ( RThread().Id() == iId )
+ {
+ aStackStart = iStackStart;
+ return ETrue;
+ }
+ else
+ {
+ aStackStart = 0;
+ return EFalse;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// TThreadStack::Match()
+// Checks if this is the the current thread.
+// -----------------------------------------------------------------------------
+//
+TBool TThreadStack::Match( const TUint aThreadId )
+ {
+ LOGSTR2( "ATMH TThreadStack::Match( %d )", aThreadId );
+
+ if ( aThreadId != 0 )
+ {
+ LOGSTR2( "ATMH > iId.operator TUint() = %d", iId.operator TUint() );
+ return ( aThreadId == iId.operator TUint() ) ? ETrue : EFalse;
+ }
+ else
+ {
+ return ( RThread().Id() == iId ) ? ETrue : EFalse;
+ }
+ }
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/envpatcher/EnvPatcher.pl Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,544 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+# Environment Patcher - Patches older S60 SDKs for supporting
+# tricks in newer platforms
+#
+
+
+require v5.6.1;
+
+use File::Copy;
+use strict;
+
+# check amount of commandline options is valid
+if (@ARGV != 1)
+{
+ print "Usage: EnvPatcher <EPOCROOT>\n";
+ exit 1;
+}
+
+
+# get epocroot and convert, convert \ -> /
+(my $epocroot = $ARGV[0]) =~ s{\\}{/}g;
+
+# remove any trailing forward slashes
+$epocroot =~ s/\/$//;
+
+
+# create variables for paths
+my $e32toolsdir = $epocroot."/epoc32/tools";
+my $e32includedir = $epocroot."/epoc32/include";
+my $e32includeoemdir = $e32includedir."/oem";
+my $platformpathspath = $e32includedir."/platform_paths.hrh";
+my $domainplatformpathspath = $e32includedir."/domain/osextensions/platform_paths.hrh";
+my $mmppmpath = $e32toolsdir."/mmp.pm";
+my $pathutlpmpath = $e32toolsdir."/pathutl.pm";
+my $prepfilepmpath = $e32toolsdir."/prepfile.pm";
+
+# variables for hacked content
+my $dependshack = "\t\t\tif (/^DEPENDS\$/o) {\r\n\t\t\t\tnext LINE; # Ignore DEPENDS keyword, not needed by ABLD\r\n\t\t\t}\r\n";
+my $smpsafehack = "\t\tif (/^SMPSAFE\$/o) {\r\n\t\t\tnext LINE; # Ignore SMPSAFE keyword, not needed by older environments\r\n\t\t}\r\n";
+my $forwardslashhack = "\t\t# EnvPatcher forwardslash hack begins\r\n\t\t\$_=~s{/}{\\\\}g; # convert all forward slashes to backslashes\r\n\t\t# EnvPatcher forwardslash hack ends\r\n\r\n";
+my $coreibyexportsupport = "\r\n// Following definition is used for exporting tools and stubs IBY files to\r\n// Core image.\r\n#define CORE_IBY_EXPORT_PATH(path,exported) /epoc32/rom/include/##exported\r\n";
+
+
+# check epoc32\tools exists
+unless (-d $e32toolsdir)
+{
+ print "$e32toolsdir not found, please check valid epocroot has been given!\n";
+ exit 1;
+}
+
+# check epoc32\include exists
+unless (-d $e32includedir)
+{
+ print "$e32includedir not found, please check valid epocroot has been given!\n";
+ exit 1;
+}
+
+
+# create epoc32\include\oem if it does not exist
+unless (-d $e32includeoemdir)
+{
+ mkdir $e32includeoemdir or die;
+ print "Missing directory $e32includeoemdir created succesfully.\n";
+}
+
+
+# check if epoc32\include\domain\osextensions\platform_paths.hrh exists
+if (-e $domainplatformpathspath)
+{
+ # show an error if the file does not have any platform macros
+ unless (string_exists_in_file($domainplatformpathspath, "OS_LAYER_SYSTEMINCLUDE"))
+ {
+ print "ERROR: $domainplatformpathspath does not have SF macros.\n";
+ print "Please check your environment, if you have S60 3.2 OEM or newer, please get the latest version!\n";
+ exit 2;
+ }
+}
+
+
+# check if epoc32\include\platform_paths.hrh exists
+if (-e $platformpathspath)
+{
+ print "$platformpathspath already exists, not checking it.\n";
+}
+else
+{
+ # create the file missing file
+ create_default_platform_paths_hrh();
+ print "Missing file $platformpathspath created succesfully.\n";
+}
+
+
+# check if CORE_IBY_EXPORT_PATH macro exist in the platform_paths.hrh
+unless (string_exists_in_file($platformpathspath, "CORE_IBY_EXPORT_PATH"))
+{
+ # read content of the platform_paths.hrh
+ my @filecontent = read_file_to_array($platformpathspath);
+
+ my $match_found = 0;
+ my $i = 0;
+ my $match_found_pos = 0;
+
+ # find the position where the include guards start (this should be a safe position)
+ foreach (@filecontent)
+ {
+ if ($_ =~ /#define PLATFORM_PATHS_HRH/)
+ {
+ $match_found = 1;
+ $match_found_pos = $i;
+ last;
+ }
+
+ $i++;
+ }
+
+ if ($match_found)
+ {
+ # insert the patched content to the file
+ splice(@filecontent, $match_found_pos+1, 0, $coreibyexportsupport);
+
+ # write the modified array to the file
+ write_file_from_array($platformpathspath, @filecontent);
+
+ print "Platform_paths.hrh updated to support CORE_IBY_EXPORT_PATH macro.\n";
+ }
+ else
+ {
+ print "WARNING: $platformpathspath is corrupted or not supported!\n";
+ }
+}
+
+
+# check if epoc32\tools\mmp.pm exists
+if (-e $mmppmpath)
+{
+ # check if DEPENDS keyword already exists in the file
+ if (string_exists_in_file($mmppmpath, "DEPENDS"))
+ {
+ print "The SDK can already handle DEPENDS keyword in a MMP file.\n";
+ }
+ else
+ {
+ # read content of the mmp.pm file
+ my @filecontent = read_file_to_array($mmppmpath);
+
+ my $match_found = 0;
+ my $i = 0;
+ my $match_found_pos = 0;
+
+ # loop through the array to find the correct place
+ foreach (@filecontent)
+ {
+ if ($_ =~ /Unrecognised Resource Keyword/)
+ {
+ $match_found = 1;
+ $match_found_pos = $i;
+ last;
+ }
+
+ $i++;
+ }
+
+ if ($match_found)
+ {
+ # insert the patched content to the file
+ splice(@filecontent, $match_found_pos-1, 0, $dependshack);
+
+ # write the modified array to the file
+ write_file_from_array($mmppmpath, @filecontent);
+
+ print "Mmp.pm patched with DEPENDS keyword hack.\n";
+ }
+ else
+ {
+ print "ERROR: Unable to find correct place from $mmppmpath for patching!\n";
+ print "Your SDK environment probably is not supported by this script!\n";
+ exit(2);
+ }
+ }
+
+ # check if SMPSAFE keyword already exists in the file
+ if (string_exists_in_file($mmppmpath, "SMPSAFE"))
+ {
+ print "The SDK can already handle SMPSAFE keyword in a MMP file.\n";
+ }
+ else
+ {
+ # read content of the mmp.pm file
+ my @filecontent = read_file_to_array($mmppmpath);
+
+ my $match_found = 0;
+ my $i = 0;
+ my $match_found_pos = 0;
+
+ # loop through the array to find the correct place
+ foreach (@filecontent)
+ {
+ if ($_ =~ /Unrecognised Keyword/)
+ {
+ $match_found = 1;
+ $match_found_pos = $i;
+ last;
+ }
+
+ $i++;
+ }
+
+ if ($match_found)
+ {
+ # insert the patched content to the file
+ splice(@filecontent, $match_found_pos, 0, $smpsafehack);
+
+ # write the modified array to the file
+ write_file_from_array($mmppmpath, @filecontent);
+
+ print "Mmp.pm patched with SMPSAFE keyword hack.\n";
+ }
+ else
+ {
+ print "ERROR: Unable to find correct place from $mmppmpath for patching!\n";
+ print "Your SDK environment probably is not supported by this script!\n";
+ exit(2);
+ }
+ }
+}
+else
+{
+ print "WARNING: $mmppmpath not found, this environment is not supported!\n";
+}
+
+
+# check if epoc32\tools\pathutl.pm exists
+if (-e $pathutlpmpath)
+{
+ # check if "sub Path_Norm" already exists in the pathutil.pm file
+ # if it does not exists, then we need to patch prepfile.pm
+ if (string_exists_in_file($pathutlpmpath, "sub Path_Norm"))
+ {
+ print "The SDK is non Symbian OS 9.1, no need to add forward slash hack.\n";
+ }
+ else
+ {
+ # check if prepfile.pm has already been patched
+ if (string_exists_in_file($prepfilepmpath, "EnvPatcher forwardslash hack"))
+ {
+ print "The SDK has already been patched with forwardslash hack.\n";
+ }
+ else
+ {
+ # read content of the prepfile.pm file
+ my @filecontent = read_file_to_array($prepfilepmpath);
+
+ my $match_found = 0;
+ my $i = 0;
+ my $match_found_pos = 0;
+
+ # loop through the array to find the correct place
+ foreach (@filecontent)
+ {
+ if ($_ =~ /# skip blank lines/)
+ {
+ $match_found = 1;
+ $match_found_pos = $i;
+ last;
+ }
+
+ $i++;
+ }
+
+ if ($match_found)
+ {
+ # insert the patched content to the file
+ splice(@filecontent, $match_found_pos+6, 0, $forwardslashhack);
+
+ # write the modified array to the file
+ write_file_from_array($prepfilepmpath, @filecontent);
+
+ print "Prepfile.pm patched with forward slash hack.\n";
+ }
+ else
+ {
+ print "ERROR: Unable to find correct place from $prepfilepmpath for patching!\n";
+ print "Your SDK environment probably is not supported by this script!\n";
+ exit(2);
+ }
+ }
+ }
+}
+else
+{
+ print "WARNING: $pathutlpmpath not found, this environment is not supported!\n";
+}
+
+
+
+# checks if string exists in the file
+sub string_exists_in_file
+{
+ my $filepath = $_[0];
+ my $findstring = $_[1];
+ my $match_found = 0;
+
+ open(FILE, "<", $filepath) or die "Failed to open $filepath for reading!";
+
+ # loop through the file for occurances
+ while (<FILE>)
+ {
+ if ($_ =~ /$findstring/)
+ {
+ $match_found = 1;
+ last;
+ }
+ }
+
+ close FILE;
+
+ return $match_found;
+}
+
+
+# reads lines from a file to an array
+sub read_file_to_array
+{
+ my $filepath = $_[0];
+
+ open(FILE, "<", $filepath) or die "Failed to open $filepath for reading!";
+ my @data = <FILE>;
+ close FILE;
+
+ return(@data);
+}
+
+
+# writes lines from an array to a file
+sub write_file_from_array
+{
+ my ($filepath, @data) = @_;
+
+ # take a backup of the file
+ copy ($filepath, $filepath."EnvPatcher") or die "Cannot take backup of $filepath to $filepath.EnvPatcher";
+
+ open(FILE, ">", $filepath) or die "Failed to open $filepath for writing!";
+
+ # write the array to file
+ foreach my $line (@data)
+ {
+ print FILE "$line";
+ }
+
+ close FILE;
+}
+
+sub create_default_platform_paths_hrh
+{
+ # the file does not exist, so create the missing file
+ open(FILE, ">", $platformpathspath) or die "Failed to open $platformpathspath for writing!\n";
+
+ print FILE <<ENDOFTHEFILE;
+#ifndef PLATFORM_PATHS_HRH
+#define PLATFORM_PATHS_HRH
+
+/**
+* ---------------------------------------
+* Location, where the applications layer specific public headers should be exported
+* See usage on top of this hrh-file.
+* ---------------------------------------
+*/
+#define APP_LAYER_SDK_EXPORT_PATH(exported) /epoc32/include/##exported
+#define APP_LAYER_PUBLIC_EXPORT_PATH(exported) /epoc32/include/##exported
+
+/**
+* ---------------------------------------
+* Location, where the applications layer specific platform headers should be exported
+* See usage on top of this hrh-file.
+* ---------------------------------------
+*/
+#define APP_LAYER_DOMAIN_EXPORT_PATH(exported) /epoc32/include/##exported
+#define APP_LAYER_PLATFORM_EXPORT_PATH(exported) /epoc32/include/##exported
+
+/**
+* ---------------------------------------
+* Location, where the middleware layer specific public headers should be exported
+* See usage on top of this hrh-file.
+* ---------------------------------------
+*/
+#define MW_LAYER_SDK_EXPORT_PATH(exported) /epoc32/include/##exported
+#define MW_LAYER_PUBLIC_EXPORT_PATH(exported) /epoc32/include/##exported
+
+/**
+* ---------------------------------------
+* Location, where the middleware layer specific platform headers should be exported
+* ---------------------------------------
+*/
+#define MW_LAYER_DOMAIN_EXPORT_PATH(exported) /epoc32/include/##exported
+#define MW_LAYER_PLATFORM_EXPORT_PATH(exported) /epoc32/include/##exported
+
+/**
+* ---------------------------------------
+* Location, where the os layer specific public headers should be exported
+* ---------------------------------------
+*/
+#define OSEXT_LAYER_SDK_EXPORT_PATH(exported) /epoc32/include/##exported
+#define OS_LAYER_PUBLIC_EXPORT_PATH(exported) /epoc32/include/##exported
+
+/**
+* ---------------------------------------
+* Location, where the os specific platform headers should be exported
+* ---------------------------------------
+*/
+#define OSEXT_LAYER_DOMAIN_EXPORT_PATH(exported) /epoc32/include/##exported
+#define OS_LAYER_PLATFORM_EXPORT_PATH(exported) /epoc32/include/##exported
+
+/**
+* ---------------------------------------
+* Location, where the cenrep excel sheets should be exported
+* Deprecated: should no longer be used. Kept for compability.
+* ---------------------------------------
+*/
+#define CENREP_XLS_EXPORT_PATH(exported) /epoc32/tools/cenrep/data/src/##exported
+
+/**
+* This define statements defines the SYSTEMINCLUDE-line, which is intended to be
+* used in the mmp-files that are part of the applications-layer. It includes all
+* the needed directories from the /epoc32/include, that are valid ones for the
+* application-layer components.
+*
+* Applications layer is the last one in the list, since most likely the most of
+* the headers come from middleware or os-layer => thus they are first.
+*/
+#define APP_LAYER_SYSTEMINCLUDE SYSTEMINCLUDE /epoc32/include /epoc32/include/oem
+
+/**
+* This define statements defines the SYSTEMINCLUDE-line, which is intended to be
+* used in the mmp-files that are part of the middleware-layer. It includes all
+* the needed directories from the /epoc32/include, that are valid ones for the
+* middleware-layer components.
+*/
+#define MW_LAYER_SYSTEMINCLUDE SYSTEMINCLUDE /epoc32/include /epoc32/include/oem
+
+/**
+* This define statements defines the SYSTEMINCLUDE-line, which is intended to be
+* used in the mmp-files that are part of the osextensions-layer. It includes all
+* the needed directories from the /epoc32/include, that are valid ones for the
+* os-layer components.
+*/
+#define OS_LAYER_SYSTEMINCLUDE SYSTEMINCLUDE /epoc32/include /epoc32/include/oem
+
+
+// Below statement is Deprecated and the OS_LAYER_SYSTEMINCLUDE-macro has to be
+// used.
+#define OSEXT_LAYER_SYSTEMINCLUDE OS_LAYER_SYSTEMINCLUDE
+
+/**
+* This define statements defines the SYSTEMINCLUDE-line, which is intended to be
+* used in the mmp-files that are part of the os-layer. This is intended
+* to be only used by those components which need to use in their mmp-file either
+* kern_ext.mmh or nkern_ext.mmh. Reason is that those
+* 2 files already contain the /epoc32/include as system include path.
+*
+*/
+#define OS_LAYER_KERNEL_SYSTEMINCLUDE SYSTEMINCLUDE /epoc32/include/oem
+
+
+// Below statement is Deprecated and the OS_LAYER_KERNEL_SYSTEMINCLUDE-macro
+// has to be used.
+#define OSEXT_LAYER_KERNEL_SYSTEMINCLUDE OS_LAYER_KERNEL_SYSTEMINCLUDE
+
+/**
+****************************************************************************
+* Definitions that also define the paths to the layer specific source directories.
+****************************************************************************
+*/
+/**
+* The below 3 macros define the paths to the layer-specific source dirs.
+* See usage on top of this hrh-file, these are used the same way as
+* for instance the OS_LAYER_DOMAIN_EXPORT_PATH
+* Deprecated: is not allowed to be using in Symbian Foundation
+*/
+#define APP_LAYER_SOURCE_PATH(rest) /s60/app/##rest
+#define MW_LAYER_SOURCE_PATH(rest) /s60/mw/##rest
+#define OSEXT_LAYER_SOURCE_PATH(rest) /s60/osext/##rest
+
+/**
+****************************************************************************
+* Definitions to export IBY files to different folders where they will be taken
+* to ROM image
+****************************************************************************
+*/
+// Following definition is used for exporting tools and stubs IBY files to
+// Core image.
+#define CORE_IBY_EXPORT_PATH(path,exported) /epoc32/rom/include/##exported
+
+/**
+* ---------------------------------------
+* Macros for Configuration tool migration.
+* The below macros define the location under epoc32, where the confml
+* (Configuration Markup Language) and crml (Central Repository Markup Language)
+* files should be exported.
+* ---------------------------------------
+*/
+#define CONFML_EXPORT_PATH(file,category) /epoc32/rom/config/confml_data/##category##/##file
+#define CRML_EXPORT_PATH(file,category) /epoc32/rom/config/confml_data/##category##/##file
+#define GCFML_EXPORT_PATH(file,category) /epoc32/rom/config/confml_data/##category##/##file
+#define CONFML_CONFIG_EXPORT_PATH(file,category) /epoc32/rom/config/confml_data/##category##/config/##file
+
+#define APP_LAYER_CONFML(exported) CONFML_EXPORT_PATH(exported,s60)
+#define APP_LAYER_CRML(exported) CRML_EXPORT_PATH(exported,s60)
+#define APP_LAYER_GCFML(exported) GCFML_EXPORT_PATH(exported,s60)
+#define APP_LAYER_CONFML_CONFIG(exported) CONFML_CONFIG_EXPORT_PATH(exported,s60)
+
+#define MW_LAYER_CONFML(exported) CONFML_EXPORT_PATH(exported,s60)
+#define MW_LAYER_CRML(exported) CRML_EXPORT_PATH(exported,s60)
+#define MW_LAYER_GCFML(exported) GCFML_EXPORT_PATH(exported,s60)
+#define MW_LAYER_CONFML_CONFIG(exported) CONFML_CONFIG_EXPORT_PATH(exported,s60)
+
+// Deprecate: Use the OS_LAYER_* macros instead of OSEXT_LAYER_*
+#define OSEXT_LAYER_CONFML(exported) CONFML_EXPORT_PATH(exported,s60)
+#define OSEXT_LAYER_CRML(exported) CRML_EXPORT_PATH(exported,s60)
+#define OSEXT_LAYER_GCFML(exported) GCFML_EXPORT_PATH(exported,s60)
+#define OSEXT_LAYER_CONFML_CONFIG(exported) CONFML_CONFIG_EXPORT_PATH(exported,s60)
+#define OS_LAYER_CONFML(exported) CONFML_EXPORT_PATH(exported,s60)
+#define OS_LAYER_CRML(exported) CRML_EXPORT_PATH(exported,s60)
+#define OS_LAYER_GCFML(exported) GCFML_EXPORT_PATH(exported,s60)
+#define OS_LAYER_CONFML_CONFIG(exported) CONFML_CONFIG_EXPORT_PATH(exported,s60)
+
+#endif // end of PLATFORM_PATHS_HRH
+
+ENDOFTHEFILE
+
+ close FILE;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/envpatcher/ReadMe.txt Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,46 @@
+Environment Patcher v1.0.1
+==========================
+
+Updated: 12th November 2009
+
+
+Introduction:
+-------------
+This tool can be used to patch your S60 SDK environment so that the tricks and
+macros introduced in the latest SDKs can be used in a public SDK and older
+OEM releases.
+
+This tool can perform the following tasks:
+- Adds support for forward slashes in paths in bld.inf/.mmp files in S60 3.0
+- Removes an unncessary warning about DEPENDS and SMPSAFE resource keywords in
+ an .mmp file
+- Creates a missing epoc32\include\platform_paths.hrh file for supporting
+ platform macros introduced since S60 3.2 OEM and Symbian Foundation releases
+- Modifies epoc32\include\platform_paths.hrh for missing macros
+- Creates a missing epoc32\include\oem directory to suppress a possible warning
+
+
+Usage:
+------
+EnvPatcher.pl <EPOCROOT>
+
+Where EPOCROOT is the path to the root of the SDK, for example:
+ EnvPatcher.pl c:\Symbian\9.1\S60_3rd_MR
+ EnvPatcher.pl z:\
+
+
+Requirements:
+-------------
+- S60 SDK (public or OEM), version 3.0 or newer
+- Perl 5.6.1 or newer
+
+
+
+
+Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+All rights reserved.
+
+This component and the accompanying materials are made available
+under the terms of "Eclipse Public License v1.0"
+which accompanies this distribution, and is available
+at the URL "http://www.eclipse.org/legal/epl-v10.html".
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/group/ReleaseNotes_AnalyzeTool.txt Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,136 @@
+===============================================================================
+
+RELEASE NOTES - ANALYZETOOL v1.9.1
+RELEASED 29th April 2010
+
+SUPPORTS SYMBIAN^1+
+
+===============================================================================
+
+Product Description:
+====================
+AnalyzeTool is a dynamic test tool that is used for testing Symbian software
+for memory and resource leaks and pinpointing the leaks from the source code.
+
+Main Features:
+==============
+- Pinpoints memoryleaks from target hardware and emulator to source code lines
+- Discovers resource leaks from processes
+- Command line interface and Carbide.c++ Extension
+
+===============================================================================
+
+What's New in v1.9.1
+====================
+- Change: Removed Avkon and Console UI's to simplify the maintenance of the
+ tool
+- Change: Middleware layer dependencies removed so AnalyzeTool can be now used
+ also in OS layer builds
+- Fix: Move all binaries to ROM instead of ROFS to avoid ROM build
+ dependencies issues in hooked components
+
+===============================================================================
+
+Installation Notes:
+===================
+AnalyzeTool is typically preinstalled on ROM. If not, it can be added to the
+ROM with the .iby file. Alternatively, the .sis file can be found under the sis-
+directory, but the user need to sign it with their own developer certificate.
+In Nokia R&D environment, you can use directly the R&D-signed .sis file under the
+internal\sis directory.
+
+When signing with own developer certificate, the following capabilities are
+needed:
+ ReadDeviceData
+ WriteDeviceData
+ DiskAdmin
+ AllFiles
+ SwEvent
+ NetworkServices
+ LocalServices
+ ReadUserData
+ WriteUserData
+ Location
+ UserEnvironment
+ CommDD
+ PowerMgmt
+ MultimediaDD
+ DRM
+ TrustedUI
+ ProtServ
+ NetworkControl
+ SurroundingsDD
+ TCB
+
+When builing AnalyzeTool against S60 3.0 or 3.1, you may need to patch your SDK
+environment first with some fixes. For more information, please refer to the
+instructions under the "envpatcher" directory.
+
+===============================================================================
+
+System Requirements:
+====================
+Basic Requirements:
+- Any S60 3.x device or emulator environment
+
+===============================================================================
+
+Compatibility Issues:
+=====================
+N/A
+
+===============================================================================
+
+Known Issues:
+=============
+- Kernel analysis are not supported.
+
+- When using monitored internal data gathering mode (-mi) and hooked
+ application contains huge amounts of allocations AnalyzeTool? storageserver
+ might run out of memory to store the data. This message "Symbian error code
+ -4" is seen when analyzing the data file with atool.exe. Solution is to use
+ external / monitored external data gathering mode.
+
+- Switch allocator. AnalyzeTool change the application memory allocator to
+ AnalyzeTool own memory allocator and using the User::SwitchAllocator function
+ can lead to situation where the tested application does not work properly.
+
+- AnalyzeTool hooked QT applications becomes too slow to run. Use small size
+ call stack(s) and new logging mode (external -e).
+
+- Stif test case with AnalyzeTool can inform wrong memory leak alert.
+
+- AnalyzeTool overwrites functions TInt User::ProcessCritical(TCritical
+ aCritical) and TInt User::SetProcessCritical(TCritical aCritical), but this
+ works only when the function is called from hooked exe application. So if
+ setting critical is done from DLL (even if it's hooked with AnalyzeTool) the
+ overwriting does not work and the process stays set critical during the
+ testing.
+
+- If hooked application is closed by calling User::Exit() from DLL instead of
+ .exe application AnalyzeTool reports "abnormal process end" and can't report
+ proper memory leaks.
+
+===============================================================================
+
+Version History:
+================
+
+Version 1.9.0 - 8th April 2010
+==============================
+- Feature: Remove false positive memory leaks with better handling of global
+ variables
+- Feature: Automatic check of correct version of dbghelp.dll for better
+ emulator support
+- Change: HTI support removed
+- Fix: SBSVS variant compilation didn't work
+
+===============================================================================
+
+Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+All rights reserved.
+
+This component and the accompanying materials are made available
+under the terms of "Eclipse Public License v1.0"
+which accompanies this distribution, and is available
+at the URL "http://www.eclipse.org/legal/epl-v10.html".
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/group/atool_stub_sis.mk Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,57 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: Stub sis makefile for Configuration UI.
+#
+
+TARGETDIR=$(EPOCROOT)EPOC32\Data\Z\System\Install
+
+SISNAME=analyzeTool_stub
+PKGNAME=analyzeTool_stub
+
+$(TARGETDIR) :
+ @perl -S emkdir.pl "$(TARGETDIR)"
+
+do_nothing :
+ rem do_nothing
+
+SISFILE=$(TARGETDIR)\$(SISNAME).sis
+
+$(SISFILE) : ..\sis\$(PKGNAME).pkg
+ makesis -s $? $@
+
+#
+# The targets invoked by bld...
+#
+
+MAKMAKE : do_nothing
+
+RESOURCE : do_nothing
+
+SAVESPACE : do_nothing
+
+BLD : do_nothing
+
+FREEZE : do_nothing
+
+LIB : do_nothing
+
+CLEANLIB : do_nothing
+
+FINAL : $(TARGETDIR) $(SISFILE)
+
+CLEAN :
+ -erase $(SISFILE)
+
+RELEASABLES :
+ @echo $(SISFILE)
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/group/bld.inf Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,49 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include <platform_paths.hrh>
+
+
+#include "../commandlineengine/group/bld.inf"
+#include "../staticlib/group/bld.inf"
+#include "../storageserver/group/bld.inf"
+#include "../kerneleventhandler/group/bld.inf"
+#include "../analyzetoolcleaner/group/bld.inf"
+#include "../dynamicmemoryhook/group/bld.inf"
+
+PRJ_EXPORTS
+//../rom/analyzetool.iby CORE_IBY_EXPORT_PATH(tools,analyzetool.iby)
+../rom/analyzetool_rom.iby CORE_IBY_EXPORT_PATH(tools/rom,analyzetool_rom.iby)
+
+/*
+PRJ_MMPFILES
+#ifndef SBSV2
+ #ifdef MARM
+ gnumakefile atool_stub_sis.mk
+ #endif
+#endif
+
+PRJ_EXTENSIONS
+#ifdef SBSV2
+ #ifdef MARM
+ START EXTENSION app-services/buildstubsis
+ OPTION SRCDIR ../sis
+ OPTION SISNAME analyzeTool_stub
+ END
+ #endif
+#endif
+*/
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/inc/atlog.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,128 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Definitions of logging macros for Analyze Tool S60 modules.
+*
+*/
+
+#ifndef __ATLOG_H__
+#define __ATLOG_H__
+
+#ifdef _DEBUG
+//To enable/disable logging uncomment/comment the next line
+// #define LOGGING_ENABLED //Enable logging
+//Uncomment next to enable logging only LOGSTR1 lines
+// #define LOGGING_ENABLED_FAST //Logging only function names
+
+//Disable next to use file logging
+ #define USE_RDEBUG
+#endif
+
+//Do not alter the code below this
+
+#ifdef __KERNEL_MODE__
+
+ #ifdef LOGGING_ENABLED
+ #include <kernel.h>
+ #define LOGSTR1( AAA ) { Kern::Printf( AAA ); }
+ #define LOGSTR2( AAA, BBB ) { Kern::Printf( AAA, BBB ); }
+ #else
+ #define LOGSTR1( AAA )
+ #define LOGSTR2( AAA, BBB )
+ #endif
+
+#else // #ifdef __KERNEL_MODE__
+
+ #ifdef LOGGING_ENABLED
+
+// INCLUDES
+ #include <flogger.h>
+ #ifdef USE_RDEBUG
+ #include <e32svr.h>
+ #endif
+
+// CONSTANTS
+ _LIT( KAtLoggingFolder, "atlog" );
+ _LIT( KAtLoggingFile , "LOG.TXT" );
+ #define ONE_SPACE_MARGIN _S(" ")
+
+// ---------------------------------------------------------------------------------
+// Internal MACROS. Do not call these directly, use the External MACROS instead
+// ---------------------------------------------------------------------------------
+
+ #ifdef LOGGING_ENABLED_FAST
+
+ #ifdef USE_RDEBUG
+ #define INTERNAL_LOGSTR1( AAA ) { _LIT( logdes, AAA ); RDebug::Print( logdes() ); }
+ #else // RFileLogger is used
+ #define INTERNAL_LOGSTR1( AAA ) { _LIT( logdes, AAA ); RFileLogger::Write( KAtLoggingFolder(), KAtLoggingFile(), EFileLoggingModeAppend, logdes() ); }
+ #endif // USE_RDEBUG
+ #define INTERNAL_LOGSTR2( AAA, BBB )
+ #define INTERNAL_LOGSTR3( AAA, BBB, CCC )
+ #define INTERNAL_LOGMEM
+ #define INTERNAL_LOG( AAA )
+
+ #else
+
+ #ifdef USE_RDEBUG
+ #define INTERNAL_LOGDESC8( AAA ) { TBuf<100> tmp; if( sizeof( AAA ) < 100 ) tmp.Copy( AAA ); RDebug::Print( tmp );}
+ #define INTERNAL_LOGSTR1( AAA ) { _LIT( logdes, AAA ); RDebug::Print( logdes() ); }
+ #define INTERNAL_LOGSTR2( AAA, BBB ) { _LIT( logdes, AAA ); RDebug::Print( TRefByValue<const TDesC>( logdes()), BBB ); }
+ #define INTERNAL_LOGSTR3( AAA, BBB, CCC ) { _LIT( logdes, AAA ); RDebug::Print( TRefByValue<const TDesC>(logdes()), BBB, CCC ); }
+ #define INTERNAL_LOGMEM { _LIT( logdes, "Heap size: %i" ); TBuf<50> buf; TInt a; User::AllocSize( a ); buf.Format( logdes, a ); RDebug::Print( buf ); }
+ #define INTERNAL_LOG( AAA ) AAA
+ #else // RFileLogger is used
+ #define INTERNAL_LOGSTR1( AAA ) { _LIT( logdes, AAA ); RFileLogger::Write( KAtLoggingFolder(), KAtLoggingFile(), EFileLoggingModeAppend, logdes() ); }
+ #define INTERNAL_LOGSTR2( AAA, BBB ) { _LIT( logdes, AAA ); RFileLogger::WriteFormat( KAtLoggingFolder(), KAtLoggingFile(), EFileLoggingModeAppend, TRefByValue<const TDesC>( logdes()), BBB ); }
+ #define INTERNAL_LOGSTR3( AAA, BBB, CCC) { _LIT( logdes, AAA ); RFileLogger::WriteFormat( KAtLoggingFolder(), KAtLoggingFile(), EFileLoggingModeAppend, TRefByValue<const TDesC>(logdes()), BBB, CCC ); }
+ #define INTERNAL_LOGMEM { _LIT( logdes, "Heap size: %i" ); TMemoryInfoV1Buf info; UserHal::MemoryInfo(info); TInt freeMemory = info().iFreeRamInBytes; TBuf<50> buf; buf.Format( logdes, freeMemory ); RFileLogger::WriteFormat( KAtLoggingFolder(), KAtLoggingFile(), EFileLoggingModeAppend, buf ); }
+ #define INTERNAL_LOG( AAA ) AAA
+ #endif // USE_RDEBUG
+
+ #endif
+
+ #else
+
+ #define INTERNAL_LOGSTR1( AAA )
+ #define INTERNAL_LOGSTR2( AAA, BBB )
+ #define INTERNAL_LOGSTR3( AAA, BBB, CCC )
+ #define INTERNAL_LOGMEM
+ #define INTERNAL_LOG( AAA )
+
+ #endif
+
+// ---------------------------------------------------------------------------------
+// External MACROS. Use these in code
+// ---------------------------------------------------------------------------------
+// Logging of string
+// i.e.: LOGSTR1( "Whoo-haa!" );
+ #define LOGSTR1( AAA ) { INTERNAL_LOGSTR1( AAA ); }
+
+// Logging of string + integer value
+// i.e.: LOGSTR2( "CHttpd status %i:", iStatus );
+ #define LOGSTR2( AAA, BBB ) { INTERNAL_LOGSTR2( AAA, BBB ); }
+
+// Logging of descriptor + 2 integers
+// i.e.: LOGSTR3( "Jippii %i %i", val1, val2 );
+ #define LOGSTR3( AAA, BBB, CCC ) { INTERNAL_LOGSTR3( AAA, BBB, CCC ); }
+
+// Log heap size
+ #define LOGMEM { INTERNAL_LOGMEM }
+
+// Logging variable operations
+ #define LOG( AAA ) INTERNAL_LOG( AAA )
+
+#endif // #ifdef __KERNEL_MODE__
+
+#endif // __ATLOG_H__
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/kerneleventhandler/group/atoolkerneleventhandler.mmp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,51 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: The .mmp file for the AToolKernelEventHandler
+*
+*/
+
+#include <platform_paths.hrh>
+#include <kernel/kern_ext.mmh>
+#include "../../symbian_version.hrh"
+
+TARGET atoolkerneleventhandler.ldd
+TARGETTYPE ldd
+CAPABILITY ALL
+
+SMPSAFE
+
+USERINCLUDE ../inc
+USERINCLUDE ../../inc
+
+OS_LAYER_KERNEL_SYSTEMINCLUDE
+
+SOURCEPATH ../src
+
+SOURCE analyzetoolchannel.cpp
+SOURCE analyzetooldevice.cpp
+SOURCE analyzetooleventhandler.cpp
+
+LIBRARY flogger.lib
+#ifdef WINSCW
+LIBRARY emulator.lib
+ start wins
+ win32_headers
+ end
+#endif // WINSCW
+
+#if ( SYMBIAN_VERSION_SUPPORT >= SYMBIAN_3 ) || defined(BSW_FLEXIBLE_MEMORY_MODEL)
+MACRO MCL_ROBJECTIX
+#endif
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/kerneleventhandler/group/bld.inf Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,35 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include <platform_paths.hrh>
+
+PRJ_PLATFORMS
+ARMV5 WINSCW
+
+PRJ_EXPORTS
+../inc/analyzetool.h OS_LAYER_PLATFORM_EXPORT_PATH(analyzetool/analyzetool.h)
+../inc/atcommon.h OS_LAYER_PLATFORM_EXPORT_PATH(analyzetool/atcommon.h)
+../inc/analyzetool.inl OS_LAYER_PLATFORM_EXPORT_PATH(analyzetool/analyzetool.inl)
+../inc/analyzetooltraceconstants.h OS_LAYER_PLATFORM_EXPORT_PATH(analyzetool/analyzetooltraceconstants.h)
+
+PRJ_MMPFILES
+atoolkerneleventhandler.mmp
+
+PRJ_TESTMMPFILES
+../internal/tsrc/group/analyzetooldevicedrivertest.mmp
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/kerneleventhandler/inc/analyzetool.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,325 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Declaration of the class RAnalyzeTool.
+*
+*/
+
+
+#ifndef __ANALYZETOOL_H__
+#define __ANALYZETOOL_H__
+
+// INCLUDES
+#include <e32cmn.h>
+
+//Version information for command line engine.
+//Tells the version of AT core componenets.
+//ANALYZETOOL_CORE_VERSION_FOR_CLE 1.9.1
+
+// CONSTANTS
+inline TVersion KAnalyzeToolLddVersion() { return TVersion(1, 0, 1); }
+
+/* The name of the analyze tool device driver*/
+_LIT( KAnalyzeToolLddName, "AToolKernelEventHandler" );
+
+/* The priority of AnalyzeTool Dfc */
+const TInt KAnalyzeToolThreadPriority = 27;
+
+/* The name of the AnalyzeTool DFC */
+_LIT8( KAnalyzeToolThreadName, "AnalyzeToolThreadDfc" );
+
+/* The panic literal */
+_LIT( KClientPanic, "AnalyzeTool" );
+
+//const TInt KATMaxCallstackLength = 20;
+
+/* The device handler panic codes */
+enum TPanic
+ {
+ EPanicRequestPending,
+ EPanicNoRequestPending,
+ EPanicUnsupportedRequest
+ };
+
+// Size of following must be multiple of 4 bytes.
+
+class TMainThreadParams
+ {
+ public:
+ RAllocator* iAllocator;
+ TBool iAlone;
+ TUint iProcessId;
+ };
+typedef TPckgBuf<TMainThreadParams> TMainThreadParamsBuf;
+
+class TLibraryInfo
+ {
+ public:
+ TBuf8<KMaxLibraryName> iLibraryName;
+ TLinAddr iRunAddress;
+ TUint32 iSize;
+ TInt iIndex;
+ TUint iProcessId;
+ };
+
+typedef TPckgBuf<TLibraryInfo> TLibraryInfoBuf;
+
+class TCodesegInfo
+ {
+ public:
+ TBuf8<KMaxLibraryName> iFullName;
+ TLinAddr iRunAddress;
+ TUint32 iSize;
+ TInt iIndex;
+ TUint iProcessId;
+ TInt iCodesegIndex;
+ TLinAddr iFileEntryPoint;
+ TInt iFuntionCount;
+ TLibraryFunction iFirstFunction;
+ TModuleMemoryInfo iMemoryInfo;
+ };
+
+typedef TPckgBuf<TCodesegInfo> TCodesegInfoBuf;
+
+class TThreadParams
+ {
+ public:
+ TLinAddr iStackAddress;
+ TInt iStackSize;
+ TUint iThreadId;
+ };
+
+typedef TPckgBuf<TThreadParams> TThreadParamsBuf;
+
+class TProcessIdentityParams
+ {
+ public:
+ TBuf8<KMaxProcessName> iProcessName;
+ TInt iDynamicCount;
+ TInt iCodesegCount;
+ TUint iProcessId;
+ TUint iThreadId;
+ TLinAddr iStackAddress;
+ TInt iStackSize;
+ };
+
+typedef TPckgBuf<TProcessIdentityParams> TProcessIdentityParamsBuf;
+
+class TLibraryEventInfo
+ {
+ public:
+ enum TLibraryEvent
+ {
+ ELibraryAdded = 0,
+ ELibraryRemoved,
+ EKillThread
+ };
+
+ public:
+ TUint iProcessId;
+ TBuf8<KMaxLibraryName> iLibraryName;
+ TLinAddr iRunAddress;
+ TUint32 iSize;
+ TLibraryEvent iEventType;
+ TUint iThreadId;
+ };
+
+typedef TPckgBuf<TLibraryEventInfo> TLibraryEventInfoBuf;
+
+class TProcessHandleInfo
+ {
+ public:
+ TInt iProcessHandleCount;
+ TInt iThreadHandleCount;
+ TInt iIndex;
+ TInt iThreadCount;
+ TLinAddr iUserStackRunAddress;
+ TInt iUserStackSize;
+ TUint iProcessId;
+ };
+
+typedef TPckgBuf<TProcessHandleInfo> TProcessHandleInfoBuf;
+
+/**
+* A class for particular process's current handle count
+*/
+class TATProcessHandles
+ {
+ public:
+
+ /** The ID of the process. */
+ TUint iProcessId;
+
+ /** The number of current handles in the library. */
+ TInt iCurrentHandleCount;
+ };
+
+typedef TPckgBuf<TATProcessHandles> TATProcessHandlesBuf;
+
+class TClientCount
+ {
+ public:
+
+ /** The count of clients */
+ TInt iClientCount;
+ };
+
+typedef TPckgBuf<TClientCount> TClientCountBuf;
+
+class TATMemoryModel
+ {
+ public :
+ /* Memory model*/
+ TUint32 iMemoryModel;
+ };
+typedef TPckgBuf<TATMemoryModel> TATMemoryModelBuf;
+
+// CLASS DECLARATION
+
+/**
+* The user-side handle to a logical channel which provides functions to
+* open a channel and to make requests to a analyze tool device driver.
+*/
+
+class RAnalyzeTool : public RBusLogicalChannel
+ {
+
+ public:
+
+ /** Enumeration of supported functions */
+ enum TBasicAnalyzerControl
+ {
+ EGetProcessInfo = 0, /* The process information */
+ EGetCodesegInfo, /* The codesegment information */
+ EGetLibraryInfo, /* The library information */
+ EGetDynamicInfo, /* The count of dynamic code in the process */
+ ELibraryEvent, /* Subscribe events from library events */
+ ECancelLibraryEvent, /* Cancel subscribetion of library events */
+ ECurrentClientCount, /* The count of clients in device driver */
+ EMainThreadAlloctor,
+ EThreadStack,
+ EGetProcessHandle, /* Gets process global handles info*/
+ EGetCurrentHandles, /* Get a process's current handle count */
+ EGetMemoryModel
+ };
+
+#ifndef __KERNEL_MODE__
+
+ /**
+ * Opens a handle to a logical channel.
+ * @return TInt Returns KErrNone, if successful or otherwise
+ one of the other system-wide error codes
+ */
+ inline TInt Open();
+
+ /**
+ * Acquires process information.
+ * @param aProcessIdentityParams The process information which
+ is filled by the device driver
+ * @return TInt Returns KErrNone, if successful
+ otherwise one of the other system-wide error codes
+ */
+ inline TInt GetProcessInfo(
+ TProcessIdentityParamsBuf& aProcessIdentityParams );
+
+ /**
+ * Acquires codeseg information.
+ * @param aCodesegInfo The codeseg information which
+ is filled by the device driver
+ * @return TInt Returns KErrNone, if successful
+ otherwise one of the other system-wide error codes
+ */
+ inline TInt GetCodesegInfo( TCodesegInfoBuf& aCodesegInfo );
+
+ /**
+ * Acquires library information.
+ * @param aLibraryInfo The library information which
+ is filled by the device driver
+ * @return TInt Returns KErrNone, if successful
+ otherwise one of the other system-wide error codes
+ */
+ inline TInt GetLibraryInfo( TLibraryInfoBuf& aLibraryInfo );
+
+ /**
+ * Subscribes library event.
+ * @param aStatus The request status object for this request.
+ * @param aLibraryInfo The library information which
+ is filled by the device driver
+ * @return TInt Returns KErrNone, if successful
+ otherwise one of the other system-wide error codes
+ */
+ inline void LibraryEvent( TRequestStatus& aStatus,
+ TLibraryEventInfo& aLibraryInfo );
+
+ /**
+ * Cancels subscribetion of the library event.
+ */
+ inline void CancelLibraryEvent();
+
+ /**
+ * Acquires device driver current client count.
+ * @param aClientCount A reference to TInt which is
+ updated by the device driver.
+ * @return TInt Returns KErrNone, if successful
+ otherwise one of the other system-wide error codes
+ */
+ inline TInt ClientCount( TClientCountBuf& aClientCount );
+
+ /**
+ * Acquires process main thread RAllocator
+ * @param aMainThreadParams The main thread information which
+ is filled by the device driver
+ * @return TInt Returns KErrNone, if successful
+ otherwise one of the other system-wide error codes
+ */
+ inline TInt MainThreadAlloctor( TMainThreadParamsBuf& aMainThreadParams );
+
+ /**
+ * Acquires main thread stack address.
+ * @param aThreadStack Pointer to the TThreadParams object.
+ * @return TInt Returns KErrNone, if successful
+ otherwise one of the other system-wide error codes
+ */
+ inline TInt ThreadStack( TThreadParamsBuf& aThreadStack );
+
+ /**
+ * Acquires information about process global handles.
+ * @param aProcessHandleInfo Pointer to the TProcessHandleInfo object.
+ * @return TInt Returns KErrNone, if successful
+ otherwise one of the other system-wide error codes
+ */
+ inline TInt GetProcessHandleInfo( TProcessHandleInfoBuf& aProcessHandleInfo );
+
+ /**
+ * Acquires a process's current handle count.
+ * @param aProcessHandles Pointer to the TATProcessHandles object.
+ * @return TInt Returns KErrNone, if successful
+ otherwise one of the other system-wide error codes
+ */
+ inline TInt GetCurrentHandleCount( TATProcessHandlesBuf& aProcessHandles );
+
+ /**
+ * Acquires memory model system uses.
+ * @param aMemoryModel pointer to the TATMemoryModelBuf object.
+ */
+ inline TInt GetMemoryModel( TATMemoryModelBuf& aMemoryModel );
+
+#endif // #ifndef __KERNEL_MODE__
+ };
+
+// INLINES
+#include <analyzetool/analyzetool.inl>
+
+#endif // #ifndef __ANALYZETOOL_H__
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/kerneleventhandler/inc/analyzetool.inl Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,159 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Definitions for inline methods of the class RAnalyzeTool.
+*
+*/
+
+
+#ifndef __ANALYZETOOL_INL
+#define __ANALYZETOOL_INL
+
+#ifndef __KERNEL_MODE__
+
+// ----------------------------------------------------------------------------
+// RAnalyzeTool::Open()
+// Opens a handle to a analyze tool device driver
+// ----------------------------------------------------------------------------
+//
+inline TInt RAnalyzeTool::Open()
+ {
+ return DoCreate( KAnalyzeToolLddName,
+ KAnalyzeToolLddVersion(),
+ KNullUnit,
+ NULL,
+ NULL,
+ EOwnerProcess );
+ }
+
+// ----------------------------------------------------------------------------
+// RAnalyzeTool::GetProcessInfo()
+// Acquires process information.
+// ----------------------------------------------------------------------------
+//
+inline TInt RAnalyzeTool::GetProcessInfo(
+ TProcessIdentityParamsBuf& aProcessIdentityParams )
+ {
+ return DoControl( EGetProcessInfo, &aProcessIdentityParams, NULL );
+ }
+
+// ----------------------------------------------------------------------------
+// RAnalyzeTool::GetCodesegInfo()
+// Acquires codeseg information.
+// ----------------------------------------------------------------------------
+//
+inline TInt RAnalyzeTool::GetCodesegInfo( TCodesegInfoBuf& aCodesegInfo )
+ {
+ return DoControl( EGetCodesegInfo, &aCodesegInfo, NULL );
+ }
+
+// ----------------------------------------------------------------------------
+// RAnalyzeTool::GetLibraryInfo()
+// Symbian 2nd phase constructor can leave.
+// ----------------------------------------------------------------------------
+//
+inline TInt RAnalyzeTool::GetLibraryInfo( TLibraryInfoBuf& aLibraryinfo )
+ {
+ return DoControl( EGetLibraryInfo, &aLibraryinfo, NULL );
+ }
+
+// ----------------------------------------------------------------------------
+// RAnalyzeTool::LibraryEvent()
+// Subscribes library event.
+// ----------------------------------------------------------------------------
+//
+inline void RAnalyzeTool::LibraryEvent( TRequestStatus& aStatus,
+ TLibraryEventInfo& aLibInfo )
+ {
+ return DoRequest( ELibraryEvent, aStatus, (TAny*)&aLibInfo );
+ }
+
+// ----------------------------------------------------------------------------
+// RAnalyzeTool::CancelLibraryEvent()
+// Cancels subscribetion of the library event.
+// ----------------------------------------------------------------------------
+//
+inline void RAnalyzeTool::CancelLibraryEvent()
+ {
+ DoControl( ECancelLibraryEvent, NULL, NULL);
+ }
+
+// ----------------------------------------------------------------------------
+// RAnalyzeTool::ClientCount()
+// Acquires the count of device driver current users
+// ----------------------------------------------------------------------------
+//
+inline TInt RAnalyzeTool::ClientCount( TClientCountBuf& aClientCount )
+ {
+ return DoControl( ECurrentClientCount, &aClientCount, NULL );
+ }
+
+// ----------------------------------------------------------------------------
+// RAnalyzeTool::MainThreadAlloctor()
+// Acquires information about process main thread
+// ----------------------------------------------------------------------------
+//
+inline TInt RAnalyzeTool::MainThreadAlloctor(
+ TMainThreadParamsBuf& aMainThreadParams )
+ {
+ return DoControl( EMainThreadAlloctor, &aMainThreadParams, NULL );
+ }
+
+// ----------------------------------------------------------------------------
+// RAnalyzeTool::ThreadStack()
+// Acquires main thread stack address.
+// ----------------------------------------------------------------------------
+//
+inline TInt RAnalyzeTool::ThreadStack( TThreadParamsBuf& aThreadStack )
+ {
+ return DoControl( EThreadStack, &aThreadStack, NULL );
+ }
+
+// ----------------------------------------------------------------------------
+// RAnalyzeTool::GetProcessHandleInfo()
+// Acquires information about process handles
+// ----------------------------------------------------------------------------
+//
+inline TInt RAnalyzeTool::GetProcessHandleInfo(
+ TProcessHandleInfoBuf& aProcessHandleInfo )
+ {
+ return DoControl( EGetProcessHandle, &aProcessHandleInfo, NULL );
+ }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::GetCurrentHandleCount()
+// Acquires a process's current handle count
+// -----------------------------------------------------------------------------
+//
+inline TInt RAnalyzeTool::GetCurrentHandleCount(
+ TATProcessHandlesBuf& aProcessHandles )
+ {
+ return DoControl( EGetCurrentHandles, &aProcessHandles, NULL );
+ }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::GetMemoryModel()
+// Acquires memory model system uses.
+// -----------------------------------------------------------------------------
+//
+inline TInt RAnalyzeTool::GetMemoryModel(
+ TATMemoryModelBuf& aMemoryModel )
+ {
+ return DoControl( EGetMemoryModel, &aMemoryModel, NULL );
+ }
+
+#endif // #ifndef __KERNEL_MODE__
+
+#endif // __ANALYZETOOL_INL
+
+// End of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/kerneleventhandler/inc/analyzetoolchannel.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,213 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Declaration of the class DAnalyzeToolChannel
+*
+*/
+
+
+#ifndef __ANALYZETOOLCHANNEL_H__
+#define __ANALYZETOOLCHANNEL_H__
+
+// INCLUDES
+#include <analyzetool/analyzetool.h>
+#include <kernel/kernel.h>
+#ifdef __WINSCW__
+#include <memmodel/emul/win32/memmodel.h>
+#endif // __WINSCW__
+
+// FORWARD DECLARATIONS
+class DAnalyzeToolEventHandler;
+
+// CLASS DECLARATION
+
+/**
+* The implementation of the abstract base class for a logical channel.
+*/
+class DAnalyzeToolChannel : public DLogicalChannel
+ {
+ public:
+
+ /**
+ * C++ default constructor.
+ */
+ DAnalyzeToolChannel();
+
+ /**
+ * Destructor.
+ */
+ ~DAnalyzeToolChannel();
+
+ protected: // from DLogicalChannel
+
+ /**
+ * Creates the logical channel.
+ * @param aUnit A unit of the device.
+ * @param anInfo A pointer to an explicit 8-bit descriptor containing
+ extra information for the physical device
+ * @param aVer The required version of the logical device
+ * @return TInt Returns KErrNone, if successful
+ otherwise one of the other system-wide error codes
+ */
+ virtual TInt DoCreate( TInt aUnit,
+ const TDesC8* anInfo,
+ const TVersion &aVer );
+
+ /**
+ * Handles a client request.
+ * @param aFunction The requested function.
+ * @param a1 A 32-bit value passed to the kernel-side. Its meaning
+ depends on the device driver requirements
+ * @param a2 A 32-bit value passed to the kernel-side. Its meaning
+ depends on the device driver requirements
+ * @param aMessage Reference to received thread message.
+ * @return TInt Returns KErrNone, if successful
+ otherwise one of the other system-wide error codes
+ */
+ virtual TInt DoControl( TInt aFunction, TAny* a1, TAny* a2, TThreadMessage& aMessage );
+
+ /**
+ * Processes a message for this logical channel.
+ * This function is called in the context of a DFC thread.
+ * @param aMsg The message to process.
+ */
+ virtual void HandleMsg( TMessageBase* aMsg );
+
+ /**
+ * Handles a client asynchronous request.
+ * @param aFunction The requested function.
+ * @param aStatus Pointer to client TRequestStatus.
+ * @param a1 A 32-bit value passed to the kernel-side. Its meaning
+ depends on the device driver requirements
+ * @param a2 A 32-bit value passed to the kernel-side. Its meaning
+ depends on the device driver requirements
+ * @param aMessage Reference to received thread message.
+ * @return TInt Returns KErrNone, if successful
+ otherwise one of the other system-wide error codes
+ */
+ virtual TInt DoRequest( TInt aFunction,
+ TRequestStatus* aStatus,
+ TAny* a1,
+ TAny* a2,
+ TThreadMessage& aMessage );
+
+ /**
+ * Cancels outstanding asynchronous request.
+ */
+ virtual void DoCancel();
+
+ private:
+
+ /**
+ * Acquires current process information
+ * @param aProcessInfo Pointer to the TProcessIdentityParams object.
+ * @return TInt Returns KErrNone, if successful
+ otherwise one of the other system-wide error codes
+ */
+ TInt GetProcessInfo( TAny* aProcessInfo, TThreadMessage& aMessage );
+
+ /**
+ * Acquires codeseg information.
+ * @param aCodesegInfo Pointer to the TCodesegInfo object.
+ * @return TInt Returns KErrNone, if successful
+ otherwise one of the other system-wide error codes
+ */
+ TInt GetCodesegInfo( TAny* aCodesegInfo, TThreadMessage& aMessage );
+
+ /**
+ * Acquires library information.
+ * @param aLibraryInfo Pointer to the TLibraryInfo object.
+ * @return TInt Returns KErrNone, if successful
+ otherwise one of the other system-wide error codes
+ */
+ TInt GetLibraryInfo( TAny* aLibraryInfo, TThreadMessage& aMessage );
+
+ /**
+ * Acquires information about process main thread RAllocator.
+ * @param aMainThreadParams Pointer to the TMainThreadParams object.
+ * @return TInt Returns KErrNone, if successful
+ otherwise one of the other system-wide error codes
+ */
+ TInt MainThreadAllocator( TAny* aMainThreadParams,
+ TThreadMessage& aMessage );
+
+ /**
+ * Acquires main thread stack address.
+ * @param aThreadStack Pointer to the TThreadParams object.
+ * @return TInt Returns KErrNone, if successful
+ otherwise one of the other system-wide error codes
+ */
+ TInt ThreadStack( TAny* aThreadStack,
+ TThreadMessage& aMessage );
+
+ /**
+ * Acquires information about process global handles.
+ * @param aProcessHandleInfo Pointer to the TProcessHandleInfo object.
+ * @return TInt Returns KErrNone, if successful
+ otherwise one of the other system-wide error codes
+ */
+ TInt GetProcessHandleInfo( TAny* aProcessHandleInfo,
+ TThreadMessage& aMessage );
+
+ /**
+ * Acquires a process's current handle count.
+ * @param aProcessHandles Pointer to the TATProcessHandles object.
+ * @return TInt Returns KErrNone, if successful
+ otherwise one of the other system-wide error codes
+ */
+ TInt GetCurrentHandleCount( TAny* aProcessHandles,
+ TThreadMessage& aMessage );
+
+ /**
+ * Acquires the count of current device driver users.
+ * @param aClientCount A reference to TInt variable
+ * @return TInt Returns KErrNone, if successful
+ * otherwise one of the other system-wide error codes
+ */
+ TInt ClientCount( TAny* aClientCount,
+ TThreadMessage& aMessage );
+
+ /**
+ * Acquires memory model system uses.
+ * @return TInt Returns KErrNone, if successful
+ * otherwise one of the other system-wide error codes
+ */
+ TInt GetMemoryModel( TAny* aMemoryModel,
+ TThreadMessage& aMessage );
+
+ #ifdef __WINSCW__
+ /**
+ * Gets module dependencies
+ * @param aModule Module handle
+ */
+ void GetModuleDependencies( HMODULE aModule );
+ #endif // __WINSCW__
+
+ private: //Member variables
+
+ /* Handler which receives kernel events */
+ DAnalyzeToolEventHandler* iEventHandler;
+
+ #ifdef __WINSCW__
+ /* Code segment array */
+ RArray<TCodesegInfo> iCodeSeg;
+ #endif // __WINSCW__
+
+ /* A DFC queue for communication */
+ TDynamicDfcQue* iOwnDfcQ;
+
+ };
+
+#endif // #ifndef __ANALYZETOOLCHANNEL_H__
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/kerneleventhandler/inc/analyzetooldevice.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,68 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Declaration of the class DAnalyzeToolDevice.
+*
+*/
+
+
+#ifndef __ANALYZETOOLEVICE_H__
+#define __ANALYZETOOLEVICE_H__
+
+// INCLUDES
+#include <analyzetool/analyzetool.h>
+#include <kernel/kernel.h>
+
+// CLASS DECLARATION
+
+/**
+* The implementation of the abstract base class for an LDD factory object.
+*/
+
+class DAnalyzeToolDevice : public DLogicalDevice
+ {
+ public:
+
+ /**
+ * C++ default constructor.
+ */
+ DAnalyzeToolDevice();
+
+ public: // from DLogicalDevice
+
+ /**
+ * Second stage constructor.
+ @return KErrNone or standard error code.
+ */
+ virtual TInt Install();
+
+ /**
+ * Gets the driver's capabilities.
+ @param aDes A user-side descriptor into which capabilities
+ information is to be written.
+ */
+ virtual void GetCaps( TDes8& aDes ) const;
+
+ /**
+ * Called by the kernel's device driver framework to
+ * create a Logical Channel.
+ @param aChannel Set to point to the created Logical Channel
+ @return KErrNone or standard error code.
+ */
+ virtual TInt Create( DLogicalChannelBase*& aChannel );
+ };
+
+
+#endif // __ANALYZETOOLEVICE_H__
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/kerneleventhandler/inc/analyzetooleventhandler.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,168 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Declaration of the class DAnalyzeToolEventHandler.
+*
+*/
+
+
+#ifndef __ANALYZETOOLEVENTHANDLER_H__
+#define __ANALYZETOOLEVENTHANDLER_H__
+
+// INCLUDES
+#include <analyzetool/analyzetool.h>
+#include "atlog.h"
+#include <kernel/kernel.h>
+
+// CLASS DECLARATION
+
+/**
+* Callback class for kernel events
+*/
+
+class DAnalyzeToolEventHandler : public DKernelEventHandler
+ {
+ public:
+
+ /**
+ * C++ default constructor.
+ */
+ inline DAnalyzeToolEventHandler( TDfcQue* aDfcQ );
+
+ /**
+ * Destructor.
+ */
+ ~DAnalyzeToolEventHandler();
+
+ /**
+ * Second stage constructor.
+ * @param aDevice A pointer to device where the event handler belongs.
+ * @param aProcessId Owner process id.
+ * @return TInt Returns KErrNone, if successful
+ otherwise one of the other system-wide error codes
+ */
+ TInt Create( DLogicalDevice* aDevice, const TUint aProcessId );
+
+ /**
+ * Subscribes library event.
+ * @param aStatus The request status object for this request.
+ * @param aLibraryInfo The library information which
+ is filled by the device driver
+ * @param aMessage Reference to received thread message.
+ * @return TInt Returns KErrNone, if successful
+ otherwise one of the other system-wide error codes
+ */
+ void InformLibraryEvent( TRequestStatus* aStatus,
+ TAny* aLibraryInfo,
+ TThreadMessage& aMessage );
+
+ /**
+ * Cancels subscribetion of the library event.
+ */
+ void CancelInformLibraryEvent();
+
+ /**
+ * Static function for DFC events.
+ * @param aPtr Pointer to DAnalyzeToolEventHandler object.
+ */
+ static void EventDfc( TAny* aPtr );
+
+ private:
+
+ /**
+ * Pointer to callback function called when an event occurs.
+ * @param aEvent Designates what event is dispatched.
+ * @param a1 Event-specific paramenter.
+ * @param a2 Event-specific paramenter.
+ * @param aThis A pointer to the event handler
+ * @return TUint Bitmask returned by callback function.
+ */
+ static TUint EventHandler( TKernelEvent aEvent,
+ TAny* a1,
+ TAny* a2,
+ TAny* aThis );
+
+ private:
+
+ /**
+ * Handles the EEventAddLibrary and EEventRemoveLibrary events
+ * @param aLib* A pointer to added/removed library.
+ * @param aThread* A pointer to thread where the libary is.
+ * @param aInfo* A reference class to be written to the client
+ */
+ void HandleLibraryEvent( DLibrary* aLib,
+ DThread* aThread,
+ TLibraryEventInfo& aInfo );
+
+ /**
+ * Handles the EEventKillThread events
+ * @param aThread* A pointer to the thread being terminated.
+ * @param aInfo* A reference class
+ */
+ void HandleKillThreadEvent( DThread* aThread,
+ TLibraryEventInfo& aInfo );
+
+ /**
+ * Informs client about the occured event
+ */
+ void DoEventComplete();
+
+ private:
+
+ /* Mutex for serializing access to event handler */
+ DMutex* iHandlerMutex;
+
+ /* Mutex fof serializing access to event handler variables */
+ DMutex* iDataMutex;
+
+ /* If the client is a RAM-loaded LDD (or PDD), it is possible for the DLL to
+ be unloaded while the handler is still in use. This would result in an
+ exception. To avoid this, the handler must open a reference to the
+ DLogicalDevice (or DPhysicalDevice) and close it in its d'tor. */
+ DLogicalDevice* iDevice;
+
+ /* Owner process ID */
+ TUint iProcessId;
+
+ /* Event array */
+ RArray<TLibraryEventInfo> iEventArray;
+
+ /* Pointer to client's TRequestStatus */
+ TRequestStatus* iClientRequestStatus;
+
+ /* Pointer to client's thread */
+ DThread* iClientThread;
+
+ /* Pointer to client's TLibraryEventInfo */
+ TAny* iClientInfo;
+
+ /* DFC for informing events to the client */
+ TDfc iEventDfc;
+ };
+
+// ----------------------------------------------------------------------------
+// DAnalyzeToolEventHandler::DAnalyzeToolEventHandler()
+// C++ default constructor.
+// ----------------------------------------------------------------------------
+//
+inline DAnalyzeToolEventHandler::DAnalyzeToolEventHandler( TDfcQue* aDfcQ ) :
+ DKernelEventHandler( EventHandler, this ),
+ iEventDfc( EventDfc, this, 1 )
+ {
+ LOGSTR1( "ATDD DAnalyzeToolEventHandler::DAnalyzeToolEventHandler()" );
+ iEventDfc.SetDfcQ( aDfcQ );
+ }
+
+#endif // __ANALYZETOOLEVENTHANDLER_H__
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/kerneleventhandler/inc/analyzetooltraceconstants.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,171 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Common declarations/definitions for Analyze Tool.
+*
+*/
+
+
+
+#ifndef __ANALYZETOOLTRACECONSTANTS_H__
+#define __ANALYZETOOLTRACECONSTANTS_H__
+
+#include <analyzetool/atcommon.h>
+
+// Trace version information.
+const TUint KATTraceVersion = 0x2;
+
+// The default logging mode
+const TATLogOption KDefaultLoggingMode = EATLogToTrace;
+
+// When needed, update the storage data file's version number directly inside
+// the _LIT8 macro. Note, if you change this string, also remember to update
+// the constant "KVersionStringLength" below.
+
+_LIT8( KDataFileVersion, "DATA_FILE_VERSION 11\r\n" );
+_LIT8( KProcessStart, "PROCESS_START %S %x " );
+_LIT16( KProcessStart16, "PROCESS_START %S %x " );
+_LIT8( KDllLoad, "DLL_LOAD %S %Lx %x %x\r\n" );
+_LIT16( KDllLoad16, "DLL_LOAD %S %Lx %x %x\r\n" );
+_LIT8( KDllUnload, "DLL_UNLOAD %S %Lx %x %x\r\n" );
+_LIT16( KDllUnload16, "DLL_UNLOAD %S %Lx %x %x\r\n" );
+_LIT8( KProcessEnd, "PROCESS_END %x " );
+_LIT16( KProcessEnd16, "PROCESS_END %x " );
+_LIT8( KProcessEndAbnormal, "PROCESS_END %x ABNORMAL " );
+_LIT8( KMemoryLeak, "MEM_LEAK " ); // Remember to update value of KMemoryLeak when changing this.
+_LIT8( KHandleLeak, "HANDLE_LEAK %S %x\r\n" );
+_LIT16( KHandleLeak16, "HANDLE_LEAK %S %x\r\n" );
+_LIT8( KErrorOccured, "ERROR_OCCURED %d " );
+_LIT8( KLoggingCancelled, "LOGGING_CANCELLED %x\r\n" );
+_LIT8( KNewLine, "\r\n" );
+_LIT8( KHexaNumber, " %x" );
+_LIT8( KSpace, " " );
+_LIT8( KUdeb, "UDEB" );
+_LIT8( KUrel, "UREL" );
+
+// Constants for logging through debug channel
+_LIT( KTraceMessage, "PCSS %x %S" );
+_LIT( KMemoryAllocHeader, "ALLOCH " );
+_LIT( KMemoryAllocFragment, "ALLOCF " );
+_LIT( KMemoryFreedHeader, "FREEH " );
+_LIT( KMemoryFreedFragment, "FREEF " );
+_LIT( KSpaceTrace, " " );
+_LIT( KNewLineTrace, "\r\n" );
+_LIT( KHexaNumberTrace, " %x" );
+_LIT( KProcessEndTrace, "PROCESS_END %x " );
+_LIT( KProcessEndAbnormalTrace, "PROCESS_END %x ABNORMAL " );
+_LIT( KErrorOccuredTrace, "ERROR_OCCURED %d " );
+_LIT( KSubtestStart, "TEST_START " );
+_LIT( KSubtestEnd, "TEST_END " );
+_LIT8( KEmpty, "" );
+_LIT( KOpenSquareBracket, "[" );
+_LIT( KCloseSquareBracket, "]" );
+_LIT( KUnderLine, "_" );
+// File name format
+_LIT( KFormat, "%S%S%02d%S");// pad char="0", field width=2
+
+// A string for setting time January 1st, 1970 AD nominal Gregorian
+_LIT( KJanuaryFirst1970, "19700000:000000.000000" );
+
+// Module name when it cannot be defined
+_LIT8( KUnknownModule, "Unknown" );
+_LIT16( KUnknownModule16, "Unknown" );
+
+// Constant time variable used to calculate timestamps for pc side.
+const TInt64 KMicroSecondsAt1970 = 62168256000000000;
+
+// The length of the string KDataFileVersion
+const TInt KVersionStringLength = 22;
+
+// The length of the string KMemoryLeak
+const TInt KMemleakLength = 9;
+
+// The maximum length of one word (32 bits) represented in the hexadecimal text format
+// without "0x" prefix
+const TInt KHexa32Length = 8;
+
+// The maximum length of one word (32 bits) represented in the decimal text format
+const TInt KDec32Length = 10;
+
+// The maximum length of a TInt64 represented in the hexadecimal text format without
+// "0x" prefix
+const TInt KHexa64Length = 16;
+
+// The length of one space character in text
+const TInt KSpaceLength = 1;
+
+// The length of the combination of carriage return and new line characters.
+const TInt KNewlineLength = 2;
+
+// The maximum length of the "PROCESS_START..." buffer. The first number is length of
+// the line tag and one space character (see the descriptor constants above).
+const TInt KProcessStartBufLength = 16 + KMaxProcessName + KSpaceLength + KHexa32Length +
+ KSpaceLength + KHexa64Length + KHexa32Length + KNewlineLength;
+
+// The maximum length of the "DLL_LOAD..." buffer. The first number is length of
+// the line tag and one space character (see the descriptor constants above).
+const TInt KDllLoadBufLength = 9 + KMaxLibraryName + KSpaceLength + KHexa64Length + KSpaceLength +
+ KHexa32Length + KSpaceLength + KHexa32Length + KNewlineLength;
+
+// The maximum length of the "DLL_UNLOAD..." buffer. The first number is length of
+// the line tag and one space character (see the descriptor constants above).
+const TInt KDllUnloadBufLength = 11 + KMaxLibraryName + KHexa64Length + KSpaceLength + KSpaceLength +
+ KHexa32Length + KSpaceLength + KHexa32Length + KNewlineLength;
+
+// The maximum length of the "PROCESS_END..." buffer. The first number is length of
+// the line tag and one space character (see the descriptor constants above).
+const TInt KProcessEndBufLength = 12 + KHexa32Length + KSpaceLength +
+ KHexa64Length + KNewlineLength;
+
+// The maximum length of the "ERROR_OCCURED..." buffer. The first number is length of
+// the line tag and one space character (see the descriptor constants above).
+const TInt KErrOccuredBufLength = 14 + KDec32Length + KSpaceLength +
+ KHexa64Length + KNewlineLength;
+
+// The maximum length of the "ALLOCH / ALLOCF..." buffer.
+const TInt KMemAllocBufLength = 255;
+
+// The maximum length of the "FREE..." buffer.
+const TInt KMemFreedBufLength = 255;
+
+// The maximum length of the "HANDLE_LEAK..." buffer. The first number is length of
+// the line tag and one space character (see the descriptor constants above).
+const TInt KHandleLeakBufLength = 12 + KMaxLibraryName + KSpaceLength +
+ KHexa32Length + KNewlineLength;
+
+// The maximum length of the "TEST_START..." buffer. The first number is length of
+// the line tag and one space character (see the descriptor constants above).
+const TInt KTestStartBufLength = 11 + KHexa64Length + KSpaceLength +
+ KATMaxSubtestIdLength + KSpaceLength + KHexa64Length + KNewlineLength;
+
+// The maximum length of the "TEST_END..." buffer. The first number is length of
+// the line tag and one space character (see the descriptor constants above).
+const TInt KTestEndBufLength = 9 + KHexa64Length + KSpaceLength +
+ KATMaxSubtestIdLength + KSpaceLength + KHexa64Length + KNewlineLength;
+
+// The maximun length of the "LOGGING_CANCELLED..." buffer. The first number is the
+// length of the line tag and one space character (see the descriptor constants above).
+const TInt KCancelBufLength = 18 + KHexa64Length + KNewlineLength;
+
+// The maximun length of the "PROCESS_END %x ABNORMAL..." buffer. The first number is length of
+// the line tag and one space character (see the descriptor constants above).
+const TInt KEndAbnormalBufLength = 22 + KHexa32Length + KHexa64Length +
+ KSpaceLength + KNewlineLength;
+
+// The maximun length of the file name extension buffer.
+const TInt KExtensionLength = 50;
+
+// The maximun length of the process UID3 buffer.
+const TInt KProcessUidLength = 20;
+
+#endif // __ANALYZETOOLTRACECONSTANTS_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/kerneleventhandler/inc/atcommon.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,108 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Common declarations/definitions for Analyze Tool.
+*
+*/
+
+
+#ifndef ATCOMMON_H_
+#define ATCOMMON_H_
+
+// CONSTANTS
+const TInt KATMaxCallstackLength = 256;
+const TInt KATMaxFreeCallstackLength = 256;
+const TInt KATMaxSubtestIdLength = 256;
+
+// The following constants only limit the configuration UI.
+// The bigger the number is, the more space will be allocated run-time
+// by the client. So, change with care.
+const TInt KATMaxProcesses = 20;
+const TInt KATMaxDlls = 30;
+
+// Constants defining call stack address range in multiple memory model.
+const TInt32 KATMultipleMemoryModelLowLimit = 0x70000000;
+const TInt32 KATMultipleMemoryModelHighLimit = 0x90000000;
+
+
+// CLASS DECLARATIONS
+
+/**
+* A class for storing process information
+*/
+class TATProcessInfo
+ {
+ public:
+
+ /** The ID of the process. */
+ TUint iProcessId;
+
+ /** The name of the process. */
+ TBuf8<KMaxProcessName> iProcessName;
+
+ /** The starting time of the process. */
+ TInt64 iStartTime;
+ };
+
+
+// ENUMERATIONS
+
+/**
+* Enumeration for different logging modes of Analyze Tool
+*/
+enum TATLogOption
+ {
+ /** Using the default. */
+ EATUseDefault = 0,
+
+ /** Logging to a file in S60. */
+ EATLogToFile,
+
+ /** Logging to debug channel. */
+ EATLogToTrace,
+
+ /** Logging to debug channel bypassing storage server. */
+ EATLogToTraceFast,
+
+ /** Logging switched off. */
+ EATLoggingOff
+ };
+
+/**
+* Class which supports interfacing with AnalyzeTool exported
+* functions. Mainly meant for STIF integration.
+*/
+class AnalyzeToolInterface
+ {
+ public:
+
+ /**
+ * This function starts subtest with a given name.
+ * @param aSubtestId The name identifying this particular sub test. The length
+ * of this descriptor must not be greater than KATMaxSubtestIdLength, or
+ * otherwise the method raises a STSEClient: 2 panic.
+ */
+ IMPORT_C static void StartSubTest( const TDesC8& aSubtestId );
+
+ /**
+ * This function stops a subtest with a given name.
+ * @param aSubtestId The name identifying this particular sub test. The length
+ * of this descriptor must not be greater than KATMaxSubtestIdLength, or
+ * otherwise the method raises a STSEClient: 2 panic.
+ */
+ IMPORT_C static void StopSubTest( const TDesC8& aSubtestId );
+
+ };
+
+
+#endif /*ATCOMMON_H_*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/kerneleventhandler/sis/analyzetooldevicedriver.pkg Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,33 @@
+;
+; Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+; All rights reserved.
+; This component and the accompanying materials are made available
+; under the terms of "Eclipse Public License v1.0"
+; which accompanies this distribution, and is available
+; at the URL "http://www.eclipse.org/legal/epl-v10.html".
+;
+; Initial Contributors:
+; Nokia Corporation - initial contribution.
+;
+; Contributors:
+;
+; Description:
+;
+
+;Language - standard language definitions
+&EN
+
+; standard SIS file header
+#{"AnalyzeToolDeviceDriver"},(0xEDF5A8A1),1,8,1
+
+;Localised Vendor name
+%{"Vendor-EN"}
+
+;Unique Vendor name
+:"Vendor"
+
+;Supports Series 60 v 3.0
+[0x101F7961], 0, 0, 0, {"Series60ProductID"}
+
+; 1 File to install
+"\epoc32\release\armv5\urel\atoolkerneleventhandler.ldd"-"!:\sys\bin\atoolkerneleventhandler.ldd"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/kerneleventhandler/src/analyzetoolchannel.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,1019 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Definitions for the class DAnalyzeToolChannel.
+*
+*/
+
+
+// INCLUDE FILES
+#include "analyzetoolchannel.h"
+#include "analyzetooldevice.h"
+#include "analyzetooleventhandler.h"
+
+#include <kernel/kern_priv.h>
+#ifdef __WINSCW__
+#include <emulator.h>
+#endif // __WINSCW__
+
+#include "atlog.h"
+
+// ================= MEMBER FUNCTIONS =========================================
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::DoCreate()
+// Creates the logical channel.
+// -----------------------------------------------------------------------------
+//
+TInt DAnalyzeToolChannel::DoCreate( TInt /*aUnit*/,
+ const TDesC8* /*aInfo*/, const TVersion &aVer )
+ {
+ LOGSTR1( "ATDD DAnalyzeToolChannel::DoCreate()" );
+
+ // Check client version.
+ if ( !Kern::QueryVersionSupported( KAnalyzeToolLddVersion(), aVer ) )
+ {
+ return KErrNotSupported;
+ }
+
+ TInt error = Kern::DynamicDfcQCreate( iOwnDfcQ,
+ KAnalyzeToolThreadPriority,
+ KAnalyzeToolThreadName );
+
+ if ( KErrNone != error )
+ {
+ return error;
+ }
+
+ SetDfcQ( iOwnDfcQ );
+
+ iMsgQ.Receive();
+
+ // Create the event handler
+ iEventHandler = new DAnalyzeToolEventHandler( iOwnDfcQ );
+
+ // Check that everything is OK
+ if ( !iEventHandler )
+ {
+ return KErrNoMemory;
+ }
+
+ // 2nd stage constructor for event handler
+ return iEventHandler->Create( iDevice, Kern::CurrentProcess().iId );
+ }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::DAnalyzeToolChannel()
+// Constructor.
+// -----------------------------------------------------------------------------
+//
+DAnalyzeToolChannel::DAnalyzeToolChannel()
+ {
+ LOGSTR1( "ATDD DAnalyzeToolChannel::DAnalyzeToolChannel()" );
+ }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::~DAnalyzeToolChannel()
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+DAnalyzeToolChannel::~DAnalyzeToolChannel()
+ {
+ LOGSTR1( "ATDD DAnalyzeToolChannel::~DAnalyzeToolChannel()" );
+
+ if ( iEventHandler )
+ {
+ // Cancel all processing that we may be doing
+ DoCancel();
+
+ // Client code should use Close() instead the operator delete
+ // to destroy the event handler.
+ TInt error( iEventHandler->Close() );
+ if ( KErrNone != error )
+ {
+ LOGSTR2( "ATDD iEventHandler->Close(%d)", error );
+ }
+ }
+ #ifdef __WINSCW__
+ iCodeSeg.Close();
+ #endif // __WINSCW__
+
+ // Destroy the queqe
+ if ( iOwnDfcQ )
+ {
+ iOwnDfcQ->Destroy();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::DoControl()
+// Handles a client request.
+// -----------------------------------------------------------------------------
+//
+TInt DAnalyzeToolChannel::DoControl( TInt aFunction,
+ TAny* a1,
+ TAny* /*a2*/,
+ TThreadMessage& aMessage )
+ {
+ LOGSTR1( "ATDD DAnalyzeToolChannel::Request()" );
+
+ TInt ret( KErrNone );
+
+ // Check the requested function
+ switch (aFunction)
+ {
+ case RAnalyzeTool::EGetProcessInfo:
+ ret = GetProcessInfo( a1, aMessage );
+ break;
+
+ case RAnalyzeTool::EGetCodesegInfo:
+ ret = GetCodesegInfo( a1, aMessage );
+ break;
+
+ case RAnalyzeTool::EGetLibraryInfo:
+ ret = GetLibraryInfo( a1, aMessage );
+ break;
+
+ case RAnalyzeTool::ECancelLibraryEvent:
+ iEventHandler->CancelInformLibraryEvent();
+ break;
+
+ case RAnalyzeTool::ECurrentClientCount:
+ ret = ClientCount( a1, aMessage );
+ break;
+
+ case RAnalyzeTool::EMainThreadAlloctor:
+ ret = MainThreadAllocator( a1, aMessage );
+ break;
+
+ case RAnalyzeTool::EThreadStack:
+ ret = ThreadStack( a1, aMessage );
+ break;
+
+ case RAnalyzeTool::EGetProcessHandle:
+ ret = GetProcessHandleInfo( a1, aMessage );
+ break;
+
+ case RAnalyzeTool::EGetCurrentHandles:
+ ret = GetCurrentHandleCount( a1, aMessage );
+ break;
+ case RAnalyzeTool::EGetMemoryModel:
+ ret = GetMemoryModel( a1, aMessage );
+ break;
+
+ // Unsupported function. Panic
+ default:
+ Kern::PanicCurrentThread( KClientPanic, EPanicUnsupportedRequest );
+ break;
+ }
+
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::DoRequest()
+// Handles a client asynchronous request.
+// -----------------------------------------------------------------------------
+//
+TInt DAnalyzeToolChannel::DoRequest( TInt aFunction,
+ TRequestStatus* aStatus,
+ TAny* a1,
+ TAny* /*a2*/,
+ TThreadMessage& aMessage )
+ {
+ LOGSTR1( "ATDD DAnalyzeToolChannel::DoRequest()" );
+
+ // Check the requested function
+ switch (aFunction)
+ {
+ case RAnalyzeTool::ELibraryEvent:
+ iEventHandler->InformLibraryEvent( aStatus, a1, aMessage );
+ break;
+
+ // Unsupported function. Panic
+ default:
+ aMessage.PanicClient( KClientPanic, EPanicUnsupportedRequest );
+ break;
+ }
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::DoCancel()
+// Cancels outstanding asynchronous request.
+// -----------------------------------------------------------------------------
+//
+void DAnalyzeToolChannel::DoCancel()
+ {
+ LOGSTR1( "ATDD DAnalyzeToolChannel::DoCancel()" );
+
+ iEventHandler->CancelInformLibraryEvent();
+ }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::HandleMsg()
+// Processes a message for this logical channel.
+// -----------------------------------------------------------------------------
+//
+void DAnalyzeToolChannel::HandleMsg(TMessageBase* aMsg)
+ {
+ LOGSTR1( "ATDD DAnalyzeToolChannel::HandleMsg()" );
+
+ TThreadMessage& message = *(TThreadMessage*)aMsg;
+
+ // Get message type
+ TInt id = message.iValue;
+
+ // Decode the message type and dispatch it to the relevent handler function...
+ if ( id == (TInt) ECloseMsg )
+ {
+ // Channel Close
+ DoCancel();
+ message.Complete( KErrNone, EFalse );
+ }
+ else if ( id == KMaxTInt )
+ {
+ // DoCancel
+ DoCancel();
+ message.Complete( KErrNone, ETrue );
+ }
+ else if ( id < 0 )
+ {
+ // DoRequest
+ TRequestStatus* status = (TRequestStatus*) message.Ptr0();
+ TInt error = DoRequest( ~id, status, message.Ptr1(), message.Ptr2(), message );
+ if ( KErrNone != error )
+ {
+ Kern::RequestComplete( message.Client(), status, error);
+ }
+ message.Complete(KErrNone, ETrue );
+ }
+ else
+ {
+ // DoControl
+ TInt ret = DoControl( id, message.Ptr0(), message.Ptr1(), message );
+ message.Complete( ret, ETrue );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::GetProcessInfo()
+// Acquires current process information
+// -----------------------------------------------------------------------------
+//
+TInt DAnalyzeToolChannel::GetProcessInfo( TAny* aProcessInfo,
+ TThreadMessage& aMessage )
+ {
+ LOGSTR1( "ATDD DAnalyzeToolChannel::GetProcessInfo()" );
+
+ // Variable for reading parameters from user side
+ TProcessIdentityParamsBuf params;
+
+ // Reads a descriptor from a thread's process.
+ TInt error = Kern::ThreadDesRead( aMessage.Client(), aProcessInfo, params, 0 );
+
+ if ( KErrNone != error )
+ {
+ LOGSTR2( "ATDD ThreadDesRead error %d", error );
+ return error;
+ }
+
+ // Gets the current process
+ Kern::Containers()[ EProcess ]->Wait();
+ DProcess& process = *Kern::ProcessFromId( params().iProcessId );
+ Kern::Containers()[ EProcess ]->Signal();
+
+ if ( NULL == &process )
+ {
+ return KErrNotFound;
+ }
+
+ // Temporary variable for collecting information from the process
+ TProcessIdentityParamsBuf info;
+
+ // Collect needed information from the process
+ process.AppendName( info().iProcessName );//lint !e64 !e1514
+
+ // Gets the current thread
+ Kern::Containers()[ EThread ]->Wait();
+ DThread& thread = *Kern::ThreadFromId( params().iThreadId );
+ Kern::Containers()[ EThread ]->Signal();
+
+ if ( NULL == &thread )
+ {
+ return KErrNotFound;
+ }
+
+ // Stack address of the main thread
+ info().iStackAddress = thread.iUserStackRunAddress;
+ info().iStackSize = thread.iUserStackSize;
+
+ // Enters thread critical section and acquires code segment mutex.
+ Kern::AccessCode();
+
+ // Collect needed information from the process
+ info().iDynamicCount = process.iDynamicCode.Count();
+
+ // Temporary queue for acquiring the count of codesegments
+ SDblQue queue;
+
+ // Acquire the count of codesegments
+ TInt codesegCount = process.TraverseCodeSegs( &queue,
+ NULL,
+ DCodeSeg::EMarkDebug,
+ DProcess::ETraverseFlagAdd );
+
+ #ifndef __WINSCW__
+ info().iCodesegCount = codesegCount;
+ #else
+ // Reset codesegment array
+ iCodeSeg.Reset();
+
+ if ( codesegCount > 0 )
+ {
+ SDblQueLink* link = queue.iA.iNext;
+ TCodesegInfo codeinfo;
+ // Iterate through codesegments
+ for ( TInt i = 0; i < codesegCount; ++i, link = link->iNext )
+ {
+ DWin32CodeSeg* codeseg =
+ (DWin32CodeSeg*)_LOFF( link, DCodeSeg, iTempLink );
+
+ // Aqcuire codeseg information
+ codeinfo.iFileEntryPoint = codeseg->iFileEntryPoint;
+ codeinfo.iSize = codeseg->iSize;
+ codeinfo.iFullName.Copy( codeseg->iRootName );
+ codeinfo.iRunAddress = codeseg->iRunAddress;
+ iCodeSeg.Append( codeinfo );
+ }
+ }
+
+ // Add dependency codesegments
+ DWin32CodeSeg* pcodeSeg = (DWin32CodeSeg*)process.iCodeSeg;
+
+ // Get dependency codesegments
+ GetModuleDependencies( pcodeSeg->iModuleHandle );
+
+ // Set codesegment count
+ info().iCodesegCount = iCodeSeg.Count();
+ #endif
+
+ // Removes all code segments from a queue and clear specified mark(s)
+ DCodeSeg::EmptyQueue( queue, DCodeSeg::EMarkDebug );
+
+ // Exits thread critical section and releases code segment mutex.
+ Kern::EndAccessCode();
+
+ // Writes a descriptor to a thread's process.
+ error = Kern::ThreadDesWrite( aMessage.Client(), aProcessInfo, info, 0 );
+
+ if ( KErrNone != error )
+ {
+ LOGSTR2( "ATDD ThreadDesWrite error %d", error );
+ return error;
+ }
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::GetCodesegInfo()
+// Acquires codeseg information.
+// -----------------------------------------------------------------------------
+//
+TInt DAnalyzeToolChannel::GetCodesegInfo( TAny* aCodesegInfo,
+ TThreadMessage& aMessage )
+ {
+ LOGSTR1( "ATDD DAnalyzeToolChannel::GetCodesegInfo()" );
+
+ // Temporary variable for collecting information from the codeseg
+ TCodesegInfoBuf params;
+
+ TInt error( KErrArgument );
+
+ // Reads a descriptor from a thread's process.
+ error = Kern::ThreadDesRead( aMessage.Client(), aCodesegInfo, params, 0 );
+
+ if ( KErrNone != error )
+ {
+ LOGSTR2( "ATDD ThreadDesRead error %d", error );
+ return error;
+ }
+
+ if ( params().iIndex < 0 )
+ {
+ return KErrArgument;
+ }
+
+ // Gets the current process
+ Kern::Containers()[ EProcess ]->Wait();
+ DProcess& process = *Kern::ProcessFromId( params().iProcessId );
+ Kern::Containers()[ EProcess ]->Signal();
+
+ if ( NULL == &process )
+ {
+ return KErrNotFound;
+ }
+
+ // Temporary variable for collecting information
+ TCodesegInfoBuf output;
+
+ // Enters thread critical section and acquires code segment mutex.
+ Kern::AccessCode();
+
+ #ifndef __WINSCW__
+ // Temporary queue for acquiring the codesegments
+ SDblQue queue;
+
+ // Acquire the codesegments
+ TInt actcount = process.TraverseCodeSegs( &queue,
+ NULL,
+ DCodeSeg::EMarkDebug,
+ DProcess::ETraverseFlagAdd );
+ if ( actcount >= params().iIndex )
+ {
+ LOGSTR1( "ATDD DAnalyzeToolChannel::GetCodesegInfo() - actcount >= params.iIndex" );
+ SDblQueLink* link = queue.iA.iNext;
+
+ // Iterate through codesegments
+ for (TInt i = 0; i < actcount; ++i, link = link->iNext)
+ {
+ DCodeSeg* codeseg = _LOFF( link, DCodeSeg, iTempLink );
+
+ // Is the codesegments which information client wants
+ if ( i == params().iIndex )
+ {
+ // Aqcuire codeseg information
+ output().iFileEntryPoint = codeseg->iFileEntryPoint;
+ output().iSize = codeseg->iSize;
+ output().iFullName.Copy( codeseg->iRootName );
+ output().iRunAddress = codeseg->iRunAddress;
+ error = codeseg->GetMemoryInfo( output().iMemoryInfo, &process );
+
+ if ( KErrNone == error )
+ {
+ // Writes a descriptor to a thread's process.
+ error = Kern::ThreadDesWrite( aMessage.Client(),
+ aCodesegInfo,
+ output,
+ 0 );
+ if ( KErrNone != error )
+ {
+ LOGSTR2( "ATDD ThreadDesWrite error %d", error );
+ }
+ }
+ break;
+ }
+ }
+ }
+ // Removes all code segments from a queue and clear specified mark(s).
+ DCodeSeg::EmptyQueue( queue, DCodeSeg::EMarkDebug );
+
+ // Exits thread critical section and releases code segment mutex.
+ Kern::EndAccessCode();
+
+ return error;
+ #else // WINSCW
+
+ if ( iCodeSeg.Count() > params().iIndex )
+ {
+ // Aqcuire codeseg information
+ output().iSize = iCodeSeg[params().iIndex].iSize;
+ output().iFullName.Copy( iCodeSeg[params().iIndex].iFullName );
+ output().iRunAddress = iCodeSeg[params().iIndex].iRunAddress;
+
+ // Writes a descriptor to a thread's process.
+ error = Kern::ThreadDesWrite( aMessage.Client(), aCodesegInfo, output, 0 );
+
+ if ( KErrNone != error )
+ {
+ LOGSTR2( "ATDD ThreadDesWrite error %d", error );
+ }
+ }
+
+ // Exits thread critical section and releases code segment mutex.
+ Kern::EndAccessCode();
+
+ return error;
+ #endif
+ }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::GetLibraryInfo()
+// Acquires library information.
+// -----------------------------------------------------------------------------
+//
+TInt DAnalyzeToolChannel::GetLibraryInfo( TAny* aLibraryInfo,
+ TThreadMessage& aMessage )
+ {
+ LOGSTR1( "ATDD DAnalyzeToolChannel::GetLibraryInfo()" );
+
+ // Temporary variable for reading informationfrom the user side
+ TLibraryInfoBuf params;
+
+ // Reads a descriptor from a thread's process.
+ TInt error = Kern::ThreadDesRead( aMessage.Client(), aLibraryInfo, params, 0 );
+
+ if ( KErrNone != error )
+ {
+ LOGSTR2( "ATDD ThreadDesRead error %d", error );
+ return error;
+ }
+
+ if ( params().iIndex < 0 )
+ {
+ return KErrArgument;
+ }
+
+ // Gets the current process
+ Kern::Containers()[ EProcess ]->Wait();
+ DProcess& process = *Kern::ProcessFromId( params().iProcessId );
+ Kern::Containers()[ EProcess ]->Signal();
+
+ if ( NULL == &process )
+ {
+ return KErrNotFound;
+ }
+
+ // Temporary variable for collecting information from the library
+ TLibraryInfoBuf output;
+
+ // Enters thread critical section and acquires code segment mutex.
+ Kern::AccessCode();
+
+ // Iterate to find the right library
+ if ( params().iIndex < process.iDynamicCode.Count() )
+ {
+ // Acquire entry to the codeseg
+ SCodeSegEntry entry = process.iDynamicCode[ params().iIndex ];
+
+ // Acquire library information
+ entry.iLib->AppendName( output().iLibraryName );//lint !e64 !e1514
+ output().iRunAddress = entry.iSeg->iRunAddress;
+ output().iSize = entry.iSeg->iSize;
+
+ // Writes a descriptor to a thread's process.
+ error = Kern::ThreadDesWrite( aMessage.Client(), aLibraryInfo, output, 0 );
+
+ if ( KErrNone != error )
+ {
+ LOGSTR2( "ATDD ThreadDesWrite error %d", error );
+ }
+
+ // Exits thread critical section and releases code segment mutex.
+ Kern::EndAccessCode();
+
+ return error;
+ }
+ else
+ {
+ // Exits thread critical section and releases code segment mutex.
+ Kern::EndAccessCode();
+
+ return KErrArgument;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::MainThreadAllocator()
+// Acquires information about process main thread RAllocator
+// -----------------------------------------------------------------------------
+//
+TInt DAnalyzeToolChannel::MainThreadAllocator( TAny* aMainThreadParams,
+ TThreadMessage& aMessage )
+ {
+ LOGSTR1( "ATDD DAnalyzeToolChannel::MainThreadAllocator()" );
+
+ // Temporary variable for reading client side parameters
+ TMainThreadParamsBuf params;
+
+ // Reads a descriptor from a thread's process.
+ TInt error = Kern::ThreadDesRead( aMessage.Client(),
+ aMainThreadParams,
+ params,
+ 0 );
+
+ if ( KErrNone != error )
+ {
+ LOGSTR2( "ATDD ThreadDesRead error %d", error );
+ return error;
+ }
+
+ // Gets the current process
+ Kern::Containers()[ EProcess ]->Wait();
+ DProcess& process = *Kern::ProcessFromId( params().iProcessId );
+ Kern::Containers()[ EProcess ]->Signal();
+
+ if ( NULL == &process )
+ {
+ return KErrNotFound;
+ }
+
+ // Gets the current process
+ Kern::AccessCode();
+
+ // Temporary variable for collecting information from the RAllocator
+ TMainThreadParamsBuf output;
+
+ // Aqcuire a reference to the main thread RAllocator
+ output().iAllocator = process.FirstThread()->iAllocator;
+
+ // Is this only thread in the process
+ output().iAlone = process.iThreadQ.First()->Alone();
+
+ // Exits thread critical section and releases code segment mutex.
+ Kern::EndAccessCode();
+
+ // Writes a descriptor to a thread's process.
+ error = Kern::ThreadDesWrite( aMessage.Client(),
+ aMainThreadParams,
+ output,
+ 0 );
+
+ if ( KErrNone != error )
+ {
+ LOGSTR2( "ATDD ThreadDesWrite error %d", error );
+ }
+
+ return error;
+ }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::ThreadStack()
+// Acquires main thread stack address
+// -----------------------------------------------------------------------------
+//
+TInt DAnalyzeToolChannel::ThreadStack( TAny* aThreadStack,
+ TThreadMessage& aMessage )
+ {
+ LOGSTR1( "ATDD DAnalyzeToolChannel::ThreadStack()" );
+
+ // Temporary variable for reading client side parameters
+ TThreadParamsBuf params;
+
+ // Reads a descriptor from a thread's process.
+ TInt error = Kern::ThreadDesRead( aMessage.Client(),
+ aThreadStack,
+ params,
+ 0 );
+
+ if ( KErrNone != error )
+ {
+ LOGSTR2( "ATDD ThreadDesRead error %d", error );
+ return error;
+ }
+
+ // Gets the current process
+ Kern::Containers()[ EThread ]->Wait();
+ DThread& thread = *Kern::ThreadFromId( params().iThreadId );
+ Kern::Containers()[ EThread ]->Signal();
+
+ if ( NULL == &thread )
+ {
+ return KErrNotFound;
+ }
+
+ // Gets the current process
+ Kern::AccessCode();
+
+ // Temporary variable for collecting information from the RAllocator
+ TThreadParamsBuf output;
+
+ // Stack address of the main thread
+ output().iStackAddress = thread.iUserStackRunAddress;
+ output().iStackSize = thread.iUserStackSize;
+
+ // Exits thread critical section and releases code segment mutex.
+ Kern::EndAccessCode();
+
+ // Writes a descriptor to a thread's process.
+ error = Kern::ThreadDesWrite( aMessage.Client(),
+ aThreadStack,
+ output,
+ 0 );
+
+ if ( KErrNone != error )
+ {
+ LOGSTR2( "ATDD ThreadDesWrite error %d", error );
+ }
+
+ return error;
+ }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::GetProcessHandleInfo()
+// Acquires information about process global handles
+// -----------------------------------------------------------------------------
+//
+TInt DAnalyzeToolChannel::GetProcessHandleInfo( TAny* aProcessHandleInfo,
+ TThreadMessage& aMessage )
+ {
+ LOGSTR1( "ATDD DAnalyzeToolChannel::GetProcessHandleInfo()" );
+
+ // Temporary variable for collecting information from the codeseg
+ TProcessHandleInfoBuf params;
+
+ // Reads a descriptor from a thread's process.
+ TInt error = Kern::ThreadDesRead( aMessage.Client(),
+ aProcessHandleInfo,
+ params,
+ 0 );
+
+ if ( KErrNone != error )
+ {
+ LOGSTR2( "ATDD ThreadDesRead error %d", error );
+ return error;
+ }
+
+ // Gets the current process
+ Kern::Containers()[ EProcess ]->Wait();
+ DProcess& process = *Kern::ProcessFromId( params().iProcessId );
+ Kern::Containers()[ EProcess ]->Signal();
+
+ if ( NULL == &process )
+ {
+ return KErrNotFound;
+ }
+
+ // Variable holding wanted information
+ TProcessHandleInfoBuf output;
+
+ // Enters thread critical section and acquires code segment mutex.
+ Kern::AccessCode();
+
+ // Get the process thread queue.
+ SDblQue queue = process.iThreadQ;
+ error = KErrNotFound;
+
+ // Tests whether this doubly linked list is empty.
+ if ( !queue.IsEmpty() )
+ {
+ // Gets a pointer to the first item in this doubly linked list.
+ SDblQueLink* link = queue.First();
+ DThread* thread = _LOFF( link, DThread, iProcessLink );
+
+ if ( thread )
+ {
+
+#ifdef MCL_ROBJECTIX
+ TInt threadHandles( thread->iHandles.ActiveCount() );
+#else
+ TInt threadHandles( thread->iHandles->ActiveCount() );
+#endif
+
+ // Aqcuire thread information
+ //thread->AppendName( output.iThreadName );
+ output().iUserStackRunAddress = thread->iUserStackRunAddress;
+ output().iUserStackSize = thread->iUserStackSize;
+ output().iThreadHandleCount = threadHandles;
+
+#ifdef MCL_ROBJECTIX
+ RObjectIx objectIx = process.iHandles;
+ output().iProcessHandleCount = objectIx.ActiveCount();
+#else
+ DObjectIx* objectIx = process.iHandles;
+ output().iProcessHandleCount = objectIx->ActiveCount();
+#endif
+
+ // Writes a descriptor to a thread's process.
+ error = Kern::ThreadDesWrite( aMessage.Client(),
+ aProcessHandleInfo,
+ output,
+ 0 );
+
+ if ( KErrNone != error )
+ {
+ LOGSTR2( "ATDD ThreadDesWrite error %d", error );
+ }
+ }
+ }
+
+ // Exits thread critical section and releases code segment mutex.
+ Kern::EndAccessCode();
+
+ return error;
+ }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::GetCurrentHandleCount()
+// Acquires a process's current handle count
+// -----------------------------------------------------------------------------
+//
+TInt DAnalyzeToolChannel::GetCurrentHandleCount( TAny* aProcessHandles,
+ TThreadMessage& aMessage )
+ {
+ LOGSTR1( "ATDD DAnalyzeToolChannel::GetCurrentHandleCount()" );
+
+ // Temporary variable for collecting information from the codeseg
+ TATProcessHandlesBuf params;
+
+ // Reads a descriptor from a thread's process.
+ TInt error = Kern::ThreadDesRead( aMessage.Client(),
+ aProcessHandles,
+ params,
+ 0 );
+
+ if ( KErrNone != error )
+ {
+ LOGSTR2( "ATDD ThreadDesRead error %d", error );
+ return error;
+ }
+
+ // Gets the current process
+ Kern::Containers()[ EProcess ]->Wait();
+ DProcess* process = Kern::ProcessFromId( params().iProcessId );
+ Kern::Containers()[ EProcess ]->Signal();
+
+ if ( NULL == process )
+ {
+ return KErrNotFound;
+ }
+
+ // Variable holding wanted information
+ TATProcessHandlesBuf output;
+
+ // Enters thread critical section and acquires code segment mutex.
+ Kern::AccessCode();
+
+ SDblQue queue = process->iThreadQ;
+ SDblQueLink* link = queue.First();
+ TInt threadHandles( 0 );
+
+ // Iterate through current processes's threads
+ while ( link != queue.Last() )
+ {
+ DThread* thread = _LOFF( link, DThread, iProcessLink );
+
+#ifdef MCL_ROBJECTIX
+ threadHandles += thread->iHandles.ActiveCount();
+#else
+ threadHandles += thread->iHandles->ActiveCount();
+#endif
+
+ link = link->iNext;
+ }
+
+ if ( link == queue.Last() )
+ {
+ DThread* thread = _LOFF( link, DThread, iProcessLink );
+
+#ifdef MCL_ROBJECTIX
+ threadHandles += thread->iHandles.ActiveCount();
+#else
+ threadHandles += thread->iHandles->ActiveCount();
+#endif
+ }
+
+ output().iCurrentHandleCount = threadHandles;
+
+ // Writes a descriptor to a thread's process.
+ error = Kern::ThreadDesWrite( aMessage.Client(),
+ aProcessHandles,
+ output,
+ 0 );
+
+ if ( KErrNone != error )
+ {
+ LOGSTR2( "ATDD ThreadDesWrite error %d", error );
+ }
+
+ // Exits thread critical section and releases code segment mutex.
+ Kern::EndAccessCode();
+
+ return error;
+ }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::ClientCount()
+// Acquires the count of current device driver users.
+// -----------------------------------------------------------------------------
+//
+TInt DAnalyzeToolChannel::ClientCount( TAny* aClientCount,
+ TThreadMessage& aMessage )
+ {
+ LOGSTR1( "ATDD DAnalyzeToolChannel::ClientCount()" );
+
+ // Enters thread critical section and acquires code segment mutex.
+ Kern::AccessCode();
+
+ // Variable holding wanted information
+ TClientCountBuf output;
+
+ // Get the number of DLogicalChannelBase objects currently in existence which
+ // have been created from this LDD.
+ output().iClientCount = DLogicalChannelBase::iDevice->iOpenChannels;
+ LOGSTR2( "ATDD > iOpenChannels count: %d", output().iClientCount );
+
+ // Writes a descriptor to a thread's process.
+ TInt error = Kern::ThreadDesWrite( aMessage.Client(),
+ aClientCount,
+ output,
+ 0 );
+
+ if ( KErrNone != error )
+ {
+ LOGSTR2( "ATDD ThreadDesWrite error %d", error );
+ }
+
+ // Exits thread critical section and releases code segment mutex.
+ Kern::EndAccessCode();
+
+ return error;
+ }
+
+#ifdef __WINSCW__
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::GetModuleDependencies()
+// Get module dependencies
+// -----------------------------------------------------------------------------
+//
+void DAnalyzeToolChannel::GetModuleDependencies( HMODULE aModule )
+ {
+ LOGSTR1( "ATDD DAnalyzeToolChannel::GetModuleDependencies()" );
+
+ Emulator::TModule etm( aModule );
+ TUint32 dllSize( 0 );
+ // Temporary variable for collecting information from the codeseg
+ TCodesegInfo info;
+ TBool found( EFalse );
+
+ const IMAGE_IMPORT_DESCRIPTOR* imports = etm.Imports();
+ while( imports->Characteristics != 0 )
+ {
+ // Reset flag
+ found = EFalse;
+
+ // Get dll name
+ const TUint8* nameAddr = ( const TUint8* )( imports->Name + ( TInt )etm.iBase );
+ TPtrC8 namePtr( nameAddr );
+
+ // Get dll run address
+ Emulator::TModule imp_etm( ( PCSTR )etm.Translate( imports->Name ) );
+ const TUint8* runAddr = ( const TUint8* )imp_etm.iBase;
+
+ // Get dll size
+ const IMAGE_NT_HEADERS32* ntHeader = imp_etm.NtHeader();
+ dllSize = ntHeader->OptionalHeader.SizeOfImage;
+
+ // Check if DLL already exists in codesegment list
+ for( TInt i = 0; i < iCodeSeg.Count(); i++ )
+ {
+ if ( iCodeSeg[i].iFullName.Compare( namePtr ) == KErrNone )
+ {
+ found = ETrue;
+ break;
+ }
+ }
+
+ if ( !found )
+ {
+ info.iSize = dllSize;
+ info.iFullName.Copy( namePtr );
+ info.iRunAddress = (TUint32) runAddr;
+ // Append codesegment to array
+ iCodeSeg.Append( info );
+ }
+ imports++;
+ }
+ }
+
+#endif // __WINSCW__
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolChannel::GetMemoryModel()
+// Acquires memory model system uses.
+// -----------------------------------------------------------------------------
+//
+TInt DAnalyzeToolChannel::GetMemoryModel(TAny* aMemoryModel,
+ TThreadMessage& aMessage)
+ {
+ LOGSTR1( "ATDD DAnalyzeToolChannel::GetMemoryModel()" );
+
+ // Model buffer.
+ TATMemoryModelBuf model;
+ // Get current model.
+ model().iMemoryModel = (TUint32) Kern::HalFunction( EHalGroupKernel, EKernelHalMemModelInfo, NULL, NULL );
+ model().iMemoryModel &= EMemModelTypeMask; // Mask out other stuff.
+ // Write it to client side.
+ TInt error = Kern::ThreadDesWrite( aMessage.Client(),
+ aMemoryModel,
+ model,
+ 0);
+ if ( error != KErrNone )
+ {
+ LOGSTR2( "ATDD ThreadDesWrite error %d", error );
+ }
+ return error;
+ }
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/kerneleventhandler/src/analyzetooldevice.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,93 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Definitions for the class DAnalyzeToolDevice.
+*
+*/
+
+
+// INCLUDE FILES
+#include "analyzetooldevice.h"
+#include "analyzetoolchannel.h"
+#include "atlog.h"
+
+// ================= MEMBER FUNCTIONS =========================================
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolDevice::DAnalyzeToolDevice()
+// C++ default constructor.
+// -----------------------------------------------------------------------------
+//
+DAnalyzeToolDevice::DAnalyzeToolDevice()
+ {
+ LOGSTR1( "ATDD DAnalyzeToolDevice::DAnalyzeToolDevice()" );
+ // Set version number
+ iVersion = KAnalyzeToolLddVersion();
+ }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolDevice::Install()
+// Second stage constructor.
+// -----------------------------------------------------------------------------
+//
+TInt DAnalyzeToolDevice::Install()
+ {
+ LOGSTR1( "ATDD DAnalyzeToolDevice::Install()" );
+ // Set device name
+ return SetName( &KAnalyzeToolLddName );
+ }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolDevice::GetCaps()
+// Gets the driver's capabilities.
+// -----------------------------------------------------------------------------
+//
+void DAnalyzeToolDevice::GetCaps( TDes8& /*aDes*/ ) const
+ {
+ LOGSTR1( "ATDD DAnalyzeToolDevice::GetCaps()" );
+ }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolDevice::Create()
+// Creates the logical channel.
+// -----------------------------------------------------------------------------
+//
+TInt DAnalyzeToolDevice::Create( DLogicalChannelBase*& aChannel )
+ {
+ LOGSTR1( "ATDD DAnalyzeToolDevice::Create()" );
+
+ // create new channel
+ aChannel = new DAnalyzeToolChannel;
+
+ // check that everything is OK
+ return ( aChannel != NULL ) ? KErrNone : KErrNoMemory;
+ }
+
+// -----------------------------------------------------------------------------
+// DECLARE_STANDARD_LDD
+// Defines the entry point for a standard logical device driver (LDD),
+// and declares the ordinal 1 export function for creating
+// the LDD factory object
+// -----------------------------------------------------------------------------
+//
+DECLARE_STANDARD_LDD()
+ {
+ LOGSTR1( "ATDD DECLARE_STANDARD_LDD()" );
+ return new DAnalyzeToolDevice;
+ }
+
+// ================= OTHER EXPORTED FUNCTIONS =================================
+
+// None
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/kerneleventhandler/src/analyzetooleventhandler.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,427 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Definitions for the class DAnalyzeToolEventHandler.
+*
+*/
+
+
+// INCLUDE FILES
+#include "analyzetooleventhandler.h"
+#include <kernel/kern_priv.h>
+
+// CONSTANTS
+
+// The handler mutex literal
+_LIT( KHandlerMutexName, "AnalyzeToolHandlerMutex" );
+
+// The handle data mutex literal
+_LIT( KDataMutexName, "AnalyzeToolDataMutex" );
+
+
+// ================= MEMBER FUNCTIONS =========================================
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolEventHandler::Create()
+// C++ default constructor.
+// -----------------------------------------------------------------------------
+//
+TInt DAnalyzeToolEventHandler::Create( DLogicalDevice* aDevice,
+ const TUint aProcessId )
+ {
+ LOGSTR1( "ATDD DAnalyzeToolEventHandler::Create()" );
+ TInt ret( KErrNone );
+
+ // Store owner process ID
+ iProcessId = aProcessId;
+ LOGSTR2( "ATDD DAnalyzeToolEventHandler::Create > iProcessId %d",
+ iProcessId );
+
+ // Open the device
+ ret = aDevice->Open();
+ if ( ret != KErrNone )
+ return ret;
+ iDevice = aDevice;
+
+ // Create mutex for the handler
+ ret = Kern::MutexCreate( iHandlerMutex, KHandlerMutexName, KMutexOrdDebug );
+ if ( ret != KErrNone )
+ return ret;
+ // Create mutex for the data
+ ret = Kern::MutexCreate( iDataMutex, KDataMutexName, KMutexOrdDebug-1 );
+ if ( ret != KErrNone )
+ return ret;
+
+ // Add handler to the handler queue
+ return Add();
+ }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolEventHandler::~DAnalyzeToolEventHandler()
+// C++ default constructor.
+// -----------------------------------------------------------------------------
+//
+DAnalyzeToolEventHandler::~DAnalyzeToolEventHandler()
+ {
+ LOGSTR1( "ATDD DAnalyzeToolEventHandler::~DAnalyzeToolEventHandler()" );
+
+ CancelInformLibraryEvent();
+
+ // Close the data mutex
+ if ( iDataMutex )
+ {
+ iDataMutex->Close( NULL );
+ }
+
+ // Close the handler mutex
+ if ( iHandlerMutex )
+ {
+ iHandlerMutex->Close( NULL );
+ }
+
+ // Close the device mutex
+ if ( iDevice )
+ {
+ iDevice->Close( NULL );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolEventHandler::EventHandler()
+// Function for receiving kernel events
+// -----------------------------------------------------------------------------
+//
+TUint DAnalyzeToolEventHandler::EventHandler( TKernelEvent aEvent,
+ TAny* a1, TAny* a2, TAny* aThis )
+ {
+
+ // Clarify the event type
+ switch ( aEvent)
+ {
+ case EEventRemoveLibrary:
+ {
+ LOGSTR1( "ATDD DAnalyzeToolEventHandler::EventHandler() - EEventRemoveLibrary" );
+ // Cast the pointer to the handler
+ DAnalyzeToolEventHandler* handler =
+ ( ( DAnalyzeToolEventHandler* ) aThis );
+ // Create variable for library information
+ TLibraryEventInfo info;
+ // Set as library remove event
+ info.iEventType = TLibraryEventInfo::ELibraryRemoved;
+ // Handle the event
+ handler->HandleLibraryEvent( ( DLibrary* ) a1, ( DThread* ) a2, info );
+ break;
+ }
+ case EEventAddLibrary:
+ {
+ LOGSTR1( "ATDD DAnalyzeToolEventHandler::EventHandler() - EEventAddLibrary" );
+ // Cast the pointer to the handler
+ DAnalyzeToolEventHandler* handler =
+ ( ( DAnalyzeToolEventHandler* ) aThis );
+ // Create variable for library information
+ TLibraryEventInfo info;
+ // Set as library remove event
+ info.iEventType = TLibraryEventInfo::ELibraryAdded;
+ // Handle the event
+ handler->HandleLibraryEvent( ( DLibrary* ) a1, ( DThread* ) a2, info );
+ break;
+ }
+ case EEventHwExc:
+ {
+ LOGSTR1( "ATDD DAnalyzeToolEventHandler::EventHandler() - EEventHwExc" );
+ break;
+ }
+ case EEventSwExc:
+ {
+ LOGSTR1( "ATDD DAnalyzeToolEventHandler::EventHandler() - EEventSwExc" );
+ break;
+ }
+ case EEventRemoveThread:
+ {
+ LOGSTR1( "ATDD DAnalyzeToolEventHandler::EventHandler() - EEventRemoveThread" );
+ break;
+ }
+ case EEventKillThread:
+ {
+ LOGSTR1( "ATDD DAnalyzeToolEventHandler::EventHandler() - EEventKillThread" );
+
+ // Cast the pointer to the handler
+ DAnalyzeToolEventHandler* handler =
+ ( ( DAnalyzeToolEventHandler* ) aThis );
+
+ // Create variable for library information
+ TLibraryEventInfo info;
+
+ // Set as kill thread event
+ info.iEventType = TLibraryEventInfo::EKillThread;
+ // Handle the event
+ handler->HandleKillThreadEvent( ( DThread* ) a1, info );
+ break;
+ }
+ default:
+ {
+ }
+ break;
+ }
+ return ERunNext;
+ }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolEventHandler::HandleLibraryEvent()
+// Handles the EEventAddLibrary and EEventRemoveLibrary events.
+// -----------------------------------------------------------------------------
+//
+void DAnalyzeToolEventHandler::HandleLibraryEvent( DLibrary* aLib,
+ DThread* aThread, TLibraryEventInfo& aInfo )
+ {
+ LOGSTR1( "ATDD DAnalyzeToolEventHandler::HandleLibraryEvent()" );
+
+ // Aqcuire the handler mutex
+ Kern::MutexWait( *iHandlerMutex );
+
+ // Aqcuire the data mutex
+ Kern::MutexWait( *iDataMutex );
+
+ TBool addInfo( EFalse );
+
+ // Check the library event type
+ if ( aInfo.iEventType == TLibraryEventInfo::ELibraryAdded )
+ {
+ if ( aThread != NULL )
+ {
+ if ( iProcessId == aThread->iOwningProcess->iId )
+ {
+ LOGSTR1( "ATDD > Process id match" );
+ aInfo.iProcessId = aThread->iOwningProcess->iId;
+ addInfo = ETrue;
+ }
+ }
+ }
+ else if ( aInfo.iEventType == TLibraryEventInfo::ELibraryRemoved )
+ {
+ if ( aThread != NULL )
+ {
+ aInfo.iProcessId = aThread->iOwningProcess->iId;
+ }
+ else
+ {
+ aInfo.iProcessId = 0;
+ }
+ addInfo = ETrue;
+ }
+
+ if ( addInfo )
+ {
+ // Store lib info
+ aLib->AppendName( aInfo.iLibraryName );//lint !e64 !e1514
+ aInfo.iSize = aLib->iCodeSeg->iSize;
+ aInfo.iRunAddress = aLib->iCodeSeg->iRunAddress;
+ // Store library event info to the array
+ iEventArray.Append( aInfo );
+ LOGSTR2( "ATDD > iEventArray.Count() = %d", iEventArray.Count() );
+
+ // if client has subscribed the event it is queued
+ if ( iClientThread != NULL )
+ {
+ iEventDfc.Enque();
+ }
+ }
+
+ // Release the data mutex
+ Kern::MutexSignal( *iDataMutex );
+
+ // Release the handler mutex
+ Kern::MutexSignal( *iHandlerMutex );
+ }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolEventHandler::InformLibraryEvent()
+// Subscribes library event.
+// -----------------------------------------------------------------------------
+//
+void DAnalyzeToolEventHandler::InformLibraryEvent( TRequestStatus* aStatus,
+ TAny* aLibraryInfo,
+ TThreadMessage& aMessage )
+ {
+ LOGSTR1( "ATDD DAnalyzeToolEventHandler::InformLibraryEvent()" );
+
+ // Aqcuire the data mutex
+ Kern::MutexWait( *iDataMutex );
+
+ // Check if request from client which is already pending
+ DThread* current = aMessage.Client();
+
+ LOGSTR2( "ATDD > Current Thread ID = %d", current->iId );
+
+ // Ensure that client doesn't subscribe service when there is a pending
+ // subscription
+ if ( NULL != iClientThread )
+ {
+ aMessage.PanicClient( KClientPanic, EPanicRequestPending );
+ }
+ else
+ {
+ // Store the client variable pointers
+ iClientThread = current;
+ iClientRequestStatus = aStatus;
+ iClientInfo = aLibraryInfo;
+ }
+
+ // Release the data mutex
+ Kern::MutexSignal( *iDataMutex );
+
+ // Queue the event since now the client has subscribed it
+ iEventDfc.Enque();
+ }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolEventHandler::CancelInformLibraryEvent
+// Cancels subscription of the library event.
+// -----------------------------------------------------------------------------
+//
+void DAnalyzeToolEventHandler::CancelInformLibraryEvent()
+ {
+ LOGSTR1( "ATDD DAnalyzeToolEventHandler::CancelInformLibraryEvent()" );
+
+ iEventDfc.Cancel();
+
+ // Aqcuire the data mutex
+ Kern::MutexWait( *iDataMutex );
+
+ if ( NULL != iClientThread && iEventArray.Count() > 0 )
+ {
+ // Signal the request as complete
+ Kern::RequestComplete( iClientThread,
+ iClientRequestStatus,
+ KErrCancel );
+
+ iClientThread = NULL;
+ iClientRequestStatus = NULL;
+ iClientInfo = NULL;
+
+ // Reset the event array
+ iEventArray.Reset();
+ }
+
+ // Release the data mutex
+ Kern::MutexSignal( *iDataMutex );
+ }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolEventHandler::HandleKillThreadEvent()
+// Handles the EEventKillThread events.
+// -----------------------------------------------------------------------------
+//
+void DAnalyzeToolEventHandler::HandleKillThreadEvent( DThread* aThread,
+ TLibraryEventInfo& aInfo )
+ {
+ LOGSTR1( "ATDD DAnalyzeToolEventHandler::HandleKillThreadEvent()" );
+
+ // Aqcuire the handler mutex
+ Kern::MutexWait( *iHandlerMutex );
+
+ // Aqcuire the data mutex
+ Kern::MutexWait( *iDataMutex );
+
+ aInfo.iProcessId = aThread->iOwningProcess->iId;
+ TBool alone( aThread->iOwningProcess->iThreadQ.First()->Alone() );
+ LOGSTR2( "ATDD > Is alone = %d", alone );
+
+ // Check if this our process and is the only thread item.
+ if ( aInfo.iProcessId == iProcessId && !alone )
+ {
+ if ( aThread )
+ {
+ // Set current Thread id
+ LOGSTR2( "ATDD > Thread ID = %d", aThread->iId );
+ aInfo.iThreadId = aThread->iId;
+ // Append event to array (beginning of the array)
+ iEventArray.Insert( aInfo, 0 );
+
+ // if client has subscribed the event it is queued
+ if ( iClientThread != NULL )
+ {
+ iEventDfc.Enque();
+ }
+ }
+ }
+
+ // Release the data mutex
+ Kern::MutexSignal( *iDataMutex );
+
+ // Release the handler mutex
+ Kern::MutexSignal( *iHandlerMutex );
+ }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolEventHandler::DoEventComplete()
+// Informs client about the occured event.
+// -----------------------------------------------------------------------------
+//
+void DAnalyzeToolEventHandler::DoEventComplete()
+ {
+ LOGSTR1( "ATDD DAnalyzeToolEventHandler::DoEventComplete()" );
+
+ // Aqcuire the handler mutex
+ Kern::MutexWait( *iHandlerMutex );
+
+ // Aqcuire the data mutex
+ Kern::MutexWait( *iDataMutex );
+
+ if ( NULL != iClientThread && iEventArray.Count() > 0 )
+ {
+ TInt ret = Kern::ThreadRawWrite( iClientThread,
+ iClientInfo,
+ &iEventArray[0],
+ sizeof( iEventArray[0] ) );
+
+ LOGSTR2( "ATDD > ThreadRawWrite err = %d", ret );
+
+ // Signal the request as complete
+ Kern::RequestComplete( iClientThread,
+ iClientRequestStatus,
+ ret );
+
+ // Remove first item to array
+ iEventArray.Remove( 0 );
+
+ // Compresses the array down to a minimum
+ iEventArray.Compress();
+
+ // Ensure that pointers are set to NULL
+ iClientThread = NULL;
+ iClientRequestStatus = NULL;
+ iClientInfo = NULL;
+
+ LOGSTR2( "ATDD > iEventArray = %d", iEventArray.Count() );
+ }
+
+ // Release the data mutex
+ Kern::MutexSignal( *iDataMutex );
+
+ // Release the handler mutex
+ Kern::MutexSignal( *iHandlerMutex );
+ }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolEventHandler::EventDfc()
+// Static function for DFC events.
+// -----------------------------------------------------------------------------
+//
+void DAnalyzeToolEventHandler::EventDfc(TAny* aPtr)
+ {
+ LOGSTR1( "ATDD DAnalyzeToolEventHandler::EventDfc()" );
+ ( (DAnalyzeToolEventHandler*) aPtr )->DoEventComplete();
+ }
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/rom/analyzetool.iby Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,25 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef __ANALYZETOOL_IBY__
+#define __ANALYZETOOL_IBY__
+
+// Stub
+data=ZSYSTEM\Install\analyzetool_stub.sis \system\install\analyzetool_stub.sis
+
+#endif // __ANALYZETOOL_IBY__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/rom/analyzetool_rom.iby Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,37 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef __ANALYZETOOL_ROM_IBY__
+#define __ANALYZETOOL_ROM_IBY__
+
+
+// Kernel event handler
+device[VARID]=ABI_DIR\BUILD_DIR\atoolkerneleventhandler.ldd SHARED_LIB_DIR\atoolkerneleventhandler.ldd
+
+// Memory hook
+file=ABI_DIR\BUILD_DIR\atoolmemoryhook.dll SHARED_LIB_DIR\atoolmemoryhook.dll
+
+// Cleaner
+file=ABI_DIR\BUILD_DIR\atoolcleaner.dll SHARED_LIB_DIR\atoolcleaner.dll
+
+// Storage server
+file=ABI_DIR\BUILD_DIR\atoolstorageserver.exe PROGRAMS_DIR\atoolstorageserver.exe
+file=ABI_DIR\BUILD_DIR\atoolstorageserverclnt.dll SHARED_LIB_DIR\atoolstorageserverclnt.dll
+
+
+#endif // __ANALYZETOOL_ROM_IBY__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/sis/AnalyzeTool.pkg Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,42 @@
+;
+; Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+; All rights reserved.
+; This component and the accompanying materials are made available
+; under the terms of "Eclipse Public License v1.0"
+; which accompanies this distribution, and is available
+; at the URL "http://www.eclipse.org/legal/epl-v10.html".
+;
+; Initial Contributors:
+; Nokia Corporation - initial contribution.
+;
+; Contributors:
+;
+; Description:
+;
+
+;Language - standard language definitions
+&EN
+
+; standard SIS file header
+#{"AnalyzeTool"},(0x20012432),1,9,1,TYPE=SA, RU
+
+;Localised Vendor name
+%{"Nokia Corporation"}
+
+;Unique Vendor name
+:"Nokia Corporation"
+
+;Supports Series 60 v 3.1
+[0x102032BE], 0, 0, 0, {"Series60ProductID"}
+
+;Supports S60 release 5.0
+[0x1028315F], 0, 0, 0, {"Series60ProductID"}
+
+"\epoc32\release\armv5\urel\atoolkerneleventhandler.ldd" -"!:\sys\bin\atoolkerneleventhandler.ldd"
+"\epoc32\release\armv5\urel\atoolmemoryhook.dll" -"!:\sys\bin\atoolmemoryhook.dll"
+"\epoc32\release\armv5\urel\atoolstorageserver.exe" -"!:\sys\bin\atoolstorageserver.exe"
+"\epoc32\release\armv5\urel\atoolstorageserverclnt.dll" -"!:\sys\bin\atoolstorageserverclnt.dll"
+"\epoc32\release\armv5\urel\atoolcleaner.dll" -"!:\sys\bin\atoolcleaner.dll"
+
+; Install console application
+"\epoc32\release\armv5\urel\atool.exe"-"!:\sys\bin\atool.exe"
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/sis/AnalyzeTool_udeb.pkg Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,42 @@
+;
+; Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+; All rights reserved.
+; This component and the accompanying materials are made available
+; under the terms of "Eclipse Public License v1.0"
+; which accompanies this distribution, and is available
+; at the URL "http://www.eclipse.org/legal/epl-v10.html".
+;
+; Initial Contributors:
+; Nokia Corporation - initial contribution.
+;
+; Contributors:
+;
+; Description:
+;
+
+;Language - standard language definitions
+&EN
+
+; standard SIS file header
+#{"AnalyzeTool"},(0x20012432),1,9,1,TYPE=SA, RU
+
+;Localised Vendor name
+%{"Nokia Corporation"}
+
+;Unique Vendor name
+:"Nokia Corporation"
+
+;Supports Series 60 v 3.1
+[0x102032BE], 0, 0, 0, {"Series60ProductID"}
+
+;Supports S60 release 5.0
+[0x1028315F], 0, 0, 0, {"Series60ProductID"}
+
+"\epoc32\release\armv5\udeb\atoolkerneleventhandler.ldd" -"!:\sys\bin\atoolkerneleventhandler.ldd"
+"\epoc32\release\armv5\udeb\atoolmemoryhook.dll" -"!:\sys\bin\atoolmemoryhook.dll"
+"\epoc32\release\armv5\udeb\atoolstorageserver.exe" -"!:\sys\bin\atoolstorageserver.exe"
+"\epoc32\release\armv5\udeb\atoolstorageserverclnt.dll" -"!:\sys\bin\atoolstorageserverclnt.dll"
+"\epoc32\release\armv5\urel\atoolcleaner.dll" -"!:\sys\bin\atoolcleaner.dll"
+
+; Install console application
+"\epoc32\release\armv5\udeb\atool.exe"-"!:\sys\bin\atool.exe"
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/sis/analyzeTool_stub.pkg Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,36 @@
+;
+; Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+; All rights reserved.
+; This component and the accompanying materials are made available
+; under the terms of "Eclipse Public License v1.0"
+; which accompanies this distribution, and is available
+; at the URL "http://www.eclipse.org/legal/epl-v10.html".
+;
+; Initial Contributors:
+; Nokia Corporation - initial contribution.
+;
+; Contributors:
+;
+; Description:
+;
+
+;Languages
+&EN
+
+;Header
+#{"AnalyzeTool"}, (0x20012432), 1,9,1
+
+; Non-localised vendor name
+:"Nokia Corporation"
+
+; Localised vendor names
+%{"Nokia Corporation"}
+
+; AnalyzeTool binaries
+""-"z:\sys\bin\atoolkerneleventhandler.ldd"
+""-"z:\sys\bin\atoolmemoryhook.dll"
+""-"z:\sys\bin\atoolstorageserver.exe"
+""-"z:\sys\bin\atoolstorageserverclnt.dll"
+""-"z:\sys\bin\atoolcleaner.dll"
+
+""-"z:\sys\bin\atool.exe"
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/staticlib/group/atoolstaticlib.mmp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,34 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: The .mmp file for AToolStaticLib.
+*
+*/
+
+#include <platform_paths.hrh>
+
+TARGET atoolstaticlib.lib
+TARGETTYPE lib
+UID 0x1000008d 0x20018421//0x02DF7F96
+CAPABILITY ALL -TCB
+
+SMPSAFE
+
+USERINCLUDE ../../inc
+SOURCEPATH ../src
+SOURCE atoolstaticlib.cpp
+
+OS_LAYER_SYSTEMINCLUDE
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/staticlib/group/bld.inf Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,27 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include <platform_paths.hrh>
+
+PRJ_PLATFORMS
+ARMV5 WINSCW
+
+PRJ_EXPORTS
+../../dynamicmemoryhook/inc/customuser.h OS_LAYER_PLATFORM_EXPORT_PATH(analyzetool/customuser.h)
+
+PRJ_MMPFILES
+atoolstaticlib.mmp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/staticlib/src/atoolstaticlib.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,122 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: The file contains declarations of extern methods and definitions
+* of overloaded User methods.
+*
+*/
+
+
+#include <analyzetool/customuser.h>
+#include "atlog.h"
+
+// -----------------------------------------------------------------------------
+// GetInt()
+// Extern function for acquiring all integer values
+// -----------------------------------------------------------------------------
+//
+GLREF_C TInt GetInt( const TUint8 aType );
+
+// -----------------------------------------------------------------------------
+// GetString()
+// Extern function for acquiring all string values
+// -----------------------------------------------------------------------------
+//
+GLREF_C TPtrC GetString( const TUint8 aType );
+
+// -----------------------------------------------------------------------------
+// User::Exit()
+// Overloaded User::Exit() function
+// -----------------------------------------------------------------------------
+//
+void User::Exit( TInt aReason )
+ {
+ LOGSTR2( "ATMH User::Exit %i", aReason );
+ CustomUser::Exit( aReason );
+ }
+
+// -----------------------------------------------------------------------------
+// User::Panic()
+// Overloaded User::Panic() function
+// -----------------------------------------------------------------------------
+//
+void User::Panic( const TDesC& aCategory, TInt aReason )
+ {
+ LOGSTR3( "ATMH User::Panic() %S %i", &aCategory, aReason );
+ CustomUser::Panic( aCategory, aReason );
+ }
+
+// -----------------------------------------------------------------------------
+// User::SetCritical()
+// Overloaded User::SetCritical() function which returns
+// KErrNone, if successful; KErrArgument, if EAllThreadsCritical is
+// passed - this is a state associated with a process, and you use
+// User::SetProcessCritical() to set it.
+// -----------------------------------------------------------------------------
+//
+TInt User::SetCritical( TCritical aCritical )
+ {
+ LOGSTR2( "ATMH User::SetCritical() %i", aCritical );
+ return CustomUser::SetCritical( aCritical );
+ }
+
+// -----------------------------------------------------------------------------
+// User::SetProcessCritical()
+// Overloaded User::SetProcessCritical() function
+// KErrNone, if successful; KErrArgument, if either EProcessCritical or
+// EProcessPermanent is passed - these are states associated with a
+// thread, and you use User::SetCritical() to set them.
+// -----------------------------------------------------------------------------
+//
+TInt User::SetProcessCritical( TCritical aCritical )
+ {
+ LOGSTR2( "ATMH User::SetProcessCritical() %i", aCritical );
+ return CustomUser::SetProcessCritical( aCritical );
+ }
+
+// -----------------------------------------------------------------------------
+// UserHeap::SetupThreadHeap()
+// Overloaded UserHeap::SetupThreadHeap function
+// -----------------------------------------------------------------------------
+//
+TInt UserHeap::SetupThreadHeap( TBool aNotFirst,
+ SStdEpocThreadCreateInfo& aInfo )
+ {
+ LOGSTR1( "ATMH UserHeap::SetupThreadHeap()" );
+
+ // Check validity of parameters
+ TInt logOption( GetInt( (TUint8) CustomUser::ELogOption ) );
+ if ( logOption < 0 )
+ logOption = KATDefaultLogOption;
+
+ TInt debug( GetInt( (TUint8) CustomUser::EDebug ) );
+ if ( debug < 0 )
+ debug = KATDefaultDebug;
+
+ TInt allocCallStack( GetInt( (TUint8) CustomUser::EAllocCallStackSize ) );
+ if ( allocCallStack < 0 )
+ allocCallStack = KATDefaultAllocCallStackSize;
+
+ TInt freeCallStack( GetInt( (TUint8) CustomUser::EFreeCallStackSize ) );
+ if ( freeCallStack < 0 )
+ freeCallStack = KATDefaultFreeCallStackSize;
+
+ return CustomUser::SetupThreadHeap( aNotFirst, aInfo,
+ GetString( (TUint8) CustomUser::ELogFileName ),
+ (TUint32) logOption, (TUint32) debug,
+ GetString( (TUint8) CustomUser::EVersion ),
+ (TUint32) allocCallStack, (TUint32) freeCallStack,
+ KATArgumentList );
+ }
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/client/bwins/atoolstorageserverclntu.def Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,26 @@
+EXPORTS
+ ??0RATStorageServer@@QAE@XZ @ 1 NONAME ; RATStorageServer::RATStorageServer(void)
+ ?CancelLogging@RATStorageServer@@QAEHI@Z @ 2 NONAME ; int RATStorageServer::CancelLogging(unsigned int)
+ ?CheckMemoryAddress@RATStorageServer@@QBEHK@Z @ 3 NONAME ; int RATStorageServer::CheckMemoryAddress(unsigned long) const
+ ?Close@RATStorageServer@@QAEXXZ @ 4 NONAME ; void RATStorageServer::Close(void)
+ ?Connect@RATStorageServer@@QAEHXZ @ 5 NONAME ; int RATStorageServer::Connect(void)
+ ?GetCurrentAllocsL@RATStorageServer@@QAEHIAAK0@Z @ 6 NONAME ; int RATStorageServer::GetCurrentAllocsL(unsigned int, unsigned long &, unsigned long &)
+ ?GetLoadedDllsL@RATStorageServer@@QAEHIAAV?$RArray@V?$TBuf8@$0DM@@@@@@Z @ 7 NONAME ; int RATStorageServer::GetLoadedDllsL(unsigned int, class RArray<class TBuf8<60> > &)
+ ?GetLoggingFileL@RATStorageServer@@QAEHIAAVTDes8@@@Z @ 8 NONAME ; int RATStorageServer::GetLoggingFileL(unsigned int, class TDes8 &)
+ ?GetLoggingModeL@RATStorageServer@@QAEHIAAW4TATLogOption@@@Z @ 9 NONAME ; int RATStorageServer::GetLoggingModeL(unsigned int, enum TATLogOption &)
+ ?GetMaxAllocsL@RATStorageServer@@QAEHIAAK0@Z @ 10 NONAME ; int RATStorageServer::GetMaxAllocsL(unsigned int, unsigned long &, unsigned long &)
+ ?GetProcessesL@RATStorageServer@@QAEHAAV?$RArray@VTATProcessInfo@@@@@Z @ 11 NONAME ; int RATStorageServer::GetProcessesL(class RArray<class TATProcessInfo> &)
+ ?GetUdebL@RATStorageServer@@QAEHIAAK@Z @ 12 NONAME ; int RATStorageServer::GetUdebL(unsigned int, unsigned long &)
+ ?IsMemoryAdded@RATStorageServer@@QAEHK@Z @ 13 NONAME ; int RATStorageServer::IsMemoryAdded(unsigned long)
+ ?LogDllLoaded@RATStorageServer@@QAEHABVTDesC8@@KK@Z @ 14 NONAME ; int RATStorageServer::LogDllLoaded(class TDesC8 const &, unsigned long, unsigned long)
+ ?LogDllUnloaded@RATStorageServer@@QAEHABVTDesC8@@KK@Z @ 15 NONAME ; int RATStorageServer::LogDllUnloaded(class TDesC8 const &, unsigned long, unsigned long)
+ ?LogMemoryAllocated@RATStorageServer@@QAEHKAAV?$TFixedArray@K$0BAA@@@H@Z @ 16 NONAME ; int RATStorageServer::LogMemoryAllocated(unsigned long, class TFixedArray<unsigned long, 256> &, int)
+ ?LogMemoryFreed@RATStorageServer@@QAEHKAAV?$TFixedArray@K$0BAA@@@@Z @ 17 NONAME ; int RATStorageServer::LogMemoryFreed(unsigned long, class TFixedArray<unsigned long, 256> &)
+ ?LogProcessEnded@RATStorageServer@@QAEHII@Z @ 18 NONAME ; int RATStorageServer::LogProcessEnded(unsigned int, unsigned int)
+ ?LogProcessStarted@RATStorageServer@@QAEHABVTDesC16@@ABVTDesC8@@IKK@Z @ 19 NONAME ; int RATStorageServer::LogProcessStarted(class TDesC16 const &, class TDesC8 const &, unsigned int, unsigned long, unsigned long)
+ ?StartSubTest@RATStorageServer@@QAEHABVTDesC8@@@Z @ 20 NONAME ; int RATStorageServer::StartSubTest(class TDesC8 const &)
+ ?StartSubTest@RATStorageServer@@QAEHIABVTDesC8@@H@Z @ 21 NONAME ; int RATStorageServer::StartSubTest(unsigned int, class TDesC8 const &, int)
+ ?StopSubTest@RATStorageServer@@QAEHABVTDesC8@@@Z @ 22 NONAME ; int RATStorageServer::StopSubTest(class TDesC8 const &)
+ ?StopSubTest@RATStorageServer@@QAEHIABVTDesC8@@H@Z @ 23 NONAME ; int RATStorageServer::StopSubTest(unsigned int, class TDesC8 const &, int)
+ ?Version@RATStorageServer@@QBE?AVTVersion@@XZ @ 24 NONAME ; class TVersion RATStorageServer::Version(void) const
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/client/eabi/atoolstorageserverclntu.def Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,27 @@
+EXPORTS
+ _ZN16RATStorageServer11StopSubTestERK6TDesC8 @ 1 NONAME
+ _ZN16RATStorageServer11StopSubTestEjRK6TDesC8i @ 2 NONAME
+ _ZN16RATStorageServer12LogDllLoadedERK6TDesC8mm @ 3 NONAME
+ _ZN16RATStorageServer12StartSubTestERK6TDesC8 @ 4 NONAME
+ _ZN16RATStorageServer12StartSubTestEjRK6TDesC8i @ 5 NONAME
+ _ZN16RATStorageServer13CancelLoggingEj @ 6 NONAME
+ _ZN16RATStorageServer13GetMaxAllocsLEjRmS0_ @ 7 NONAME
+ _ZN16RATStorageServer13GetProcessesLER6RArrayI14TATProcessInfoE @ 8 NONAME
+ _ZN16RATStorageServer13IsMemoryAddedEm @ 9 NONAME
+ _ZN16RATStorageServer14GetLoadedDllsLEjR6RArrayI5TBuf8ILi60EEE @ 10 NONAME
+ _ZN16RATStorageServer14LogDllUnloadedERK6TDesC8mm @ 11 NONAME
+ _ZN16RATStorageServer14LogMemoryFreedEmR11TFixedArrayImLi256EE @ 12 NONAME
+ _ZN16RATStorageServer15GetLoggingFileLEjR5TDes8 @ 13 NONAME
+ _ZN16RATStorageServer15GetLoggingModeLEjR12TATLogOption @ 14 NONAME
+ _ZN16RATStorageServer15LogProcessEndedEjj @ 15 NONAME
+ _ZN16RATStorageServer17GetCurrentAllocsLEjRmS0_ @ 16 NONAME
+ _ZN16RATStorageServer17LogProcessStartedERK7TDesC16RK6TDesC8jmm @ 17 NONAME
+ _ZN16RATStorageServer18LogMemoryAllocatedEmR11TFixedArrayImLi256EEi @ 18 NONAME
+ _ZN16RATStorageServer5CloseEv @ 19 NONAME
+ _ZN16RATStorageServer7ConnectEv @ 20 NONAME
+ _ZN16RATStorageServer8GetUdebLEjRm @ 21 NONAME
+ _ZN16RATStorageServerC1Ev @ 22 NONAME
+ _ZN16RATStorageServerC2Ev @ 23 NONAME
+ _ZNK16RATStorageServer18CheckMemoryAddressEm @ 24 NONAME
+ _ZNK16RATStorageServer7VersionEv @ 25 NONAME
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/client/group/atoolstorageserverclnt.mmp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,41 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: The .mmp file for the client side of AToolStorageServer
+*
+*/
+
+#include <platform_paths.hrh>
+
+TARGET atoolstorageserverclnt.dll
+TARGETTYPE dll
+UID 0x1000008d 0x20012431
+CAPABILITY ALL -TCB
+
+SMPSAFE
+
+SOURCEPATH ../src
+
+SOURCE atstorageserverclnt.cpp
+
+USERINCLUDE ../inc
+USERINCLUDE ../../inc
+USERINCLUDE ../../server/inc
+USERINCLUDE ../../../inc
+
+OS_LAYER_SYSTEMINCLUDE
+
+LIBRARY euser.lib
+LIBRARY flogger.lib
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/client/inc/atstorageserverclnt.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,371 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Declaration of the client side handle class RATStorageServer
+*
+*/
+
+
+
+#ifndef ATSTORAGESERVERCLNT_H
+#define ATSTORAGESERVERCLNT_H
+
+
+// INCLUDES
+#include <e32base.h>
+#include <analyzetool/atcommon.h>
+
+
+// CONSTANTS
+// Constants for the lowest version of the server with which the
+// client is compatible
+const TUint KLowestVersionNumberMaj = 0;
+const TUint KLowestVersionNumberMin = 1;
+const TUint KLowestVersionNumberBld = 1;
+
+
+// FORWARD DECLARATIONS
+class TATProcessInfo;
+
+
+// CLASS DECLARATION
+
+/**
+* The main class of the Storage Server client. Objects of this class work as handles
+* to the Storage Server's server side. Use Connect() to connect a client to the server,
+* and Close() to end an opened session.
+*/
+class RATStorageServer: public RSessionBase
+ {
+ public: // Constructor and destructor
+
+ /**
+ * C++ default constructor.
+ */
+ IMPORT_C RATStorageServer();
+
+ public: // New functions
+
+ /**
+ * Creates a new process for the server, if that doesn't already exist, and
+ * connects a client to the server by creating a new session with it, and
+ * initializes the client for use. To end the server session, use Close().
+ * @return KErrNone, if successful; otherwise one of the other
+ * system-wide error codes.
+ */
+ IMPORT_C TInt Connect();
+
+ /**
+ * Closes a handle to a server session. This has also the effect of destroying
+ * the associated server side session object. Also, the server itself and the
+ * process where it is running are destroyed, if there are no other open sessions
+ * left.
+ */
+ IMPORT_C void Close();
+
+ /**
+ * This method is called to initialize the server for logging and it is to be
+ * called as the first method after connecting to the server. The method informs
+ * the server that a new process has been started. The method cannot be called
+ * again without a call to the LogProcessEnded() first. Otherwise a STSEClient: 3
+ * panic is raised. A KERN-EXEC: 0 panic is raised if the client is not connected
+ * to the server.
+ * @param aFileName The name of the logging file used when the system is logging
+ * to a file (the logging mode is EATLogToFile). The length of aFileName must not be
+ * greater than KMaxFileName, otherwise the method raises a STSEClient: 2 panic.
+ * @param aProcessName The name of the new process started. The length of this
+ * descriptor must not be greater than KMaxProcessName, otherwise the method
+ * raises a STSEClient: 2 panic.
+ * @param aProcessId The ID of the process started.
+ * @param aLogOption An option telling the logging mode.
+ * @param aIsDebug Determines whether a binary is UDEB or UREL
+ * @return KErrNone, if successful; otherwise one of the other
+ * system-wide error codes.
+ */
+ IMPORT_C TInt LogProcessStarted( const TDesC& aFileName,
+ const TDesC8& aProcessName,
+ TUint aProcessId,
+ TUint32 aLogOption, TUint32 aIsDebug );
+
+ /**
+ * Asks the server to log that a new DLL has been loaded. Note, the method
+ * LogProcessStarted() has to be previously called. Otherwise a STSEClient: 3
+ * panic is raised. A KERN-EXEC: 0 panic is raised if the client is not connected
+ * to the server.
+ * @param aDllName The name of the new DLL loaded. The length of this descriptor
+ * must not be greater than KMaxLibraryName, otherwise the method raises a
+ * STSEClient: 2 panic.
+ * @param aStartAddress The start address of the DLL loaded.
+ * @param aEndAddress The end address of the DLL loaded.
+ * @return KErrNone, if successful; otherwise one of the other
+ * system-wide error codes.
+ */
+ IMPORT_C TInt LogDllLoaded( const TDesC8& aDllName, TUint32 aStartAddress,
+ TUint32 aEndAddress );
+
+ /**
+ * Asks the server to log that a new DLL has been unloaded. Note, the method
+ * LogProcessStarted() has to be previously called. Otherwise a STSEClient: 3
+ * panic is raised. A KERN-EXEC: 0 panic is raised if the client is not connected
+ * to the server. If the method is called with illegal parameter values, a
+ * STSEClient: 2 panic is raised.
+ * @param aDllName The name of the DLL to be unloaded. The length of this
+ * descriptor must not be greater than KMaxLibraryName, otherwise the method
+ * raises a STSEClient: 2 panic.
+ * @param aStartAddress The start address of the DLL to be unloaded.
+ * @param aEndAddress The end address of the DLL to be unloaded.
+ * @return KErrNone, if successful; otherwise one of the other
+ * system-wide error codes.
+ */
+ IMPORT_C TInt LogDllUnloaded( const TDesC8& aDllName, TUint32 aStartAddress,
+ TUint32 aEndAddress );
+
+ /**
+ * Informs the server that a memory allocation has occured at the specified
+ * address. Sends also the current call stack to the server. Note, the method
+ * LogProcessStarted() has to be previously called. Otherwise a STSEClient: 3
+ * panic is raised. A KERN-EXEC: 0 panic is raised if the client is not connected
+ * to the server.
+ * @param aMemAddress The memory location where memory has been allocated.
+ * @param aCallstack An array including the current call stack.
+ * @param aSize The size of the newly allocated memory chunk.
+ * @return KErrNone, if successful; otherwise one of the other
+ * system-wide error codes.
+ */
+ IMPORT_C TInt LogMemoryAllocated( TUint32 aMemAddress,
+ TFixedArray<TUint32, KATMaxCallstackLength>& aCallstack,
+ TInt aSize );
+
+ /**
+ * Informs the server that memory was released at the specified address. Note,
+ * the method LogProcessStarted() has to be previously called. Otherwise a
+ * STSEClient: 3 panic is raised. A KERN-EXEC: 0 panic is raised if the client is
+ * not connected to the server.
+ * @param aMemAddress The memory location where memory has been deallocated.
+ * @param aFreeCallstack An array including the current call stack.
+ * @return KErrNone, if successful; otherwise one of the other
+ * system-wide error codes.
+ */
+ IMPORT_C TInt LogMemoryFreed( TUint32 aMemAddress,
+ TFixedArray<TUint32, KATMaxFreeCallstackLength>& aFreeCallstack );
+
+ /**
+ * Tells the server that the process under test has been ended. Prints information
+ * related to process ending, such as possibly occured memory leaks (when file
+ * logging mode used), and possibly occured handle leaks. Note, the method
+ * LogProcessStarted() has to be previously called. Otherwise a STSEClient:
+ * 3 panic is raised. A call to this method also closes the file opened for
+ * the current process. So, no further logging is possible without a new call
+ * to the method LogProcessStarted(). A KERN-EXEC: 0 panic is raised if the client
+ * is not connected to the server.
+ * @param aProcessId The ID number of the process ended.
+ * @param aHandleLeaks Amount of handle leaks.
+ * @return KErrNone, if successful; otherwise one of the other
+ * system-wide error codes.
+ */
+ IMPORT_C TInt LogProcessEnded( TUint aProcessId,
+ TUint aHandleLeaks );
+
+ /**
+ * Gives the lowest version number of the server needed for this client.
+ * @return The lowest version of the server needed for this client.
+ */
+ IMPORT_C TVersion Version() const;
+
+ /**
+ * Checks if the current process has allocated, but not freed, the given memory
+ * address. Note, the method LogProcessStarted() has to be previously called.
+ * Otherwise a STSEClient: 3 panic is raised. A KERN-EXEC: 0 panic is raised if
+ * the client is not connected to the server.
+ * @param aMemAddress The memory location to check.
+ * @return When the system is logging into a file: the index of a found
+ * memory address or KErrNotFound, if a matching memory address cannot
+ * be found. When the system is not logging into a file: always KErrNone.
+ */
+ IMPORT_C TInt CheckMemoryAddress( TUint32 aMemAddress ) const;
+
+ /**
+ * Gets all the processes with currently open logging sessions.
+ * @param aProcesses A reference to a process array to be filled by the server.
+ * @return KErrNone, if successful; otherwise one of the other
+ * system wide error codes.
+ */
+ IMPORT_C TInt GetProcessesL( RArray<TATProcessInfo>& aProcesses );
+
+ /**
+ * Gets all the DLLs loaded by the given process.
+ * @param aProcessId The ID of the process whose DLLs will be fetched.
+ * @param aDlls An array that after this function call includes names of
+ * the given process's dlls
+ * @return KErrNone, if successful; KErrNotFound, if the requested process was
+ * not found; otherwise one of the other system wide error codes.
+ */
+ IMPORT_C TInt GetLoadedDllsL( TUint aProcessId,
+ RArray< TBuf8<KMaxLibraryName> >& aDlls );
+
+ /**
+ * Gets the logging mode of the given process.
+ * @param aProcessId The ID of the process whose logging mode is being asked.
+ * @param aLoggingMode An enumeration telling the logging mode after a call
+ * to this function.
+ * @return KErrNone, if successful; KErrNotFound, if the requested process was
+ * not found; otherwise one of the other system wide error codes.
+ */
+ IMPORT_C TInt GetLoggingModeL( TUint aProcessId, TATLogOption& aLoggingMode );
+
+ /**
+ * Starts a sub test for the given process.
+ * @param aProcessId The ID of the process for which to start a sub test.
+ * @param aSubtestId The name identifying this particular sub test. The length
+ * of this descriptor must not be greater than KATMaxSubtestIdLength, or
+ * otherwise the method raises a STSEClient: 2 panic.
+ * @param aHandleCount The current handle count of a particular process.
+ * @return KErrNone, if successful; KErrNotFound, if the requested process was not
+ * found; KErrNotSupported, if the requested process does not have a logging
+ * session ongoing or its logging mode is not EATLogToTrace; Otherwise one of the
+ * other system wide error codes.
+ */
+ IMPORT_C TInt StartSubTest( TUint aProcessId, const TDesC8& aSubtestId, TInt aHandleCount = 0 );
+
+ /**
+ * Stops a sub test for the given process.
+ * @param aProcessId The ID of the process for which to stop a sub test.
+ * @param aSubtestId The name identifying this particular sub test. The length
+ * of this descriptor must not be greater than KATMaxSubtestIdLength, or
+ * otherwise the method raises a STSEClient: 2 panic.
+ * @param aHandleCount The current handle count of a particular process.
+ * @return KErrNone, if successful; KErrNotFound, if the requested process was not
+ * found; KErrNotSupported, if the requested process does not have a logging
+ * session ongoing or its logging mode is not EATLogToTrace; Otherwise one of the
+ * other system wide error codes.
+ */
+ IMPORT_C TInt StopSubTest( TUint aProcessId, const TDesC8& aSubtestId, TInt aHandleCount = 0 );
+
+ /**
+ * Gets the number and total size of the memory chunks currently allocated by the
+ * requested process.
+ * @param aProcessId The ID of the process whose information is requested.
+ * @param aNumber On return contains the number of memory chunks currenlty
+ * allocated by the requested process.
+ * @param aSize On return contains the amount of memory currently allocated
+ * by the requested process.
+ * @return KErrNone, if successful; KErrNotFound, if the requested process was not
+ * found; Otherwise one of the other system wide error codes.
+ */
+ IMPORT_C TInt GetCurrentAllocsL( TUint aProcessId, TUint32& aNumber, TUint32& aSize );
+
+ /**
+ * Gets the maximum number and total size of the memory chunks allocated by the
+ * requested process.
+ * @param aProcessId The ID of the process whose information is requested.
+ * @param aNumber On return contains the maximum number of memory chunks
+ * allocated by the requested process during the test run.
+ * @param aSize On return contains the maximum amount of memory allocated
+ * by the requested process during the test run.
+ * @return KErrNone, if successful; KErrNotFound, if the requested process was not
+ * found; Otherwise one of the other system wide error codes.
+ */
+ IMPORT_C TInt GetMaxAllocsL( TUint aProcessId, TUint32& aNumber, TUint32& aSize );
+
+ /**
+ * Starts a sub test for the calling process.
+ * @param aSubtestId The name identifying this particular sub test. The length
+ * of this descriptor must not be greater than KATMaxSubtestIdLength, or
+ * otherwise the method raises a STSEClient: 2 panic.
+ * @return KErrNone, if successful; KErrNotSupported, if the calling process
+ * does not have a logging session ongoing or its logging mode is not
+ * EATLogToTrace; Otherwise one of the other system wide error codes.
+ */
+ IMPORT_C TInt StartSubTest( const TDesC8& aSubtestId );
+
+ /**
+ * Stops a sub test for the calling process
+ * @param aSubtestId The name identifying this particular sub test. The length
+ * of this descriptor must not be greater than KATMaxSubtestIdLength, or
+ * otherwise the method raises a STSEClient: 2 panic.
+ * @return KErrNone, if successful; KErrNotSupported, if the calling process
+ * does not have a logging session ongoing or its logging mode is not
+ * EATLogToTrace; Otherwise one of the other system wide error codes.
+ */
+ IMPORT_C TInt StopSubTest( const TDesC8& aSubtestId );
+
+ /**
+ * Cancels logging for the requested process. After logging of a given process
+ * has been cancelled, the session associated with that process will not be
+ * usable anymore. If a process wants to start logging again, it needs to close
+ * the handle and open it again in order to create a new session. Until then, most
+ * of the client's methods will return KErrCancel.
+ * @param aProcessId The process ID of the process whose logging is requested to
+ * be cancelled.
+ * @return KErrNone, if successful; KErrNotFound, if the requested process was
+ * not found; otherwise one of the other system wide error codes.
+ */
+ IMPORT_C TInt CancelLogging( TUint aProcessId );
+
+ /**
+ * Gets the number and total size of the memory chunks currently allocated by the
+ * requested process.
+ * @param aProcessId The ID of the process whose information is requested.
+ * @param aIsUdeb On return contains an value greater than KErrNone if
+ * mode is UDEB. Else the mode is UREL
+ * @return KErrNone, if successful; KErrNotFound, if the requested process was not
+ * found; Otherwise one of the other system wide error codes.
+ */
+ IMPORT_C TInt GetUdebL( TUint aProcessId, TUint32& aIsUdeb );
+
+ /**
+ * Gets the number and total size of the memory chunks currently allocated by the
+ * requested process.
+ * @param aProcessId The ID of the process whose information is requested.
+ * @param aFileName On return contains logging filename for the process.
+ * @return KErrNone, if successful; KErrNotFound, if the requested process was not
+ * found; Otherwise one of the other system wide error codes.
+ */
+ IMPORT_C TInt GetLoggingFileL( TUint aProcessId, TDes8& aFileName );
+
+ /**
+ * Check a memory allocation (memory address) from an internal array.
+ * @param aMemAddress The memory address to be check
+ * @return KErrNone, if memory address found in array;
+ * KErrNotFound, if the requested memory address was not found.
+ */
+ IMPORT_C TInt IsMemoryAdded( TUint32 aMemAddress );
+
+ protected: // New functions
+
+ /**
+ * Creates a new process for the server, if it does not already exist.
+ * @return KErrNone, if successful; otherwise one of the other
+ * system-wide error codes.
+ */
+ TInt CreateProcess();
+
+ private: // Internal functions
+
+ /**
+ * Creates two buffers: one for storing call stack memory addresses and one for
+ * handle leaks. Internally used by this class. May leave, if there is
+ * insufficient memory.
+ */
+ void ConstructBuffersL();
+
+ private: // Data
+
+ /** A pointer to a buffer of call stack's memory addresses */
+ CBufFlat* iStackBuf;
+ };
+
+#endif // ATSTORAGESERVERCLNT_H
+
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/client/src/atstorageserverclnt.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,930 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Definitions for the client side handle class RATStorageServer
+*
+*/
+
+
+
+// INCLUDE FILES
+#include "atstorageserverclnt.h"
+#include "atstorageserver.h"
+#include "atlog.h"
+#include "atstorageservercommon.h"
+
+
+// CONSTANTS
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::RATStorageServer
+// C++ default constructor.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C RATStorageServer::RATStorageServer() :
+ RSessionBase(), iStackBuf( NULL )
+ {
+ LOGSTR1( "STSE RATStorageServer::RATStorageServer()" );
+ }
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::Connect
+// A function for connecting to the server
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt RATStorageServer::Connect()
+ {
+ LOGSTR1( "STSE TInt RATStorageServer::Connect()" );
+
+ TInt errorCode( KErrNone );
+ errorCode = CreateProcess();
+
+ // If process's creation failed, return the error code
+ if ( errorCode != KErrNone )
+ {
+ return errorCode;
+ }
+
+ // Otherwise create a new session
+ errorCode = CreateSession( KStorageServerName, Version() );
+
+ // If creation of a new session failed, return the error code
+ if ( errorCode != KErrNone )
+ {
+ return errorCode;
+ }
+
+ // Construct a buffer for call stack's memory addresses. If the function leaves,
+ // the leave code is put in "errorCode".
+ TRAP( errorCode, ConstructBuffersL() );
+
+ return errorCode;
+ }
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::Close
+// Destroys all memory reserved by this class, and calls RSessionBase::Close()
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void RATStorageServer::Close()
+ {
+ LOGSTR1( "STSE void RATStorageServer::Close()" );
+
+ // Delete iStackBuf
+ delete iStackBuf;
+ iStackBuf = NULL;
+
+ // Call the base class' Close()
+ RSessionBase::Close();
+ }
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::LogProcessStarted
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt RATStorageServer::LogProcessStarted( const TDesC& aFileName,
+ const TDesC8& aProcessName,
+ TUint aProcessId,
+ TUint32 aLogOption, TUint32 aIsDebug )
+ {
+ LOGSTR1( "STSE TInt RATStorageServer::LogProcessStarted()" );
+
+ // Panic always if aFileName or aProcessName are longer than allowed.
+ __ASSERT_ALWAYS( aFileName.Length() <= KMaxFileName &&
+ aProcessName.Length() <= KMaxProcessName,
+ StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+
+ // Panic (in debug builds) if aProcessId is KNullProcessId
+ __ASSERT_DEBUG( aProcessId != KNullProcessId,
+ StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+
+ // This information is optional -> ignoring error
+ // Must be before EProcessStarted in order to append udeb/urel
+ // information to LogProcessStarted
+ TIpcArgs ipcArgs2( aIsDebug );
+ SendReceive( CATStorageServer::EProcessUdeb, ipcArgs2 );
+
+ TIpcArgs ipcArgs( &aFileName, &aProcessName, aProcessId, aLogOption );
+ TInt error( 0 );
+
+ error = SendReceive( CATStorageServer::EProcessStarted, ipcArgs );
+
+ // Return, if error is not KErrNone.
+ if ( error != KErrNone )
+ {
+ return error;
+ }
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::LogDllLoaded
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt RATStorageServer::LogDllLoaded( const TDesC8& aDllName,
+ TUint32 aStartAddress,
+ TUint32 aEndAddress )
+ {
+ LOGSTR1( "STSE TInt RATStorageServer::LogDllLoaded()" );
+
+ // Panic always if aDllName is longer than allowed.
+ __ASSERT_ALWAYS( aDllName.Length() <= KMaxLibraryName,
+ StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+
+ // Panic (in debug builds) if aStartAddress is greater than aEndAddress
+ __ASSERT_DEBUG( aStartAddress <= aEndAddress,
+ StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+
+ TIpcArgs ipcArgs( &aDllName, aStartAddress, aEndAddress );
+
+ return SendReceive( CATStorageServer::EDllLoaded, ipcArgs );
+ }
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::LogDllUnloaded
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt RATStorageServer::LogDllUnloaded( const TDesC8& aDllName,
+ TUint32 aStartAddress,
+ TUint32 aEndAddress )
+ {
+ LOGSTR1( "STSE TInt RATStorageServer::LogDllUnloaded()" );
+
+ // Panic always if aDllName is longer than allowed.
+ __ASSERT_ALWAYS( aDllName.Length() <= KMaxLibraryName,
+ StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+
+ // Panic (in debug builds) if aStartAddress is greater than aEndAddress
+ __ASSERT_DEBUG( aStartAddress <= aEndAddress,
+ StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+
+ TIpcArgs ipcArgs( &aDllName, aStartAddress, aEndAddress );
+
+ return SendReceive( CATStorageServer::EDllUnloaded, ipcArgs );
+ }
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::LogMemoryAllocated
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt RATStorageServer::LogMemoryAllocated( TUint32 aMemAddress,
+ TFixedArray<TUint32, KATMaxCallstackLength>& aCallstack,
+ TInt aSize )
+ {
+ LOGSTR1( "STSE TInt RATStorageServer::LogMemoryAllocated()" );
+
+ TInt count=0;
+ // The number of memory addresses in aCallstack
+ for ( TInt i = 0; i < KATMaxCallstackLength; i++ )
+ {
+ if( aCallstack[i] == 0 )
+ {
+ break;
+ }
+ count++;
+ }
+
+ LOGSTR2( "STSE The number of memory addresses in the current call stack: %d", count );
+
+ // The maximum number of call stack's memory addresses this server can handle
+ // is KMaxCallstackLength
+ if ( count > KATMaxCallstackLength )
+ {
+ count = KATMaxCallstackLength;
+ }
+
+ // Panic (in debug builds) if the parameters are faulty
+ __ASSERT_DEBUG( aMemAddress != 0 && count >= 0 && aSize >= 0,
+ StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+
+ // Buffer position
+ TInt pos = 0;
+ TUint32 callStackAddr;
+
+ // Write the number of memory addresses of aCallstack (one word) into
+ // the beginning of the call stack buffer
+ iStackBuf->Write( pos, &count, KWordSize );
+
+ // Increase the position by one word
+ pos += KWordSize;
+
+ // Write all the memory addresses of aCallStack into the buffer
+ for ( TInt i = 0; i < count; i++ )
+ {
+ callStackAddr = aCallstack[i];
+
+ // Write the current memory address (the length of an address is one word)
+ iStackBuf->Write( pos, &callStackAddr, KWordSize );
+
+ // Move the pos variable one word (4 bytes) onwards.
+ pos += KWordSize;
+ }
+
+ TPtr8 bufPtr( iStackBuf->Ptr(0) );
+
+ TIpcArgs ipcArgs( aMemAddress, &bufPtr, aSize );
+
+ return SendReceive( CATStorageServer::EMemoryAllocated, ipcArgs );
+ }
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::LogMemoryFreed
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt RATStorageServer::LogMemoryFreed( TUint32 aMemAddress,
+ TFixedArray<TUint32, KATMaxFreeCallstackLength>& aFreeCallstack )
+ {
+ LOGSTR1( "STSE TInt RATStorageServer::LogMemoryFreed()" );
+
+ TInt count=0;
+ // The number of memory addresses in aFreeCallstack
+ for ( TInt i = 0; i < KATMaxCallstackLength; i++ )
+ {
+ if( aFreeCallstack[i] == 0 )
+ {
+ break;
+ }
+ count++;
+ }
+ LOGSTR3( "STSE > aFreeCallstack.Count() ( %i ), address( %x )",
+ count, aMemAddress );
+
+ // The maximum number of call stack's memory addresses this server can handle
+ // is KMaxCallstackLength
+ if ( count > KATMaxFreeCallstackLength )
+ {
+ count = KATMaxFreeCallstackLength;
+ }
+
+ // Buffer position
+ TInt pos = 0;
+ TUint32 callStackAddr;
+
+ // Write the number of memory addresses of aFreeCallstack (one word) into
+ // the beginning of the call stack buffer
+ iStackBuf->Write( pos, &count, KWordSize );
+
+ // Increase the position by one word
+ pos += KWordSize;
+
+ // Write all the memory addresses of aFreeCallstack into the buffer
+ for ( TInt i = 0; i < count; i++ )
+ {
+ callStackAddr = aFreeCallstack[i];
+
+ // Write the current memory address (the length of an address is one word)
+ iStackBuf->Write( pos, &callStackAddr, KWordSize );
+
+ // Move the pos variable one word (4 bytes) onwards.
+ pos += KWordSize;
+ }
+
+ TPtr8 bufPtr( iStackBuf->Ptr( 0 ) );
+ TIpcArgs ipcArgs( aMemAddress, &bufPtr );
+
+ return SendReceive( CATStorageServer::EMemoryFreed, ipcArgs );
+ }
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::LogProcessEnded
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt RATStorageServer::LogProcessEnded( TUint aProcessId,
+ TUint aHandleLeaks )
+ {
+ LOGSTR1( "STSE TInt RATStorageServer::LogProcessEnded()" );
+
+ // Panic (in debug builds) if the parameters are faulty
+ __ASSERT_DEBUG( aProcessId != KNullProcessId,
+ StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+
+ TIpcArgs ipcArgs( aProcessId, aHandleLeaks );
+
+ return SendReceive( CATStorageServer::EProcessEnded, ipcArgs );
+ }
+
+//-----------------------------------------------------------------------------
+// RATStorageServer::Version()
+// Returns the version number.
+//-----------------------------------------------------------------------------
+//
+EXPORT_C TVersion RATStorageServer::Version() const
+ {
+ LOGSTR1( "STSE TInt RATStorageServer::Version()" );
+
+ return TVersion(KLowestVersionNumberMaj, KLowestVersionNumberMin,
+ KLowestVersionNumberBld);
+ }
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::CheckMemoryAddress
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt RATStorageServer::CheckMemoryAddress( TUint32 aMemAddress ) const
+ {
+ LOGSTR1( "STSE TInt RATStorageServer::CheckMemoryAddress()" );
+
+ // Panic (in debug builds) if the parameters are faulty
+ __ASSERT_DEBUG( aMemAddress != 0,
+ StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+
+ TIpcArgs ipcArgs( aMemAddress );
+
+ return SendReceive( CATStorageServer::EMemoryCheck, ipcArgs );
+ }
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::GetProcessesL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt RATStorageServer::GetProcessesL( RArray<TATProcessInfo>& aProcesses )
+ {
+ LOGSTR1( "STSE TInt RATStorageServer::GetProcessesL()" );
+
+ TInt error( KErrNone );
+ TInt sizeOfProcessInfo = sizeof( TATProcessInfo );
+
+ // Reset the sent array
+ aProcesses.Reset();
+
+ // Calculate the length of the buffer to be constructed for processes.
+ // One word will be reserved for the length of the array.
+ TInt bufferLength = KWordSize + KATMaxProcesses * sizeOfProcessInfo;
+
+ CBufFlat* processBuf;
+ // Construct processBuf and expand it before the beginning (index 0)
+ processBuf = CBufFlat::NewL( bufferLength );
+ CleanupStack::PushL( processBuf );
+ processBuf->ExpandL( 0, bufferLength );
+
+ TPtr8 bufPtr( processBuf->Ptr(0) );
+
+ // Send the buffer to the server, which will fill it.
+ TIpcArgs ipcArgs( &bufPtr );
+ error = SendReceive( CATStorageServer::EGetProcesses, ipcArgs );
+ // Return with the error code if the operation failed
+ if ( error != KErrNone )
+ {
+ CleanupStack::PopAndDestroy( processBuf );
+ return error;
+ }
+
+ // A variable for the number of TATProcessInfo objects
+ TInt count( 0 );
+ // A variable for the position
+ TInt pos( 0 );
+
+ // Read the value for count
+ processBuf->Read( pos, &count, KWordSize );
+
+ // Return if we got an illegal value for count
+ if ( count < 0 || count > KATMaxProcesses )
+ {
+ CleanupStack::PopAndDestroy( processBuf );
+ return KErrGeneral;
+ }
+
+ // Move the position one word onwards.
+ pos += KWordSize;
+
+ TATProcessInfo processInfo;
+
+ // Go through all TATProcessInfo objects sent to the server
+ for ( TInt j = 0; j < count; j++ )
+ {
+ // Read one of the TATProcessInfo objects stored in the buffer.
+ processBuf->Read( pos, &processInfo, sizeOfProcessInfo );
+
+ // Append this processInfo to the array
+ error = aProcesses.Append( processInfo );
+
+ if ( error != KErrNone )
+ {
+ CleanupStack::PopAndDestroy( processBuf );
+ return error;
+ }
+
+ // Move the pos variable one word onwards.
+ pos += sizeOfProcessInfo;
+ }
+
+ CleanupStack::PopAndDestroy( processBuf );
+ return error;
+ }
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::GetLoadedDllsL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt RATStorageServer::GetLoadedDllsL( TUint aProcessId,
+ RArray< TBuf8<KMaxLibraryName> >& aDlls )
+ {
+ LOGSTR1( "STSE TInt RATStorageServer::GetLoadedDllsL()" );
+
+ // Panic (in debug builds) if aProcessId is faulty
+ __ASSERT_DEBUG( aProcessId != KNullProcessId,
+ StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+
+ TInt error( KErrNone );
+
+ // Size of a DLL descriptor
+ TInt sizeOfDllDesc = sizeof( TBuf8<KMaxLibraryName> );
+
+ // Reset the sent array
+ aDlls.Reset();
+
+ // Calculate the length of the buffer to be constructed for DLL names.
+ // One word will be reserved for the length of the array.
+ TInt bufferLength = KWordSize + KATMaxDlls * sizeOfDllDesc;
+
+ CBufFlat* dllBuf;
+ // Construct dllBuf and expand it before the beginning (index 0)
+ dllBuf = CBufFlat::NewL( bufferLength );
+ CleanupStack::PushL( dllBuf );
+ dllBuf->ExpandL( 0, bufferLength );
+
+ TPtr8 bufPtr( dllBuf->Ptr(0) );
+
+ // Call the server with the given arguments
+ TIpcArgs ipcArgs( aProcessId, &bufPtr );
+ error = SendReceive( CATStorageServer::EGetDlls, ipcArgs );
+
+ // Return, if error is not KErrNone.
+ if ( error != KErrNone )
+ {
+ CleanupStack::PopAndDestroy( dllBuf );
+ return error;
+ }
+
+ // A variable for the number of objects in the buffer
+ TInt count( 0 );
+
+ // A variable for the position
+ TInt pos( 0 );
+
+ // Read the value for count
+ dllBuf->Read( pos, &count, KWordSize );
+
+ // Return if we got an illegal value for count
+ if ( count < 0 || count > KATMaxDlls )
+ {
+ CleanupStack::PopAndDestroy( dllBuf );
+ return KErrGeneral;
+ }
+
+ // Move the position one word onwards.
+ pos += KWordSize;
+
+ TBuf8<KMaxLibraryName> dllName;
+
+ // Go through all DLL names objects sent to the server
+ for ( TInt j = 0; j < count; j++ )
+ {
+ // Read one of the DLL names stored in the buffer.
+ dllBuf->Read( pos, &dllName, sizeOfDllDesc );
+
+ // Append this DLL name to the array
+ error = aDlls.Append( dllName );
+
+ if ( error != KErrNone )
+ {
+ return error;
+ }
+
+ // Move the pos variable one word onwards.
+ pos += sizeOfDllDesc;
+ }
+
+ CleanupStack::PopAndDestroy( dllBuf );
+ return error;
+ }
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::GetLoggingModeL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt RATStorageServer::GetLoggingModeL( TUint aProcessId,
+ TATLogOption& aLoggingMode )
+ {
+ LOGSTR1( "STSE TInt RATStorageServer::GetLoggingModeL()" );
+
+ // Panic (in debug builds) if aProcessId is illegal
+ __ASSERT_DEBUG( aProcessId != KNullProcessId,
+ StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+
+ TInt error(0);
+
+ // The length of the buffer to be constructed for logging mode
+ TInt bufferLength = KWordSize;
+
+ CBufFlat* loggingModeBuf;
+ // Construct allocInfoBuf and expand it before the beginning (index 0)
+ loggingModeBuf = CBufFlat::NewL( bufferLength );
+ CleanupStack::PushL( loggingModeBuf );
+ loggingModeBuf->ExpandL( 0, bufferLength );
+
+ TPtr8 bufPtr( loggingModeBuf->Ptr(0) );
+
+ // Call the server
+ TIpcArgs ipcArgs( aProcessId, &bufPtr );
+ error = SendReceive( CATStorageServer::EGetLoggingMode, ipcArgs );
+
+ // Return if an error occured.
+ if ( error )
+ {
+ CleanupStack::PopAndDestroy( loggingModeBuf );
+ return error;
+ }
+
+ // A variable for the position
+ TInt pos( 0 );
+
+ // Read the value for aNumber
+ loggingModeBuf->Read( pos, &aLoggingMode, KWordSize );
+
+ CleanupStack::PopAndDestroy( loggingModeBuf );
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::StartSubTest
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt RATStorageServer::StartSubTest( TUint aProcessId,
+ const TDesC8& aSubtestId, TInt aHandleCount )
+ {
+ LOGSTR1( "STSE TInt RATStorageServer::StartSubTest()" );
+
+ // Panic if the parameters are faulty
+ __ASSERT_ALWAYS( aSubtestId.Length() <= KATMaxSubtestIdLength,
+ StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+
+ // Panic (in debug builds) if the parameters are faulty
+ __ASSERT_DEBUG( aProcessId != KNullProcessId,
+ StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+
+ TIpcArgs ipcArgs( aProcessId, &aSubtestId, aHandleCount );
+
+ return SendReceive( CATStorageServer::ESubtestStart, ipcArgs );
+ }
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::StopSubTest
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt RATStorageServer::StopSubTest( TUint aProcessId,
+ const TDesC8& aSubtestId, TInt aHandleCount )
+ {
+ LOGSTR1( "STSE TInt RATStorageServer::StopSubTest()" );
+
+ // Panic if the parameters are faulty
+ __ASSERT_ALWAYS( aSubtestId.Length() <= KATMaxSubtestIdLength,
+ StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+
+ // Panic (in debug builds) if the parameters are faulty
+ __ASSERT_DEBUG( aProcessId != KNullProcessId,
+ StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+
+ TIpcArgs ipcArgs( aProcessId, &aSubtestId, aHandleCount );
+
+ return SendReceive( CATStorageServer::ESubtestStop, ipcArgs );
+ }
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::GetCurrentAllocsL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt RATStorageServer::GetCurrentAllocsL( TUint aProcessId,
+ TUint32& aNumber,
+ TUint32& aSize )
+ {
+ LOGSTR1( "STSE TInt RATStorageServer::GetCurrentAllocsL()" );
+
+ // Panic (in debug builds) if aProcessId is illegal
+ __ASSERT_DEBUG( aProcessId != KNullProcessId,
+ StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+
+ TInt error(0);
+
+ // The length of the buffer to be constructed for allocation number and size
+ TInt bufferLength = KWordSize + KWordSize;
+
+ CBufFlat* allocInfoBuf;
+ // Construct allocInfoBuf and expand it before the beginning (index 0)
+ allocInfoBuf = CBufFlat::NewL( bufferLength );
+ CleanupStack::PushL( allocInfoBuf );
+ allocInfoBuf->ExpandL( 0, bufferLength );
+
+ TPtr8 bufPtr( allocInfoBuf->Ptr(0) );
+
+ // Call the server
+ TIpcArgs ipcArgs( aProcessId, &bufPtr );
+ error = SendReceive( CATStorageServer::EGetCurrentAllocs, ipcArgs );
+
+ // Return if error is not KErrNone.
+ if ( error != KErrNone )
+ {
+ CleanupStack::PopAndDestroy( allocInfoBuf );
+ return error;
+ }
+
+ // A variable for the position
+ TInt pos( 0 );
+
+ // Read the value for aNumber
+ allocInfoBuf->Read( pos, &aNumber, KWordSize );
+
+ pos += KWordSize;
+
+ // Read the value for aSize
+ allocInfoBuf->Read( pos, &aSize, KWordSize );
+
+ CleanupStack::PopAndDestroy( allocInfoBuf );
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::GetMaxAllocsL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt RATStorageServer::GetMaxAllocsL( TUint aProcessId,
+ TUint32& aNumber,
+ TUint32& aSize )
+ {
+ LOGSTR1( "STSE TInt RATStorageServer::GetMaxAllocsL()" );
+
+ // Panic (in debug builds) if aProcessId is illegal
+ __ASSERT_DEBUG( aProcessId != KNullProcessId,
+ StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+
+ TInt error(0);
+
+ // The length of the buffer to be constructed for allocation number and size
+ TInt bufferLength = KWordSize + KWordSize;
+
+ CBufFlat* allocInfoBuf;
+ // Construct allocInfoBuf and expand it before the beginning (index 0)
+ allocInfoBuf = CBufFlat::NewL( bufferLength );
+ CleanupStack::PushL( allocInfoBuf );
+ allocInfoBuf->ExpandL( 0, bufferLength );
+
+ TPtr8 bufPtr( allocInfoBuf->Ptr(0) );
+
+ // Call the server
+ TIpcArgs ipcArgs( aProcessId, &bufPtr );
+ error = SendReceive( CATStorageServer::EGetMaxAllocs, ipcArgs );
+
+ // Return, if error is not KErrNone.
+ if ( error != KErrNone )
+ {
+ CleanupStack::PopAndDestroy( allocInfoBuf );
+ return error;
+ }
+
+ // A variable for the position
+ TInt pos( 0 );
+
+ // Read the value for aNumber
+ allocInfoBuf->Read( pos, &aNumber, KWordSize );
+
+ pos += KWordSize;
+
+ // Read the value for aSize
+ allocInfoBuf->Read( pos, &aSize, KWordSize );
+
+ CleanupStack::PopAndDestroy( allocInfoBuf );
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::StartSubTest
+// An overloaded version without a PID parameter
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt RATStorageServer::StartSubTest( const TDesC8& aSubtestId )
+ {
+ LOGSTR1( "STSE TInt RATStorageServer::StartSubTest()" );
+
+ // Panic if the parameters are faulty
+ __ASSERT_ALWAYS( aSubtestId.Length() <= KATMaxSubtestIdLength,
+ StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+
+ TIpcArgs ipcArgs( &aSubtestId );
+
+ return SendReceive( CATStorageServer::ESubtestStart2, ipcArgs );
+ }
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::StopSubTest
+// An overloaded version without a PID parameter
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt RATStorageServer::StopSubTest( const TDesC8& aSubtestId )
+ {
+ LOGSTR1( "STSE TInt RATStorageServer::StopSubTest()" );
+
+ // Panic if the parameters are faulty
+ __ASSERT_ALWAYS( aSubtestId.Length() <= KATMaxSubtestIdLength,
+ StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+
+ TIpcArgs ipcArgs( &aSubtestId );
+
+ return SendReceive( CATStorageServer::ESubtestStop2, ipcArgs );
+ }
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::CancelLogging
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt RATStorageServer::CancelLogging( TUint aProcessId )
+ {
+ LOGSTR1( "STSE TInt RATStorageServer::CancelLogging()" );
+
+ // Panic (in debug builds) if aProcessId is illegal
+ __ASSERT_DEBUG( aProcessId != KNullProcessId,
+ StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+
+ TIpcArgs ipcArgs( aProcessId );
+
+ return SendReceive( CATStorageServer::ECancelLogging, ipcArgs );
+ }
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::CreateProcess
+// Checks if the server already exists. If it doesn't, creates a new process
+// for it.
+// -----------------------------------------------------------------------------
+//
+TInt RATStorageServer::CreateProcess()
+ {
+ LOGSTR1( "STSE TInt RATStorageServer::CreateProcess()" );
+
+ TInt errorCode( KErrNone );
+
+ // Check if the server already exists
+ TFindServer findServer( KStorageServerName );
+ TFullName fullName;
+
+ errorCode = findServer.Next( fullName );
+
+ // Return KErrNone if the server is already running
+ if ( errorCode == KErrNone )
+ {
+ return KErrNone;
+ }
+
+ // Otherwise initiate starting the server by creating first a new process for it.
+ // The second argument of the Create() method call is an empty descriptor, because
+ // we don't need to pass any data to the thread function of the new process's main
+ // thread.
+ RProcess process;
+ errorCode = process.Create( KStorageServerFile, KNullDesC );
+
+ // Return the error code if the creation of the process failed
+ if ( errorCode != KErrNone )
+ {
+ return errorCode;
+ }
+
+ TRequestStatus status;
+ process.Rendezvous( status );
+
+ // If the status is not KRequestPending, abort the project creation
+ // and return KErrGeneral
+ if ( status != KRequestPending )
+ {
+ process.RendezvousCancel( status );
+ process.Kill( KErrGeneral );
+ process.Close();
+ return KErrGeneral;
+ }
+
+ // Otherwise make the first thread of the new process eligible for execution
+ process.Resume();
+
+ // Wait for a signal from the server
+ User::WaitForRequest( status );
+
+ // Close the process handle
+ process.Close();
+
+ // Return the error code
+ return status.Int();
+ }
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::ConstructBuffersL
+// Allocates buffers from heap. Called when connecting to the server
+// -----------------------------------------------------------------------------
+//
+void RATStorageServer::ConstructBuffersL()
+ {
+ LOGSTR1( "STSE void RATStorageServer::ConstructBuffersL()" );
+
+ // Calculate the length of the buffer to be constructed for call stack.
+ // One word will be reserved for the length of the array
+ TInt bufferLength = ( (1 + KATMaxCallstackLength) * KWordSize );
+
+ // Construct iStackBuf and expand it before the beginning (index 0)
+ iStackBuf = CBufFlat::NewL( bufferLength );
+ iStackBuf->ExpandL( 0, bufferLength );
+ }
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::GetLoggingFileL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt RATStorageServer::GetLoggingFileL( TUint aProcessId,
+ TDes8& aFileName )
+ {
+ LOGSTR1( "STSE TInt RATStorageServer::GetLoggingFileL()" );
+
+ // Panic (in debug builds) if aProcessId is illegal
+ __ASSERT_DEBUG( aProcessId != KNullProcessId,
+ StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+
+ TInt error(0);
+
+ TBuf8<KMaxFileName> fileBuf;
+ // Call the server
+ TIpcArgs ipcArgs( aProcessId, &fileBuf );
+ error = SendReceive( CATStorageServer::EGetLoggingFile, ipcArgs );
+
+ // Return, if an error occured.
+ if ( error )
+ {
+ return error;
+ }
+
+ aFileName.Copy( fileBuf );
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::GetUdebL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt RATStorageServer::GetUdebL( TUint aProcessId, TUint32& aIsUdeb )
+ {
+ LOGSTR1( "STSE TInt RATStorageServer::GetUdebL()" );
+
+ // Panic (in debug builds) if aProcessId is illegal
+ __ASSERT_DEBUG( aProcessId != KNullProcessId,
+ StorageServerPanic( KCategoryClient, EAToolBadArgument ) );
+
+ TInt error(0);
+ TBuf8<KMaxVersionName> isUdeb;
+ _LIT8( KUdeb, "UDEB" );
+ // Call the server
+ TIpcArgs ipcArgs( aProcessId, &isUdeb );
+ error = SendReceive( CATStorageServer::EGetUdeb, ipcArgs );
+
+ // Return, if an error occured.
+ if ( error != KErrNone )
+ {
+ return error;
+ }
+
+ if ( isUdeb.Compare( KUdeb() ) == 0 )
+ {
+ LOGSTR1( "STSE TInt RATStorageServer::GetUdebL() - Is UDEB" );
+ aIsUdeb = 1;
+ }
+ else
+ {
+ LOGSTR1( "STSE TInt RATStorageServer::GetUdebL() - Is UREL" );
+ aIsUdeb = 0;
+ }
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// RATStorageServer::IsMemoryAdded
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt RATStorageServer::IsMemoryAdded( TUint32 aMemAddress )
+ {
+ LOGSTR1( "STSE TInt RATStorageServer::IsMemoryAdded()" );
+
+ TIpcArgs ipcArgs( aMemAddress );
+ return SendReceive( CATStorageServer::EIsMemoryAdded, ipcArgs );
+ }
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/group/bld.inf Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,31 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include <platform_paths.hrh>
+
+PRJ_PLATFORMS
+ARMV5 WINSCW
+
+PRJ_EXPORTS
+../client/inc/atstorageserverclnt.h OS_LAYER_PLATFORM_EXPORT_PATH(analyzetool/atstorageserverclnt.h)
+
+PRJ_MMPFILES
+../server/group/atoolstorageserver.mmp
+../client/group/atoolstorageserverclnt.mmp
+
+PRJ_TESTMMPFILES
+../internal/tsrc/group/storageservertest.mmp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/inc/atstorageservercommon.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,77 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Includes common constants and enums for the AnalyzeTool
+* StorageServer client and server.
+*
+*/
+
+
+
+#ifndef ATSTORAGESERVERCOMMON_H
+#define ATSTORAGESERVERCOMMON_H
+
+
+// INCLUDES
+
+#include <e32base.h>
+
+
+// CONSTANTS
+
+// Server's file name
+_LIT(KStorageServerFile, "AToolStorageServer.exe");
+
+// server name
+_LIT(KStorageServerName,"AToolStorageServer");
+
+
+// The path of the storage file
+#ifdef __WINS__
+_LIT( KATDataFilePath, ":\\logs\\analyzetool\\" );
+#else
+_LIT( KATDataFilePath, ":\\analyzetool\\" );
+_LIT( KATDataFilePath2, ":\\data\\analyzetool\\" );
+#endif
+
+// The word size in the current system is 32 bits, which is 4 bytes.
+const TInt KWordSize = 4;
+
+// Leak array granularity value
+const TInt KLeakArrayGranularity = 100;
+
+// DATA TYPES
+
+/** Storage Server panic codes */
+enum TStorageServerPanics
+ {
+ EAToolBadRequest = 1, // An undefined operation request from the client
+ EAToolBadArgument, // Illegal arguments / function parameters
+ EAToolNotAllowed, // An operation is not allowed in the current program state
+ EAToolInternalError, // An internal error has occured
+ EAToolIllegalLogOption // An undefined log option has been requested
+ };
+
+
+/** Panic categories */
+_LIT(KCategoryServer,"STSEServer");
+_LIT(KCategoryClient,"STSEClient");
+
+inline void StorageServerPanic( const TDesC &aCategory, TStorageServerPanics aReason )
+ {
+ User::Panic(aCategory, aReason);
+ }
+
+#endif // ATSTORAGESERVERCOMMON_H
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/server/group/atoolstorageserver.mmp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,50 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: The .mmp file for the server side of AToolStorageServer
+*
+*/
+
+#include <platform_paths.hrh>
+
+TARGET atoolstorageserver.exe
+TARGETTYPE exe
+UID 0x0 0x20012430
+CAPABILITY NONE
+
+SMPSAFE
+
+EPOCHEAPSIZE 0x10000 0x800000
+
+SOURCEPATH ../src
+
+SOURCE atstorageserver.cpp
+SOURCE atstorageserversession.cpp
+SOURCE atmemoryentry.cpp
+SOURCE atdynprocessinfo.cpp
+SOURCE atdriveinfo.cpp
+SOURCE atdllinfo.cpp
+
+USERINCLUDE ../inc
+USERINCLUDE ../../inc
+USERINCLUDE ../../../inc
+
+OS_LAYER_SYSTEMINCLUDE
+
+LIBRARY euser.lib
+LIBRARY efsrv.lib
+LIBRARY flogger.lib
+LIBRARY charconv.lib
+LIBRARY platformenv.lib
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/server/inc/atdllinfo.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,96 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Declaration of the class TATDllInfo.
+*
+*/
+
+
+#ifndef ATDLLINFO_H
+#define ATDLLINFO_H
+
+// INCLUDES
+#include <u32std.h>
+
+/**
+* Stores information of process loaded library
+*/
+class TATDllInfo
+ {
+
+ public: // Constructors
+
+ /**
+ * C++ default constructor.
+ * @param aStartAddress Start address of the library
+ * @param aEndAddress The end address of the library
+ * @param aLoadTime The current time in a 64-bit form.
+ * @param aDllName The name of the library
+ */
+ TATDllInfo( const TUint32 aStartAddress, const TUint32 aEndAddress,
+ const TInt64& aLoadTime, const TDesC8& aDllName );
+
+ public: // New functions
+
+ /**
+ * Returs library start address
+ * @return TUint32 start address of the library
+ */
+ TUint32 StartAddress();
+
+ /**
+ * Returns library end address
+ * @return TUint32 end address of the library
+ */
+ TUint32 EndAddress();
+
+ /**
+ * Gets specific library name
+ * return TDes8 Name of the library
+ */
+ TDes8& Name();
+
+ /**
+ * Returns library load time
+ * @return TInt64 library load time
+ */
+ TInt64 LibraryLoadTime();
+
+ /**
+ * Checks if two objects of this class match based on the objects's
+ * saved library name.
+ * @param aFirst Library object
+ * @param aSecond Library object
+ * return TBool ETrue, if the two objects match. EFalse otherwise.
+ */
+ static TBool Match( const TATDllInfo& aFirst, const TATDllInfo& aSecond );
+
+ public: // Member variables
+
+ /* Start address of the loaded dll */
+ const TUint32 iStartAddress;
+
+ /* End address of the loaded dll */
+ const TUint32 iEndAddress;
+
+ /* Loaded dll name */
+ TBuf8<KMaxLibraryName> iName;
+
+ /** For storing the time when DLL has loaded. */
+ const TInt64 iLoadTime;
+ };
+
+#endif // ATDLLINFO_H
+
+// End of File
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/server/inc/atdriveinfo.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,67 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Declaration of the class TATDriveInfo.
+*
+*/
+
+
+
+#ifndef ATDRIVEINFO_H
+#define ATDRIVEINFO_H
+
+#include <f32file.h>
+
+/**
+* Check what drives exists and creates file full path.
+*/
+class TATDriveInfo
+ {
+ public: // Constructors
+
+ /**
+ * C++ default constructor.
+ */
+ TATDriveInfo();
+
+ public: // New functions
+
+ /**
+ * Create the file full path.
+ * @param aPath Full path.
+ * @param aFileName Filename.
+ * @param aFs A handle to a file server.
+ * @return KErrNone or KErrAlreadyExists, if successful;
+ * Otherwise one of the other system wide error codes.
+ */
+ static TInt CreatePath( TDes& aPath, const TDesC& aFileName, RFs& aFs );
+
+ private: // New functions
+
+ /**
+ * Get the available drive character.
+ * @param aDrive The drive letter.
+ * @param aDriveNumber The drive number.
+ * @param aFs A handle to a file server.
+ * @param aDriveType Drive type.
+ * @return KErrNone, if successful; otherwise KErrNotFound
+ */
+ static TInt GetDrive( TChar& aDrive, TInt& aDriveNumber,
+ RFs& aFs, const TUint aDriveType );
+
+ };
+
+#endif // ATDRIVEINFO_H
+
+// End of File
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/server/inc/atdynprocessinfo.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,102 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Declaration of the class CATDynProcessInfo
+*
+*/
+
+
+#ifndef ATDYNPROCESSINFO_H
+#define ATDYNPROCESSINFO_H
+
+
+// INCLUDES
+#include <e32base.h>
+#include <analyzetool/atcommon.h>
+#include "atdllinfo.h"
+
+// FORWARD DECLARATIONS
+class CATStorageServerSession;
+
+// CLASS DECLARATION
+
+/**
+* A class that can store different process related information. The information
+* is associated to a particular process wiht a member telling a process ID.
+* All the other information but the process ID and the pointer to this process's
+* associated session object can be subject to change dynamically, run-time.
+*/
+class CATDynProcessInfo : public CBase
+ {
+ public: // Constructor
+
+ /**
+ * Constructor.
+ */
+ CATDynProcessInfo();
+
+ /**
+ * Constructor.
+ * @param aProcessId A process ID.
+ * @param aSessionObject A pointer to this process's associated session object.
+ * @param aDlls The loaded DLLs of the associated process.
+ */
+ CATDynProcessInfo( TUint aProcessId,
+ CATStorageServerSession* aSessionObject,
+ const RArray<TATDllInfo>& aDlls );
+
+ /**
+ * Constructor.
+ * @param aProcessId A process ID.
+ * @param aSessionObject A pointer to this process's associated session object.
+ */
+ CATDynProcessInfo( TUint aProcessId,
+ CATStorageServerSession* aSessionObject );
+
+ /**
+ * Constructor.
+ * @param aProcessId A process ID.
+ */
+ CATDynProcessInfo( TUint aProcessId );
+
+ /**
+ * Destructor
+ */
+ virtual ~CATDynProcessInfo();
+
+ public:
+
+ /**
+ * Compares two objects of this class based on the process ID.
+ * @param aFirst The first object of this class to be compared.
+ * @param aSecond The second object of this class to be compared.
+ * @return Zero, if the two objects are equal. A negative value,
+ * if the first object is less than the second. A positive value,
+ * if the first object is greater than the second.
+ */
+ static TInt Compare( const CATDynProcessInfo& aFirst,
+ const CATDynProcessInfo& aSecond );
+
+ public:
+
+ /** The ID of the process. */
+ const TUint iProcessId;
+
+ /** A pointer to the session object associated with this process. */
+ CATStorageServerSession* const iSessionObject;
+
+ /** The DLLs loaded by the associated process */
+ RArray<TATDllInfo> iDlls;
+ };
+
+#endif // ATDYNPROCESSINFO_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/server/inc/atmemoryentry.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,98 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Declaration of the class CATMemoryEntry
+*
+*/
+
+
+#ifndef ATMEMORYENTRY_H
+#define ATMEMORYENTRY_H
+
+
+// INCLUDES
+#include <e32base.h>
+
+
+// CLASS DECLARATION
+
+/**
+* A class for storing memory entries when the server is informed that memory has been
+* allocated. The class stores the memory address of a new allocation and a pointer to
+* a buffer including the current call stack. It also stores a time stamp, and the size
+* of the allocation.
+* The class has member methods for evaluating two different objects of this class
+* with each other. In the construction the class takes a pointer to the call stack
+* buffer, but it does not create the buffer itself. However, it is responsible for
+* deleting the buffer in the destruction.
+*/
+class CATMemoryEntry : public CBase
+ {
+ public: // Constructor
+
+ /**
+ * Constructor.
+ * @param aMemAddress An address to allocated memory.
+ * @param aCallstackBuf A pointer to a buffer containing call stack's memory
+ * addresses.
+ * @param aAllocTime The current time in a 64-bit form.
+ * @param aAllocSize The size of an allocated memory chunk.
+ */
+ CATMemoryEntry( TUint32 aMemAddress, const CBufFlat* aCallstackBuf,
+ const TInt64& aAllocTime, TInt aAllocSize );
+
+ /**
+ * Destructor
+ */
+ virtual ~CATMemoryEntry();
+
+ public:
+ /**
+ * Compares two objects of this class based on the allocation time.
+ * @param aFirst The first object of this class to be compared.
+ * @param aSecond The second object of this class to be compared.
+ * @return Zero, if the two objects are equal. A negative value,
+ * if the first object is less than the second. A positive value,
+ * if the first object is greater than the second.
+ */
+ static TInt Compare( const CATMemoryEntry& aFirst,
+ const CATMemoryEntry& aSecond );
+
+ /**
+ * Checks if two objects of this class match based on the objects's
+ * saved memory allocation addresses.
+ * @param aFirst The first object of this class to be evaluated.
+ * @param aSecond The second object of this class to be evaluated.
+ * @return ETrue, if the two objects match. EFalse otherwise.
+ */
+ static TBool Match( const CATMemoryEntry& aFirst,
+ const CATMemoryEntry& aSecond );
+
+ public:
+
+ /** For storing an address of a memory allocation. */
+ const TUint32 iMemAddress;
+
+ /** A pointer to an array for storing the current call stack. */
+ const CBufFlat* const iCallstackBuf;
+
+ /** For storing the time when an allocation has occured. */
+ const TInt64 iAllocTime;
+
+ /** For storing the size of an allocation. */
+ const TInt iAllocSize;
+
+ };
+
+
+#endif // ATMEMORYENTRY_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/server/inc/atstorageserver.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,218 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Declaration of the server side main class CATStorageServer
+*
+*/
+
+
+#ifndef ATSTORAGESERVER_H
+#define ATSTORAGESERVER_H
+
+
+// INCLUDES
+#include <e32base.h>
+#include <analyzetool/atcommon.h>
+#include "atdllinfo.h"
+
+// CONSTANTS
+// Constants for the server's version
+const TUint KVersionNumberMaj = 0;
+const TUint KVersionNumberMin = 1;
+const TUint KVersionNumberBld = 1;
+
+// DATA TYPES
+
+// FORWARD DECLARATIONS
+class TATProcessInfo;
+class CATDynProcessInfo;
+class CATStorageServerSession;
+
+// CLASS DECLARATION
+
+/**
+* The main class of the Storage Server.
+* When a client connects to the server, a new session object
+* is created by an object of this class. If the server does not exist when
+* connecting, a new process and an object of this class are created first.
+*/
+class CATStorageServer : public CPolicyServer
+ {
+
+ public: // Enumerations
+
+ // opcodes used in message passing between client and server
+ enum TStorageServerReq
+ {
+ EProcessStarted,
+ EDllLoaded,
+ EDllUnloaded,
+ EMemoryAllocated,
+ EMemoryFreed,
+ EProcessEnded,
+ EMemoryCheck,
+ EGetProcesses,
+ EGetDlls,
+ ESetLoggingMode,
+ EGetLoggingMode,
+ ESubtestStart,
+ ESubtestStop,
+ ESubtestStart2,
+ ESubtestStop2,
+ EGetCurrentAllocs,
+ EGetMaxAllocs,
+ ECancelLogging,
+ EGetUdeb,
+ EGetLoggingFile,
+ EProcessUdeb,
+ EIsMemoryAdded,
+ EOutOfBounds
+ };
+
+
+ public: // Constructors and destructor
+
+ /**
+ * Two-phased constructor that can leave.
+ * @return A new instance of this class
+ */
+ static CATStorageServer* NewL();
+
+ /**
+ * Two-phased constructor that can leave and leaves a pointer
+ * on the cleanup stack.
+ * @return A new instance of this class
+ */
+ static CATStorageServer* NewLC();
+
+ /**
+ * Destructor
+ */
+ virtual ~CATStorageServer();
+
+ public: // New functions
+
+
+ /**
+ * Creates a new server object and starts the server.
+ */
+ static void RunServerL();
+
+ /**
+ * Increments the count of active sessions for this server.
+ */
+ void IncSessionCount();
+
+ /**
+ * Decrements the count of active sessions for this server.
+ */
+ void DecSessionCount();
+
+ /**
+ * Adds a new process into the server's arrays.
+ * @param aProcessName The name of the process to be added.
+ * @param aProcessId The ID of the process to be added.
+ * @param aSessionObject A pointer to the current process's associated session
+ * object.
+ * @param aStartTime The starting time of the process to be added. It represents
+ * time as a number of microseconds since midnight, January 1st, 0 AD nominal
+ * Gregorian. This is the representation used by, e.g., the TTime class.
+ * @return KErrNone, if the operation is successful; KErrAlreadyExists, if
+ * an attempt is being made to insert a duplicate process; otherwise one of
+ * the other system wide error codes.
+ */
+ TInt AddProcessL( const TDesC8& aProcessName,
+ TUint aProcessId,
+ CATStorageServerSession* aSessionObject,
+ const TInt64& aStartTime );
+
+ /**
+ * Removes a process from the server's arrays.
+ * @param aProcessId The ID of the process to be removed.
+ * @return KErrNone, if successful; KErrNotFound, if a process with
+ * the specified process ID could not be found in the array.
+ */
+ TInt RemoveProcessL( TUint aProcessId );
+
+ /**
+ * Adds a DLL for a given process to the dynamic process info array of this class.
+ * @param aProcessId The ID of the process that has loaded the DLL to be added.
+ * @param aDllInfo Information of the DLL.
+ * @return KErrNone, if successful; KErrNotFound, if a process with the given
+ * process ID could not be found; KErrAlreadyExists, if a DLL with the given
+ * name was already stored; otherwise one of the other system wide error codes.
+ */
+ TInt AddDllL( TUint aProcessId, const TATDllInfo aDllInfo );
+
+ /**
+ * Removes a DLL associated with the given process from the dynamic process
+ * info array of this class.
+ * @param aProcessId The ID of the process that has loaded the DLL to be removed.
+ * @param aDllName The name of the DLL to be removed.
+ * @return KErrNone, if successful; KErrNotFound, if a process with
+ * the specified process ID could not be found, or if a DLL with the specified
+ * name could not be found.
+ */
+ TInt RemoveDllL( TUint aProcessId, const TDesC8& aDllName );
+
+ /**
+ * Gives a reference to the process info array of this class.
+ * @return A reference to iProcesses array
+ */
+ const RArray<TATProcessInfo>& ProcessInfoArray();
+
+ /**
+ * Gives a reference to the dynamic process info array of this class.
+ * @return A reference to iProcessesDyn array
+ */
+ const RPointerArray<CATDynProcessInfo>& DynProcessInfoArray();
+
+ public: // Functions from base classes
+
+ /**
+ * From CPolicyServer.
+ * Creates a new server-side session object.
+ * @param aVersion The version of this server
+ * @param aMessage A message from the client
+ * @return A pointer to a new session object.
+ */
+ CSession2* NewSessionL( const TVersion& aVersion, const RMessage2& aMessage ) const;
+
+ private:
+
+ /**
+ * C++ default constructor.
+ * @param aPriority A priority for this active object
+ */
+ CATStorageServer( TInt aPriority );
+
+ /**
+ * Symbian 2nd phase constructor.
+ */
+ void ConstructL();
+
+ private: // Data
+
+ /** The number of active sessions */
+ TInt iSessionCount;
+
+ /** An array for storing TATProcessInfo objects */
+ RArray<TATProcessInfo> iProcesses;
+
+ /** An array for storing CATDynProcessInfo pointers */
+ RPointerArray<CATDynProcessInfo> iProcessesDyn;
+ };
+
+#endif // ATSTORAGESERVER_H
+
+// End of File
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/server/inc/atstorageserversession.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,588 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Declaration of the server side session class CATStorageServerSession
+*
+*/
+
+
+#ifndef ATSTORAGESERVERSESSION_H
+#define ATSTORAGESERVERSESSION_H
+
+
+// INCLUDES
+#include <e32base.h>
+#include <f32file.h>
+#include <analyzetool/atcommon.h>
+
+// FORWARD DECLARATIONS
+class CATStorageServer;
+class CATMemoryEntry;
+
+// CLASS DECLARATIONS
+
+/**
+* A class for storing memory addresses and sizes of allocations.
+* Needed for giving allocation information for the configuration UI.
+*/
+class TAllocInfo
+ {
+ public:
+
+ // Constructor
+ TAllocInfo( TUint32 aMemAddress, TInt aAllocSize );
+
+ /** Address of a memory allocation. */
+ const TUint32 iMemAddress;
+
+ /** Size of the associated allocation. */
+ const TInt iAllocSize;
+ };
+
+
+/**
+* The session class for Storage Server.
+* When the Storage Server client connects to the server, a new object of this
+* class is constructed. So, for every client there is an associated object
+* of this class. CATStorageServer forwards all client messages to their associated
+* session objects.
+*/
+class CATStorageServerSession : public CSession2
+ {
+ public: // Enumerations
+
+ public: // Constructors and destructor
+
+ /**
+ * Two-phased constructor that can leave.
+ * @return A new instance of this class
+ */
+ static CATStorageServerSession* NewL( CATStorageServer& aStorageServer );
+
+ /**
+ * Two-phased constructor that can leave and leaves a pointer
+ * on the cleanup stack.
+ * @return A new instance of this class
+ */
+ static CATStorageServerSession* NewLC( CATStorageServer& aStorageServer );
+
+ /**
+ * Destructor
+ */
+ virtual ~CATStorageServerSession();
+
+ public: // Functions from base classes
+
+ /**
+ * Receives messages sent by a client.
+ * @param aMessage A message from a client
+ */
+ virtual void ServiceL( const RMessage2& aMessage );
+
+ protected: // new functions
+
+ /**
+ * Initializes this session for logging. This includes opening a logging file
+ * with a requested name. The method is to be called as the first method after
+ * connecting to the server. The method logs information on process starting into
+ * the just opened logging file.
+ * If a logging session is already ongoing, the method makes the client raise an
+ * STSEClient: 3 panic, and returns KErrCancel.
+ * @param aMessage A message that includes parameters sent by the client.
+ * @return KErrNone, if successful; KErrCancel, if a logging session is already
+ * ongoing. Otherwise one of the other system wide error codes.
+ */
+ TInt LogProcessStartedL( const RMessage2& aMessage );
+
+ /**
+ * Initializes this session for logging. The method is to be called as the first
+ * method after connecting to the server. The method logs information on process
+ * starting into debug channel.
+ * If a logging session is already ongoing, the method makes the client raise an
+ * STSEClient: 3 panic, and returns KErrCancel.
+ * @param aMessage A message that includes parameters sent by the client.
+ * @return KErrNone, if successful; KErrCancel, if a logging session is already
+ * ongoing. Otherwise one of the other system wide error codes.
+ */
+ TInt LogProcessStartTraceL( const RMessage2& aMessage );
+
+ /**
+ * Logs information on a DLL load into the opened file.
+ * If a logging session is not ongoing, the method makes the client raise an
+ * STSEClient: 3 panic, and returns KErrCancel.
+ * @param aMessage A message that includes parameters sent by the client.
+ * @return KErrNone, if successful; KErrCancel, if a logging session is not
+ * currently ongoing; Otherwise one of the other system wide error codes.
+ */
+ TInt LogDllLoadedL( const RMessage2& aMessage );
+
+ /**
+ * Logs information on a DLL load into debug channel.
+ * If a logging session is not ongoing, the method makes the client raise an
+ * STSEClient: 3 panic, and returns KErrCancel.
+ * @param aMessage A message that includes parameters sent by the client.
+ * @return KErrNone, if successful; KErrCancel, if a logging session is not
+ * currently ongoing; Otherwise one of the other system wide error codes.
+ */
+ TInt LogDllLoadTraceL( const RMessage2& aMessage );
+
+ /**
+ * Logs information on a DLL unload into the opened file.
+ * If a logging session is not ongoing, the method makes the client raise an
+ * STSEClient: 3 panic, and returns KErrCancel.
+ * @param aMessage A message that includes parameters sent by the client.
+ * @return KErrNone, if successful; KErrCancel, if a logging session is not
+ * currently ongoing; Otherwise one of the other system wide error codes.
+ */
+ TInt LogDllUnloadedL( const RMessage2& aMessage );
+
+ /**
+ * Logs information on a DLL unload into debug channel.
+ * If a logging session is not ongoing, the method makes the client raise an
+ * STSEClient: 3 panic, and returns KErrCancel.
+ * @param aMessage A message that includes parameters sent by the client.
+ * @return KErrNone, if successful; KErrCancel, if a logging session is not
+ * currently ongoing; Otherwise one of the other system wide error codes.
+ */
+ TInt LogDllUnloadTraceL( const RMessage2& aMessage );
+
+ /**
+ * Stores a memory allocation (memory address, current call stack, allocation
+ * time and allocation size) in an internal array.
+ * If a logging session is not ongoing, the method makes the client raise an
+ * STSEClient: 3 panic, and returns KErrCancel.
+ * @param aMessage A message that includes parameters sent by the client.
+ * @return KErrNone, if successful; KErrCancel, if a logging session is not
+ * currently ongoing; KErrAlreadyExists, if an attempt is being made to allocate
+ * again an already allocated memory area; Otherwise one of the other system
+ * wide error codes.
+ */
+ TInt LogMemoryAllocatedL( const RMessage2& aMessage );
+
+ /**
+ * Logs information on a memory allocation into debug channel.
+ * If a logging session is not ongoing, the method makes the client raise an
+ * STSEClient: 3 panic, and returns KErrCancel.
+ * @param aMessage A message that includes parameters sent by the client.
+ * @return KErrNone, if successful; KErrCancel, if a logging session is not
+ * currently ongoing; KErrAlreadyExists, if an attempt is being made to allocate
+ * again an already allocated memory area; Otherwise one of the other system
+ * wide error codes.
+ */
+ TInt LogMemoryAllocTraceL( const RMessage2& aMessage );
+
+ /**
+ * Check a memory allocation (memory address) from an internal array.
+ * If a logging session is not ongoing, the method makes the client raise an
+ * STSEClient: 3 panic, and returns KErrCancel.
+ * @param aMessage A message that includes parameters sent by the client.
+ * @param aRemoveAlloc Boolean to enable removing the found address from allocations.
+ * @return KErrNone, if memory address found in array;
+ * KErrNotFound, if the requested memory address was not found.
+ */
+ TInt IsMemoryAdded( const RMessage2& aMessage, const TBool aRemoveAlloc = EFalse );
+
+ /**
+ * Removes a memory allocation (memory address, current call stack, allocation
+ * time and allocation size) from an internal array.
+ * If a logging session is not ongoing, the method makes the client raise an
+ * STSEClient: 3 panic, and returns KErrCancel.
+ * @param aMessage A message that includes parameters sent by the client.
+ * @return KErrNone, if successful; KErrCancel, if a logging session is not
+ * currently ongoing; KErrNotFound, if the requested memory address was not
+ * found; Otherwise one of the other system wide error codes.
+ */
+ TInt LogMemoryFreedL( const RMessage2& aMessage );
+
+ /**
+ * Logs information on freeing of a memory allocatin into debug channel.
+ * If a logging session is not ongoing, the method makes the client raise an
+ * STSEClient: 3 panic, and returns KErrCancel.
+ * @param aMessage A message that includes parameters sent by the client.
+ * @return KErrNone, if successful; KErrCancel, if a logging session is not
+ * currently ongoing; KErrNotFound, if the requested memory address was not
+ * found; Otherwise one of the other system wide error codes.
+ */
+ TInt LogMemoryFreedTraceL( const RMessage2& aMessage );
+
+ /**
+ * Logs all non-released memory allocations into the opened file as memory leaks.
+ * Then the method logs a number of possibly occured handle leaks into the file.
+ * Next, the method logs information on process ending into the logging file.
+ * Finally, this method closes the logging file opened for the connected process,
+ * and ends the current logging session. However, this method does not end the
+ * actual client-server session.
+ * If a logging session is not ongoing, the method makes the client raise an
+ * STSEClient: 3 panic, and returns KErrCancel.
+ * @param aMessage A message that includes parameters sent by the client.
+ * @return KErrNone, if successful; KErrCancel, if a logging session is not
+ * currently ongoing; KErrNotSupported if this method is called with a wrong
+ * process id from the client. Otherwise one of the other system wide error
+ * codes.
+ */
+ TInt LogProcessEndedL( const RMessage2& aMessage );
+
+ /**
+ * Logs a number of possibly occured handle leaks into debug channel. Then, the method
+ * logs information on process ending into debug channel. The method also
+ * ends the current logging session. However, this method does not end the actual
+ * client-server session.
+ * If a logging session is not ongoing, the method makes the client raise an
+ * STSEClient: 3 panic, and returns KErrCancel.
+ * @param aMessage A message that includes parameters sent by the client.
+ * @return KErrNone, if successful; KErrCancel, if a logging session is not
+ * currently ongoing; KErrNotSupported if this method is called with a wrong
+ * process id from the client. Otherwise one of the other system wide error
+ * codes.
+ */
+ TInt LogProcessEndTraceL( const RMessage2& aMessage );
+
+ /**
+ * Checks if a given memory address can be found.
+ * If a logging session is not ongoing, the method makes the client raise an
+ * STSEClient: 3 panic, and returns KErrCancel.
+ * @param aMessage A message that includes parameters sent by the client.
+ * @return When the system is logging into a file: the index of a found
+ * memory address, or KErrNotFound, if a matching memory address cannot
+ * be found. KErrNone, when the system is not logging into a file.
+ * KErrCancel, if a logging session is not currently ongoing.
+ */
+ TInt CheckMemoryAddressL( const RMessage2& aMessage );
+
+ /**
+ * Checks if a given memory address can be found.
+ * If a logging session is not ongoing, the method makes the client raise an
+ * STSEClient: 3 panic, and returns KErrCancel.
+ * @param aMessage A message that includes parameters sent by the client.
+ * @return When the system is logging into a file: the index of a found
+ * memory address, or KErrNotFound, if a matching memory address cannot
+ * be found. KErrNone, when the system is not logging into a file.
+ * KErrCancel, if a logging session is not currently ongoing.
+ */
+ TInt CheckMemoryAddressTrace( const RMessage2& aMessage );
+
+ /**
+ * Gets all the processes currently logging with AnalyzeTool
+ * @param aMessage A message that includes parameters sent by the client.
+ * On return a buffer including all the currently logging processes is written
+ * into this message.
+ * @return KErrNone, if successful; otherwise one of the other system wide error
+ * codes.
+ */
+ TInt GetProcessesL( const RMessage2& aMessage );
+
+ /**
+ * Gets all the DLLs loaded by the process determined by the parameters.
+ * @param aMessage A message that includes parameters sent by the client.
+ * A buffer including all the DLLs loaded by the requested process is
+ * written into this message.
+ * @return KErrNone, if successful; KErrNotFound, if the requested process was
+ * not found; otherwise one of the other system wide error codes.
+ */
+ TInt GetDllsL( const RMessage2& aMessage );
+
+ /**
+ * Gets the logging mode of the process determined by the parameters.
+ * @param aMessage A message that includes parameters sent by the client.
+ * On return, the logging mode is written into this message.
+ * @return KErrNone, if successful; KErrNotFound, if the requested process was
+ * not found; otherwise one of the other system wide error codes.
+ */
+ TInt GetLoggingModeL( const RMessage2& aMessage );
+
+ /**
+ * Starts a sub test for the given process.
+ * @param aMessage A message that includes parameters sent by the client.
+ * @return KErrNone, if successful; KErrNotFound, if the requested process is not
+ * found; KErrNotSupported, if the requested process does not have a logging
+ * session ongoing or its logging mode is not EATLogToTrace; Otherwise one of the
+ * other system wide error codes.
+ */
+ TInt StartSubtestL( const RMessage2& aMessage );
+
+ /**
+ * Stops a sub test for the given process.
+ * @param aMessage A message that includes parameters sent by the client.
+ * @return KErrNone, if successful; KErrNotFound, if the requested process is not
+ * found; KErrNotSupported, if the requested process does not have a logging
+ * session ongoing or its logging mode is not EATLogToTrace; Otherwise one of the
+ * other system wide error codes.
+ */
+ TInt StopSubtestL( const RMessage2& aMessage );
+
+ /**
+ * Starts a sub test for the calling process. Does not need a PID from the client.
+ * @param aMessage A message that includes parameters sent by the client.
+ * @return KErrNone, if successful; KErrNotSupported, if the calling process
+ * does not have a logging session ongoing or its logging mode is not
+ * EATLogToTrace; Otherwise one of the other system wide error codes.
+ */
+ TInt StartSubtest2L( const RMessage2& aMessage );
+
+ /**
+ * Stops a sub test for the calling process. Does not need a PID from the client.
+ * @param aMessage A message that includes parameters sent by the client.
+ * @return KErrNone, if successful; KErrNotSupported, if the calling process
+ * does not have a logging session ongoing or its logging mode is not
+ * EATLogToTrace; Otherwise one of the other system wide error codes.
+ */
+ TInt StopSubtest2( const RMessage2& aMessage );
+
+ /**
+ * Gets the number and total size of the current memory chunks allocated by the
+ * requested process.
+ * @param aMessage A message that includes parameters sent by the client. The
+ * requested information is written into this message.
+ * @return KErrNone, if successful; KErrNotFound, if the requested process was
+ * not found; otherwise one of the other system wide error codes.
+ */
+ TInt GetCurrentAllocsL( const RMessage2& aMessage );
+
+ /**
+ * Gets the maximum number of memory chunks and the maximum amount of memory
+ * allocated by the requested process during the test run.
+ * @param aMessage A message that includes parameters sent by the client. The
+ * requested information is written into this message.
+ * @return KErrNone, if successful; KErrNotFound, if the requested process was
+ * not found; otherwise one of the other system wide error codes.
+ */
+ TInt GetMaxAllocsL( const RMessage2& aMessage );
+
+ /**
+ * Cancels logging for the requested process. After logging of a given process
+ * has been cancelled, the session associated with that process will not be
+ * usable anymore. If a process wants to start logging again, it needs to close
+ * the handle and open it again in order to create a new session. Until then, any
+ * of the server's methods that can be called by the client will return
+ * KErrCancel.
+ * @param aMessage A message that includes parameters sent by the client.
+ * @return KErrNone, if successful; KErrNotFound, if the requested process was
+ * not found; otherwise one of the other system wide error codes.
+ */
+ TInt CancelLoggingL( const RMessage2& aMessage );
+
+ /**
+ * Gets the logging file of the process determined by the parameters.
+ * @param aMessage A message that includes parameters sent by the client.
+ * On return, the logging file is written into this message.
+ * @return KErrNone, if successful; KErrNotFound, if the requested process was
+ * not found; otherwise one of the other system wide error codes.
+ */
+ TInt GetLoggingFileL( const RMessage2& aMessage );
+
+ /**
+ * Gets the mode of the process determined by the parameters.
+ * @param aMessage A message that includes parameters sent by the client.
+ * On return, the logging file is written into this message.
+ * @return KErrNone, if successful; KErrNotFound, if the requested process was
+ * not found; otherwise one of the other system wide error codes.
+ */
+ TInt GetUdebL( const RMessage2& aMessage );
+
+ /**
+ * Sets the mode of the process determined by the parameters.
+ * @param aMessage A message that includes parameters sent by the client.
+ */
+ void SetUdeb( const RMessage2& aMessage );
+
+ private: // New functions for internal use
+
+ /**
+ * Releases the resources reserved by this object, and before closing the logging
+ * file and file server session, the method logs information on the occured error
+ * into the logging file.
+ * @param aError The error code to be logged.
+ */
+ void HandleError( TInt aError );
+
+ /**
+ * Releases the resources reserved by this object, and logs information on the
+ * occured error into debug channel.
+ * @param aError The error code to be logged.
+ */
+ void HandleErrorTrace( TInt aError );
+
+ /**
+ * Opens a file server session and a file with the name specified.
+ * @param aFileName The name of the file into which to log.
+ * @param aProcessName Current process name.
+ * @return KErrNone, if successful; otherwise one of the other system wide
+ * error codes.
+ */
+ TInt OpenFsAndFile( const TDesC& aFileName, const TDesC8& aProcessName );
+
+ /**
+ * Method is used to parse file name extension.
+ * @param aFileName The name of the file into which to log.
+ * @param aExtension Parsed file extension.
+ */
+ void ParseExtension( TDes& aFileName, TDes& aExtension );
+
+ /**
+ * Called internally when need generate new file name.
+ * @param aFileName The name of the file into which to log.
+ * @param aProcessName Current process name.
+ */
+ void GenerateNewFileName( TDes& aFileName, const TDesC8& aProcessName );
+
+ /**
+ * Method is used to check that file exists and is valid.
+ * @param aFileName The name of the file into which to log.
+ */
+ void CheckIfFileAlreadyExist( const TDes& aFileName );
+
+ /**
+ * Method is used to check file version.
+ * @param aFileName The name of the file into which to log.
+ */
+ void CheckFileVersion( const TDes& aFileName );
+
+ /**
+ * Closes the handles to the file server session and to the file (if currently open).
+ */
+ void CloseFsAndFile();
+
+ /**
+ * Writes the memory leaks stored in the iLeakArray member array into the
+ * logging file opened for the current logging session. If the method is
+ * called in a wrong program state (logging session is not ongoing, or the
+ * logging mode is not EATLogToFile), STSEClient: 4, and STSEServer: 4
+ * panics are raised.
+ * @param aMessage The current message from the client.
+ * @return KErrNone, if successful; otherwise one of the other system wide
+ * error codes.
+ */
+ TInt PrintLeaksL( const RMessage2& aMessage );
+
+ /**
+ * Sets the server's mode of operation. The operation mode is determined with
+ * an enumeration value, which is received from the client. If the method is
+ * called in a wrong program state (logging session is ongoing), STSEClient: 4,
+ * and STSEServer: 4 panics are raised.
+ * @param aMessage The current message from the client.
+ */
+ void SetLogOption( const RMessage2& aMessage );
+
+ /**
+ * Logs the given descriptor through debug channel.
+ * @param aLogString The descriptor to be logged.
+ * @return KErrNone, if successful; KErrNotSupported, if a logging session is not
+ * ongoing, or the logging mode is not EATLogToTrace;
+ */
+ TInt LogThroughTrace( const TDesC& aLogString ) const;
+
+ /**
+ * Gives a reference to the allocation info array of this class.
+ * @return A reference to iAllocInfoArray array
+ */
+ RArray<TAllocInfo>& AllocInfoArray();
+
+ /**
+ * Creates a panic in the associated client's code.
+ * @param aPanic The panic code
+ * @param aMessage The message associated with this panic.
+ */
+ void PanicClient( TInt aPanic, const RMessage2& aMessage );
+
+ /**
+ * Logs the abnormal end to the debug channel (If logging mode is EATLogToTrace)
+ * and to the file(If logging mode is EATLogToFile).
+ */
+ void LogAbnormalEnd();
+
+ /**
+ * Get the current universal time.
+ * @return Time
+ */
+ TInt64 GetTime();
+
+ private: // Constructors
+
+ /**
+ * C++ default constructor.
+ */
+ CATStorageServerSession( CATStorageServer& aStorageServer );
+
+ /**
+ * Symbian 2nd phase constructor.
+ */
+ void ConstructL();
+
+ private: // Data
+
+ /** A reference to the CATStorageServer object that has created this session */
+ CATStorageServer& iStorageServer;
+
+ /** A handle to a file server */
+ RFs iFileServer;
+
+ /** A handle to a file */
+ RFile iFile;
+
+ /** A member variable for storing results of server function calls. */
+ TInt iError;
+
+ /** An object for getting time stamps */
+ TTime iTime;
+
+ /**
+ * An array for storing CATMemoryEntry pointers. Used when logging
+ * to an S60 file.
+ */
+ RPointerArray<CATMemoryEntry> iLeakArray;
+
+ /**
+ * An array for storing TAllocInfo objects. Used for keeping records on memory
+ * allocations and their sizes.
+ */
+ RArray<TAllocInfo> iAllocInfoArray;
+
+ /** The ID of the process associated with this session. */
+ TUint iProcessId;
+
+ /**
+ * A boolean telling whether this session has been initialized for logging
+ * ( whether the client's LogProcessStarted() method has been called ) or not.
+ */
+ TBool iLoggingOngoing;
+
+ /**
+ * A variable telling the number of microseconds from January 1st, 0 AD
+ * nominal Gregorian to January 1st, 1970 AD nominal Gregorian.
+ */
+ TInt64 iMicroSecondsAt1970;
+
+ /**
+ * An enumeration that tells the current operation mode of the Storage Server.
+ */
+ TATLogOption iLogOption;
+
+ /** The total size of all the current allocations of this process */
+ TUint32 iCurAllocSize;
+
+ /** The maximum number of allocations of this process */
+ TUint32 iMaxAllocs;
+
+ /** The maximum total size of allocations of this process */
+ TUint32 iMaxAllocSize;
+
+ /** The logging file of this process */
+ TBuf8<KMaxFileName> iLogFile;
+
+ /** The mode of the session. Default is 1 = UDEB */
+ TUint32 iIsUdeb;
+ };
+
+#endif // ATSTORAGESERVERSESSION_H
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/server/src/atdllinfo.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,102 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Definitions for the class TATDllInfo.
+*
+*/
+
+// INCLUDE FILES
+#include "atdllinfo.h"
+#include "atlog.h"
+
+// -----------------------------------------------------------------------------
+// TATDllInfo::TATDllInfo
+// C++ default constructor.
+// -----------------------------------------------------------------------------
+//
+TATDllInfo::TATDllInfo( const TUint32 aStartAddress, const TUint32 aEndAddress,
+ const TInt64& aLoadTime, const TDesC8& aDllName )
+ : iStartAddress( aStartAddress ), iEndAddress( aEndAddress ),
+ iLoadTime( aLoadTime )
+ {
+ LOGSTR3( "STSE TATDllInfo::TATDllInfo() %x - %x", iStartAddress, iEndAddress );
+
+ iName.Copy( aDllName );
+ }
+
+// -----------------------------------------------------------------------------
+// TATDllInfo::StartAddress
+// Returns library start address
+// -----------------------------------------------------------------------------
+//
+TUint32 TATDllInfo::StartAddress()
+ {
+ LOGSTR2( "STSE TATDllInfo::StartAddress( %x )", iStartAddress );
+
+ return iStartAddress;
+ }
+
+// -----------------------------------------------------------------------------
+// TATDllInfo::EndAddress
+// Returns library end address
+// -----------------------------------------------------------------------------
+//
+TUint32 TATDllInfo::EndAddress()
+ {
+ LOGSTR2( "STSE TATDllInfo::EndAddress( %x )", iEndAddress );
+
+ return iEndAddress;
+ }
+
+// -----------------------------------------------------------------------------
+// TATDllInfo::Name
+// Gets specific library name
+// -----------------------------------------------------------------------------
+//
+TDes8& TATDllInfo::Name()
+ {
+ LOGSTR1( "STSE TATDllInfo::Name()" );
+
+ return iName;
+ }
+
+// -----------------------------------------------------------------------------
+// TATDllInfo::LibraryLoadTime
+// Returns library load time
+// -----------------------------------------------------------------------------
+//
+TInt64 TATDllInfo::LibraryLoadTime()
+ {
+ LOGSTR1( "STSE TATDllInfo::LibraryLoadTime()" );
+
+ return iLoadTime;
+ }
+
+// -----------------------------------------------------------------------------
+// TATDllInfo::Match
+// Checks if two objects of this class match based on the objects's
+// saved library name.
+// -----------------------------------------------------------------------------
+//
+TBool TATDllInfo::Match( const TATDllInfo& aFirst, const TATDllInfo& aSecond )
+ {
+ LOGSTR1( "STSE TATDllInfo::Match()" );
+
+ if ( aFirst.iName.Compare( aSecond.iName ) == 0 )
+ {
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/server/src/atdriveinfo.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,188 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Definitions for the class TATDriveInfo.
+*
+*/
+
+
+
+// INCLUDE FILES
+#include <f32file.h>
+#include <driveinfo.h>
+#include "atdriveinfo.h"
+#include "atstorageservercommon.h"
+#include "atlog.h"
+
+// -----------------------------------------------------------------------------
+// TATDriveInfo::TATDriveInfo
+// C++ default constructor.
+// -----------------------------------------------------------------------------
+//
+TATDriveInfo::TATDriveInfo()
+ {
+ LOGSTR1( "TATD TATDriveInfo::TATDriveInfo()" );
+ }
+
+// -----------------------------------------------------------------------------
+// TATDriveInfo::CreatePath()
+// -----------------------------------------------------------------------------
+//
+TInt TATDriveInfo::CreatePath( TDes& aPath,
+ const TDesC& aFileName, RFs& aFs )
+ {
+ LOGSTR1( "TATD TInt TATDriveInfo::CreatePath()" );
+
+ // Drive letter
+ TChar driveLetter;
+ // Drive number
+ TInt dNumber( EDriveZ );
+ TBool found( EFalse );
+ // Drive type
+ TUint driveType( KDriveAttRemovable );
+ TInt err( KErrNotFound );
+
+ while ( !found )
+ {
+ // Get drive letter
+ if ( GetDrive( driveLetter, dNumber, aFs, driveType ) == KErrNotFound )
+ {
+ if ( driveType == KDriveAttInternal )
+ {
+ return KErrNotFound;
+ }
+ driveType = KDriveAttInternal;
+ dNumber = EDriveZ;
+ }
+ else
+ {
+ // Create path
+ aPath.Delete( 0, aPath.MaxLength() );
+ aPath.Append( driveLetter );
+
+
+ #ifdef __WINS__
+ // For emulator the data file is stored to different location
+ aPath.Append( KATDataFilePath );
+ #else
+ TDriveInfo driveInfo;
+ aFs.Drive( driveInfo, dNumber );
+ // The drive is removable( memory card ) so we can log inside of root folder
+ if ( driveInfo.iDriveAtt & KDriveAttRemovable )
+ {
+ aPath.Append( KATDataFilePath );
+ }
+ // The drive is internal user can only access data folder so log into that
+ else
+ {
+ aPath.Append( KATDataFilePath2 );
+ }
+ #endif
+
+ // Make a directory for AToolStorageServer's logging data file
+ err = aFs.MkDir( aPath );
+ LOGSTR2( "STSE > aFs.MkDir err = %i", err );
+
+ if ( !err || err == KErrAlreadyExists )
+ {
+ if ( aFileName.Length() != 0 &&
+ ( ( aPath.MaxLength() - aPath.Length() ) > aFileName.Length() ) )
+ {
+ aPath.Append( aFileName );
+ }
+ found = ETrue;
+ }
+ }
+ }
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// TATDriveInfo::GetDrive()
+// -----------------------------------------------------------------------------
+//
+TInt TATDriveInfo::GetDrive( TChar& aDrive, TInt& aDriveNumber, RFs& aFs,
+ const TUint aDriveType )
+ {
+ LOGSTR1( "TATD TInt TATDriveInfo::GetDrive()" );
+
+ // Contains drive information.
+ TDriveInfo driveInfo;
+
+ for ( TInt i = aDriveNumber; i >= (TInt)EDriveA; i-- )
+ {
+ // Gets information about a drive and the medium mounted on it.
+ // If error occured then skip to next drive.
+ if ( aFs.Drive( driveInfo, i ) != KErrNone )
+ continue;
+
+ // Test whether drive is available. If not, skip to next drive.
+ if ( driveInfo.iDriveAtt & KDriveAbsent || i == (TInt)EDriveD ||
+ driveInfo.iDriveAtt & KDriveAttRom ||
+ driveInfo.iMediaAtt & KMediaAttWriteProtected ||
+ driveInfo.iDriveAtt & KDriveFileSysROFS )
+ continue;
+
+ // Maps a drive number to the corresponding character.
+ if ( aFs.DriveToChar( i, aDrive ) != KErrNone )
+ continue;
+
+ if ( driveInfo.iDriveAtt & aDriveType &&
+ driveInfo.iType != EMediaNotPresent &&
+ driveInfo.iType != EMediaCdRom )
+ {
+ TUint status( 0 );
+
+ switch ( aDriveType )
+ {
+ case KDriveAttRemovable:
+ {
+ // Get the drive status of the default removable mass storage.
+ if ( DriveInfo::GetDriveStatus( aFs, i, status ) == KErrNone )
+ {
+ // To indicate that the drive is physically removable.
+ if ( status & DriveInfo::EDriveRemovable &&
+ !( status & DriveInfo::EDriveCorrupt ) )
+ {
+ aDriveNumber = --i;
+ return KErrNone;
+ }
+ }
+ }
+ break;
+ case KDriveAttInternal:
+ {
+ // Get the drive status of the default removable mass storage.
+ if ( DriveInfo::GetDriveStatus( aFs, i, status ) == KErrNone )
+ {
+ // To indicate that the drive is internal and
+ // cannot be physically removed.
+ if ( status & DriveInfo::EDriveInternal &&
+ !( status & DriveInfo::EDriveExternallyMountable ) )
+ {
+ aDriveNumber = --i;
+ return KErrNone;
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ return KErrNotFound;
+ }
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/server/src/atdynprocessinfo.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,94 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Definitions for the class CATDynProcessInfo
+*
+*/
+
+
+// INCLUDE FILES
+#include "atdynprocessinfo.h"
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+
+// -----------------------------------------------------------------------------
+// CATDynProcessInfo::CATDynProcessInfo
+// -----------------------------------------------------------------------------
+//
+CATDynProcessInfo::CATDynProcessInfo() :
+ iProcessId( KNullProcessId ),
+ iSessionObject( NULL )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CATDynProcessInfo::CATDynProcessInfo
+// -----------------------------------------------------------------------------
+//
+CATDynProcessInfo::CATDynProcessInfo( TUint aProcessId,
+ CATStorageServerSession* aSessionObject,
+ const RArray<TATDllInfo>& aDlls ) :
+ iProcessId( aProcessId ),
+ iSessionObject( aSessionObject ),
+ iDlls( aDlls )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CATDynProcessInfo::CATDynProcessInfo
+// -----------------------------------------------------------------------------
+//
+CATDynProcessInfo::CATDynProcessInfo( TUint aProcessId,
+ CATStorageServerSession* aSessionObject ) :
+ iProcessId( aProcessId ), iSessionObject( aSessionObject )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CATDynProcessInfo::CATDynProcessInfo
+// -----------------------------------------------------------------------------
+//
+CATDynProcessInfo::CATDynProcessInfo( TUint aProcessId ) :
+ iProcessId( aProcessId ), iSessionObject( NULL )
+ {
+ }
+
+// Destructor
+CATDynProcessInfo::~CATDynProcessInfo()
+ {
+ iDlls.Close();
+ }
+
+// -----------------------------------------------------------------------------
+// CATDynProcessInfo::Compare
+// -----------------------------------------------------------------------------
+//
+TInt CATDynProcessInfo::Compare( const CATDynProcessInfo& aFirst,
+ const CATDynProcessInfo& aSecond )
+ {
+ if ( aFirst.iProcessId < aSecond.iProcessId )
+ {
+ return -1;
+ }
+
+ if ( aFirst.iProcessId > aSecond.iProcessId )
+ {
+ return 1;
+ }
+
+ // else
+ return 0;
+ }
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/server/src/atmemoryentry.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,84 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Definitions for the class CATMemoryEntry
+*
+*/
+
+
+
+// INCLUDE FILES
+#include "atmemoryentry.h"
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+
+// -----------------------------------------------------------------------------
+// CATMemoryEntry::CATMemoryEntry
+// C++ default constructor.
+// -----------------------------------------------------------------------------
+//
+CATMemoryEntry::CATMemoryEntry( TUint32 aMemAddress,
+ const CBufFlat* aCallstackBuf,
+ const TInt64& aAllocTime,
+ TInt aAllocSize ) :
+ iMemAddress( aMemAddress ),
+ iCallstackBuf( aCallstackBuf ),
+ iAllocTime( aAllocTime ),
+ iAllocSize( aAllocSize )
+ {
+ }
+
+// Destructor
+CATMemoryEntry::~CATMemoryEntry()
+ {
+ delete const_cast<CBufFlat*>( iCallstackBuf );
+ }
+
+// -----------------------------------------------------------------------------
+// CATMemoryEntry::Compare
+// -----------------------------------------------------------------------------
+//
+TInt CATMemoryEntry::Compare( const CATMemoryEntry& aFirst, const CATMemoryEntry& aSecond )
+ {
+ if ( aFirst.iAllocTime < aSecond.iAllocTime )
+ {
+ return -1;
+ }
+
+ if ( aFirst.iAllocTime > aSecond.iAllocTime )
+ {
+ return 1;
+ }
+
+ // else
+ return 0;
+ }
+
+// -----------------------------------------------------------------------------
+// CATMemoryEntry::Match
+// -----------------------------------------------------------------------------
+//
+TBool CATMemoryEntry::Match( const CATMemoryEntry& aFirst, const CATMemoryEntry& aSecond )
+ {
+ if ( aFirst.iMemAddress == aSecond.iMemAddress )
+ {
+ return ETrue;
+ }
+
+ // else
+ return EFalse;
+ }
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/server/src/atstorageserver.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,452 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Definitions for the class CATStorageServer. Includes also the
+* entry point of the atoolstorageserver.exe executable.
+*
+*/
+
+
+
+
+// INCLUDE FILES
+
+#include "atstorageserver.h"
+#include "atstorageserversession.h"
+#include "atstorageservercommon.h"
+#include "atlog.h"
+#include "atdynprocessinfo.h"
+
+
+// CONSTANTS
+
+
+// The amount of different ranges of requests specified for this policy server.
+// In a policy server, different actions can be determined for different ranges
+// of requests.
+const TUint8 KAmountOfRanges = 2;
+
+
+const TInt ranges[KAmountOfRanges] =
+ {
+ CATStorageServer::EProcessStarted,
+ CATStorageServer::EOutOfBounds
+ };
+
+
+const TUint8 actionForRange[ KAmountOfRanges ] =
+ { 0, CPolicyServer::ENotSupported };
+
+
+const CPolicyServer::TPolicyElement elements[] =
+ {
+
+ { _INIT_SECURITY_POLICY_C1( ECapability_None ),
+ CPolicyServer::EFailClient }
+
+ };
+
+
+const CPolicyServer::TPolicy policy =
+ {
+ CPolicyServer::EAlwaysPass, // On connect
+ KAmountOfRanges, // Range count
+ ranges,
+ actionForRange,
+ elements,
+ };
+
+
+
+// ENTRY POINT
+
+TInt E32Main()
+ {
+ LOGSTR1( "STSE TInt E32Main() in ATStorageServer.cpp" );
+
+ __UHEAP_MARK;
+
+ // Create a cleanup stack
+ CTrapCleanup* cleanup = CTrapCleanup::New();
+
+ TInt errorCode( KErrNoMemory );
+
+ // If there was enough memory to create a cleanup stack,
+ // create and start the server.
+ if( cleanup )
+ {
+ // If RunServerL() doesn't leave, errorCode will be set to KErrNone
+ TRAP( errorCode, CATStorageServer::RunServerL() );
+ delete cleanup;
+ }
+
+ // Signal the client that server creation failed, if a leave occured during
+ // the call to 'RunServerL()' function
+ if( errorCode != KErrNone )
+ {
+ RProcess::Rendezvous( errorCode );
+ }
+
+ __UHEAP_MARKEND;
+
+ return errorCode;
+
+ }
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CATStorageServer::CATStorageServer
+// C++ default constructor can NOT contain any code that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CATStorageServer::CATStorageServer( TInt aPriority ) :
+ CPolicyServer( aPriority, policy, ESharableSessions ),
+ iSessionCount( 0 )
+ {
+ LOGSTR1( "STSE CATStorageServer::CATStorageServer()" );
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServer::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CATStorageServer::ConstructL()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServer::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CATStorageServer* CATStorageServer::NewL()
+ {
+ CATStorageServer* self = NewLC();
+ CleanupStack::Pop( self );
+
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServer::NewLC
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CATStorageServer* CATStorageServer::NewLC()
+ {
+ CATStorageServer* self = new ( ELeave ) CATStorageServer( EPriorityStandard );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ self->StartL( KStorageServerName );
+ return self;
+ }
+
+// Destructor
+CATStorageServer::~CATStorageServer()
+ {
+ LOGSTR1( "STSE CATStorageServer::~CATStorageServer()" );
+
+ iProcesses.Close();
+ iProcessesDyn.ResetAndDestroy();
+ iProcessesDyn.Close();
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServer::NewSessionL
+// Create a new server session.
+// -----------------------------------------------------------------------------
+//
+CSession2* CATStorageServer::NewSessionL(
+ const TVersion &aVersion,
+ const RMessage2& /*aMessage*/ ) const
+ {
+ LOGSTR1( "STSE CSession2* CATStorageServer::NewSessionL()" );
+
+ // The server's version
+ TVersion version( KVersionNumberMaj, KVersionNumberMin,
+ KVersionNumberBld );
+
+ // Check this is a high enough version of the server
+ if ( !User::QueryVersionSupported(version, aVersion) )
+ {
+ User::Leave( KErrNotSupported );
+ }
+
+ // Construct and return a new session object
+ return CATStorageServerSession::NewL( const_cast<CATStorageServer&>(*this) );
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServer::RunServerL
+// Create active scheduler and a server object
+// -----------------------------------------------------------------------------
+//
+void CATStorageServer::RunServerL()
+ {
+ LOGSTR1( "STSE void CATStorageServer::RunServerL()" );
+
+ // Create and install an active scheduler
+ CActiveScheduler* activeSched = new (ELeave) CActiveScheduler;
+ CleanupStack::PushL( activeSched );
+ CActiveScheduler::Install( activeSched );
+
+ // Create server
+ CATStorageServer::NewLC();
+
+ // The initialization performed alright, signal the client
+ RProcess::Rendezvous( KErrNone );
+
+ // Start the active scheduler
+ CActiveScheduler::Start();
+
+ // Remove the server and active scheduler from the cleanup stack
+ CleanupStack::PopAndDestroy( 2, activeSched );
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServer::IncSessionCount
+// Increments the count of active sessions for this server.
+// -----------------------------------------------------------------------------
+//
+void CATStorageServer::IncSessionCount()
+ {
+ LOGSTR1( "STSE void CATStorageServer::IncSessionCount()" );
+
+ iSessionCount++;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServer::DecSessionCount
+// Decrements the count of active sessions for this server.
+// -----------------------------------------------------------------------------
+//
+void CATStorageServer::DecSessionCount()
+ {
+ LOGSTR1( "STSE void CATStorageServer::DecSessionCount()" );
+
+ iSessionCount--;
+
+ // Cancels all outstanding messages and stops the active scheduler,
+ // if there are no other sessions open at the moment
+ if ( iSessionCount <= 0 )
+ {
+ this->Cancel();
+ CActiveScheduler::Stop();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServer::AddProcessL
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServer::AddProcessL( const TDesC8& aProcessName,
+ TUint aProcessId,
+ CATStorageServerSession* aSessionObject,
+ const TInt64& aStartTime )
+ {
+ LOGSTR1( "STSE TInt CATStorageServer::AddProcessL()" );
+
+ TInt error( KErrNone );
+ TATProcessInfo processInfo;
+
+ processInfo.iProcessId = aProcessId;
+ processInfo.iProcessName.Copy( aProcessName );
+ processInfo.iStartTime = aStartTime;
+
+ // Insert the static process info into the iProcesses array
+ error = iProcesses.InsertInUnsignedKeyOrder( processInfo );
+
+ // Return if an error occured
+ if ( error != KErrNone)
+ {
+ return error;
+ }
+
+ // Construct a CATDynProcessInfo object with the given process ID and logging mode
+ CATDynProcessInfo* dynProcessInfo =
+ new (ELeave) CATDynProcessInfo( aProcessId,
+ aSessionObject );
+
+ // Insert the dynamic process info into the iProcessesDyn array
+ TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
+ error = iProcessesDyn.InsertInOrder( dynProcessInfo, order );
+
+ return error;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServer::RemoveProcessL
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServer::RemoveProcessL( TUint aProcessId )
+ {
+ LOGSTR1( "STSE TInt CATStorageServer::RemoveProcessL()" );
+
+ TATProcessInfo processInfo;
+ processInfo.iProcessId = aProcessId;
+
+ TInt index = iProcesses.FindInUnsignedKeyOrder( processInfo );
+
+ // Return, if a process with the requested process ID was not found
+ if ( index == KErrNotFound )
+ {
+ return index;
+ }
+
+ // Remove the TATProcessInfo object at "index" from the array
+ iProcesses.Remove( index );
+
+ // Now, start removing the associated dynamic process info object
+
+ // Construct a CATDynProcessInfo object with the given process ID
+ CATDynProcessInfo* dynProcessInfo =
+ new (ELeave) CATDynProcessInfo( aProcessId );
+
+ // Find the index of a CATDynProcessInfo object with the given ID in the array
+ TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
+ index = iProcessesDyn.FindInOrder( dynProcessInfo, order );
+ delete dynProcessInfo;
+ dynProcessInfo = NULL;
+
+ // Return, if a process with the requested process ID was not found
+ if ( index == KErrNotFound )
+ {
+ return index;
+ }
+
+ // Otherwise, delete the object and remove the pointer at "index"
+ delete iProcessesDyn[index];
+ iProcessesDyn.Remove( index );
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServer::AddDllL
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServer::AddDllL( TUint aProcessId,
+ const TATDllInfo aDllInfo )
+ {
+ LOGSTR1( "STSE TInt CATStorageServer::AddDllL()" );
+
+ // Construct a CATDynProcessInfo object with the given process ID
+ CATDynProcessInfo* dynProcessInfo =
+ new (ELeave) CATDynProcessInfo( aProcessId );
+
+ // Find out if a process with this ID can be found in the dynamic process array
+ TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
+ TInt index = iProcessesDyn.FindInOrder( dynProcessInfo, order );
+ delete dynProcessInfo;
+ dynProcessInfo = NULL;
+
+ // Return, if a process with the requested process ID was not found
+ if ( index == KErrNotFound )
+ {
+ return index;
+ }
+
+ // If we are here, the wanted process was found at index => append a DLL for it
+ dynProcessInfo = iProcessesDyn[index];
+
+ // Get the DLL array from this dynamic process info object
+ RArray<TATDllInfo>& dllArray = dynProcessInfo->iDlls;
+
+ // Let's see if the DLL to be added already exists
+ TIdentityRelation<TATDllInfo> matcher( TATDllInfo::Match );
+ index = dllArray.Find( aDllInfo, matcher );
+
+ // If so, return KErrAlreadyExists
+ if ( index != KErrNotFound )
+ {
+ return KErrAlreadyExists;
+ }
+
+ // Otherwise append this DLL to the array and return
+ return dynProcessInfo->iDlls.Append( aDllInfo );
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServer::RemoveDllL
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServer::RemoveDllL( TUint aProcessId,
+ const TDesC8& aDllName )
+ {
+ LOGSTR1( "STSE TInt CATStorageServer::RemoveDllL()" );
+
+ // Construct a CATDynProcessInfo object with the given process ID
+ CATDynProcessInfo* dynProcessInfo =
+ new (ELeave) CATDynProcessInfo( aProcessId );
+
+ // Find out if a process with this ID can be found in the dynamic process array
+ TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
+ TInt index = iProcessesDyn.FindInOrder( dynProcessInfo, order );
+ delete dynProcessInfo;
+ dynProcessInfo = NULL;
+
+ // Return, if a process with the requested process ID was not found
+ if ( index == KErrNotFound )
+ {
+ return index;
+ }
+
+ // If we are here, the wanted process was found at index
+ dynProcessInfo = iProcessesDyn[index];
+
+ // Get the DLL array from this dynamic process info object
+ RArray<TATDllInfo>& dllArray = dynProcessInfo->iDlls;
+
+ // Try to find wanted DLL
+ TIdentityRelation<TATDllInfo> matcher( TATDllInfo::Match );
+ index = dllArray.Find( TATDllInfo( 0, 0, 0, aDllName ), matcher );
+
+ // Return, if a process with the requested process ID was not found
+ if ( index == KErrNotFound )
+ {
+ return index;
+ }
+
+ // Otherwise remove the found DLL at "index"
+ dllArray.Remove( index );
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServer::ProcessInfoArray
+// -----------------------------------------------------------------------------
+//
+const RArray<TATProcessInfo>& CATStorageServer::ProcessInfoArray()
+ {
+ LOGSTR1( "STSE RArray<TATProcessInfo>& CATStorageServer::ProcessInfoArray()" );
+
+ return iProcesses;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServer::DynProcessInfoArray
+// -----------------------------------------------------------------------------
+//
+const RPointerArray<CATDynProcessInfo>& CATStorageServer::DynProcessInfoArray()
+ {
+ LOGSTR1( "STSE RPointerArray<CATDynProcessInfo>& CATStorageServer::DynProcessInfoArray()" );
+
+ return iProcessesDyn;
+ }
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/server/src/atstorageserversession.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,3397 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Definitions and constants for the class CATStorageServerSession
+*
+*/
+
+
+
+// INCLUDE FILES
+#include <utf.h>
+#include <analyzetool/analyzetooltraceconstants.h>
+#include "atstorageserversession.h"
+#include "atstorageserver.h"
+#include "atstorageservercommon.h"
+#include "atmemoryentry.h"
+#include "atlog.h"
+#include "atdynprocessinfo.h"
+#include "atdriveinfo.h"
+
+// CONSTANTS
+
+// New file name start and end index.
+const TInt KNameIndexStart = 1;
+const TInt KNameIndexEnd = 100;
+
+// ==================== MEMBER FUNCTIONS for TAllocInfo ========================
+
+// -----------------------------------------------------------------------------
+// TAllocInfo::TAllocInfo
+// Implementation for the constructor of the class TAllocInfo
+// -----------------------------------------------------------------------------
+//
+TAllocInfo::TAllocInfo( TUint32 aMemAddress, TInt aAllocSize ) :
+ iMemAddress( aMemAddress ),
+ iAllocSize( aAllocSize )
+ {
+ }
+
+
+// ============== MEMBER FUNCTIONS for CATStorageServerSession =================
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::CATStorageServerSession
+// C++ default constructor. It Does not contain any code that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CATStorageServerSession::CATStorageServerSession( CATStorageServer& aStorageServer ) :
+ iStorageServer( aStorageServer ),
+ iError( 0 ),
+ iLeakArray( KLeakArrayGranularity ),
+ iProcessId( KNullProcessId ),
+ iLoggingOngoing( EFalse ),
+ iLogOption( KDefaultLoggingMode ),
+ iCurAllocSize( 0 ),
+ iMaxAllocs( 0 ),
+ iMaxAllocSize( 0 ),
+ iLogFile( KEmpty() ),
+ iIsUdeb( 1 )
+ {
+ LOGSTR1( "STSE CATStorageServerSession::CATStorageServerSession()" );
+
+ // Initialize iMicroSecondsAt1970
+ TTime time( KJanuaryFirst1970 );
+ iMicroSecondsAt1970 = time.Int64();
+
+ // Increment the server's session count by one (1)
+ iStorageServer.IncSessionCount();
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CATStorageServerSession::ConstructL()
+ {
+ // Intentionally left empty
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CATStorageServerSession* CATStorageServerSession::NewL( CATStorageServer& aStorageServer )
+ {
+ CATStorageServerSession* self = NewLC( aStorageServer );
+ CleanupStack::Pop( self );
+
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::NewLC
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CATStorageServerSession* CATStorageServerSession::NewLC( CATStorageServer& aStorageServer )
+ {
+ CATStorageServerSession* self = new ( ELeave ) CATStorageServerSession( aStorageServer );
+
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::~CATStorageServerSession
+// Destructor
+// -----------------------------------------------------------------------------
+CATStorageServerSession::~CATStorageServerSession()
+ {
+ LOGSTR1( "STSE CATStorageServerSession::~CATStorageServerSession()" );
+
+ // Empty the array and delete the referenced objects
+ iLeakArray.ResetAndDestroy();
+
+ // Close the leak array
+ iLeakArray.Close();
+
+ // Close the allocation info array
+ iAllocInfoArray.Close();
+
+ // Check if process closed abnormal
+ if ( iProcessId != KNullProcessId &&
+ iLoggingOngoing && iLogOption != EATLoggingOff &&
+ iError != KErrNoMemory )
+ {
+ LogAbnormalEnd();
+ }
+
+ // Close the file and the handle to the file server
+ CloseFsAndFile();
+
+ // Remove the process with the current PID from the server's array of processes
+ TRAP_IGNORE( iStorageServer.RemoveProcessL( iProcessId ) );
+
+ // Decrement the server's session count by one (1)
+ iStorageServer.DecSessionCount();
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::ServiceL
+// This function is called by the client/server framework
+// -----------------------------------------------------------------------------
+//
+void CATStorageServerSession::ServiceL( const RMessage2& aMessage )
+ {
+ LOGSTR1( "STSE void CATStorageServerSession::ServiceL()" );
+
+ // If logging has been cancelled for this session, return immediately
+ if( iLogOption == EATLoggingOff )
+ {
+ aMessage.Complete( KErrCancel );
+ return;
+ }
+
+ switch ( aMessage.Function() )
+ {
+ case CATStorageServer::EProcessStarted:
+ {
+ // If logging is not ongoing, set the log option
+ if( !iLoggingOngoing )
+ {
+ // Set the operation mode
+ SetLogOption( aMessage );
+ }
+
+ switch ( iLogOption )
+ {
+ case EATLogToTrace:
+ {
+ iError = LogProcessStartTraceL( aMessage );
+ }
+ break;
+
+ case EATLogToFile:
+ {
+ iError = LogProcessStartedL( aMessage );
+ }
+ break;
+
+ default:
+ {
+ // Panic the client and set iError KErrCancel, because being
+ // here implies that an illegal log option has been given.
+ PanicClient( EAToolIllegalLogOption, aMessage );
+ iError = KErrCancel;
+ }
+ break;
+ }
+ }
+ break;
+
+
+ case CATStorageServer::EDllLoaded:
+ {
+ switch ( iLogOption )
+ {
+ case EATLogToTrace:
+ {
+ iError = LogDllLoadTraceL( aMessage );
+ }
+ break;
+
+ case EATLogToFile:
+ {
+ iError = LogDllLoadedL( aMessage );
+ }
+ break;
+
+ default:
+ {
+ // Panic the client and set iError KErrCancel, because being
+ // here implies that an illegal log option has been given.
+ PanicClient( EAToolIllegalLogOption, aMessage );
+ iError = KErrCancel;
+ }
+ break;
+ }
+ }
+ break;
+
+
+ case CATStorageServer::EDllUnloaded:
+ {
+ switch ( iLogOption )
+ {
+ case EATLogToTrace:
+ {
+ iError = LogDllUnloadTraceL( aMessage );
+ }
+ break;
+
+ case EATLogToFile:
+ {
+ iError = LogDllUnloadedL( aMessage );
+ }
+ break;
+
+ default:
+ {
+ // Panic the client and set iError KErrCancel, because being
+ // here implies that an illegal log option has been given.
+ PanicClient( EAToolIllegalLogOption, aMessage );
+ iError = KErrCancel;
+ }
+ break;
+ }
+ }
+ break;
+
+
+ case CATStorageServer::EMemoryAllocated:
+ {
+ switch ( iLogOption )
+ {
+ case EATLogToTrace:
+ {
+ iError = LogMemoryAllocTraceL( aMessage );
+ }
+ break;
+
+ case EATLogToFile:
+ {
+ iError = LogMemoryAllocatedL( aMessage );
+ }
+ break;
+
+ default:
+ {
+ // Panic the client and set iError KErrCancel, because being
+ // here implies that an illegal log option has been given.
+ PanicClient( EAToolIllegalLogOption, aMessage );
+ iError = KErrCancel;
+ }
+ break;
+ }
+ }
+ break;
+
+
+ case CATStorageServer::EMemoryFreed:
+ {
+ switch ( iLogOption )
+ {
+ case EATLogToTrace:
+ {
+ iError = LogMemoryFreedTraceL( aMessage );
+ }
+ break;
+
+ case EATLogToFile:
+ {
+ iError = LogMemoryFreedL( aMessage );
+ }
+ break;
+
+ default:
+ {
+ // Panic the client and set iError KErrCancel, because being
+ // here implies that an illegal log option has been given.
+ PanicClient( EAToolIllegalLogOption, aMessage );
+ iError = KErrCancel;
+ }
+ break;
+ }
+ }
+ break;
+
+
+ case CATStorageServer::EProcessEnded:
+ {
+ switch ( iLogOption )
+ {
+ case EATLogToTrace:
+ {
+ iError = LogProcessEndTraceL( aMessage );
+ }
+ break;
+
+ case EATLogToFile:
+ {
+ iError = LogProcessEndedL( aMessage );
+ }
+ break;
+
+ default:
+ {
+ // Panic the client and set iError KErrCancel, because being
+ // here implies that an illegal log option has been given.
+ PanicClient( EAToolIllegalLogOption, aMessage );
+ iError = KErrCancel;
+ }
+ break;
+ }
+ }
+ break;
+
+
+ case CATStorageServer::EMemoryCheck:
+ {
+ switch ( iLogOption )
+ {
+ case EATLogToTrace:
+ {
+ iError = CheckMemoryAddressTrace( aMessage );
+ }
+ break;
+
+ case EATLogToFile:
+ {
+ iError = CheckMemoryAddressL( aMessage );
+ }
+ break;
+
+ default:
+ {
+ // Panic the client and set iError KErrCancel, because being
+ // here implies that an illegal log option has been given.
+ PanicClient( EAToolIllegalLogOption, aMessage );
+ iError = KErrCancel;
+ }
+ break;
+ }
+ }
+ break;
+
+
+ case CATStorageServer::EGetProcesses:
+ {
+ iError = GetProcessesL( aMessage );
+ }
+ break;
+
+
+ case CATStorageServer::EGetDlls:
+ {
+ iError = GetDllsL( aMessage );
+ }
+ break;
+
+ case CATStorageServer::EGetLoggingMode:
+ {
+ iError = GetLoggingModeL( aMessage );
+ }
+ break;
+
+ case CATStorageServer::ESubtestStart:
+ {
+ iError = StartSubtestL( aMessage );
+ }
+ break;
+
+ case CATStorageServer::ESubtestStop:
+ {
+ iError = StopSubtestL( aMessage );
+ }
+ break;
+
+ case CATStorageServer::ESubtestStart2:
+ {
+ iError = StartSubtest2L( aMessage );
+ }
+ break;
+
+ case CATStorageServer::ESubtestStop2:
+ {
+ iError = StopSubtest2( aMessage );
+ }
+ break;
+
+ case CATStorageServer::EGetCurrentAllocs:
+ {
+ iError = GetCurrentAllocsL( aMessage );
+ }
+ break;
+
+ case CATStorageServer::EGetMaxAllocs:
+ {
+ iError = GetMaxAllocsL( aMessage );
+ }
+ break;
+
+ case CATStorageServer::ECancelLogging:
+ {
+ iError = CancelLoggingL( aMessage );
+ }
+ break;
+
+ case CATStorageServer::EGetUdeb:
+ {
+ iError = GetUdebL( aMessage );
+ }
+ break;
+
+ case CATStorageServer::EGetLoggingFile:
+ {
+ iError = GetLoggingFileL( aMessage );
+ }
+ break;
+
+ case CATStorageServer::EProcessUdeb:
+ {
+ SetUdeb( aMessage );
+ }
+ break;
+
+ case CATStorageServer::EIsMemoryAdded:
+ {
+ iError = IsMemoryAdded( aMessage );
+ LOGSTR2( "STSE > IsMemoryAdded err = %i", iError );
+ }
+ break;
+
+ default:
+ {
+ // Panic both the client and server, because being here implies
+ // that there is an internal error in the client/server.
+ PanicClient( EAToolBadRequest, aMessage );
+ StorageServerPanic( KCategoryServer, EAToolBadRequest );
+ }
+ break;
+
+ }
+
+ // Complete the message, if it has not been already cancelled.
+ if ( iError != KErrCancel )
+ {
+ // Log the error code. Only KErrNoMemory errors are logged.
+ if ( iLogOption == EATLogToFile && iError == KErrNoMemory )
+ {
+ HandleError( iError );
+ }
+ else if ( iLogOption == EATLogToTrace && iError == KErrNoMemory )
+ {
+ HandleErrorTrace( iError );
+ }
+
+ // Complete serving the message
+ aMessage.Complete( iError );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::LogProcessStartedL()
+// Opens a logging file with the requested name and then writes information
+// on process start into the file.
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::LogProcessStartedL( const RMessage2& aMessage )
+ {
+ LOGSTR1( "STSE TInt CATStorageServerSession::LogProcessStartedL()" );
+
+ // Panic the client and return, if this method has already been called for this
+ // session object (and a logging file has been opened)
+ if ( iLoggingOngoing )
+ {
+ PanicClient( EAToolNotAllowed, aMessage );
+ return KErrCancel;
+ }
+
+ iError = KErrNone;
+
+ LOGMEM;
+
+ // READ THE FIRST ARGUMENT (descriptor)
+
+ // Length of the first argument (index 0)
+ TInt length = aMessage.GetDesLength( 0 );
+
+ LOGSTR2( "STSE length of the fileName: %i", length );
+
+ // Return if errors
+ if ( length == KErrArgument || length == KErrBadDescriptor )
+ {
+ return length;
+ }
+
+ // Construct a buffer for file name, and leave the pointer on Cleanup Stack
+ HBufC* fileName = HBufC::NewLC( length );
+ TPtr fileNamePtr( fileName->Des() );
+
+ // Read the client side's descriptor at index 0
+ iError = aMessage.Read( 0, fileNamePtr );
+
+ if ( iError != KErrNone )
+ {
+ CleanupStack::PopAndDestroy( fileName );
+ return iError;
+ }
+
+ // READ THE SECOND ARGUMENT (descriptor)
+
+ // Length of the second argument (index 1)
+ length = aMessage.GetDesLength( 1 );
+
+ LOGSTR2( "STSE length of the processName: %i", length );
+
+ // Return if errors
+ if ( length == KErrArgument || length == KErrBadDescriptor )
+ {
+ CleanupStack::PopAndDestroy( fileName );
+ return length;
+ }
+
+ HBufC8* processName = HBufC8::NewL( length );
+ TPtr8 bufPtr( processName->Des() );
+
+ // Read the client side's descriptor at index 1
+ iError = aMessage.Read( 1, bufPtr );
+
+ if ( iError != KErrNone )
+ {
+ delete processName;
+ CleanupStack::PopAndDestroy( fileName );
+ return iError;
+ }
+
+ // READ THE THIRD ARGUMENT (integer, a process ID)
+ TInt processId = aMessage.Int2();
+
+ // Open a file server session and a file. The file
+ // will be opened with the name received from the client
+ iError = OpenFsAndFile( *fileName, *processName );
+ CleanupStack::PopAndDestroy( fileName );
+ // Return without logging, if an error occured
+ if ( iError != KErrNone )
+ {
+ // Delete the local objects
+ delete processName;
+ return iError;
+ }
+
+ // Get the home time for the configuration UI
+ iTime.HomeTime();
+
+ // Add the process into the server's array of processes
+ iError = iStorageServer.AddProcessL( *processName,
+ processId,
+ this,
+ iTime.Int64() );
+
+ // Return without logging, if an error occured
+ if ( iError )
+ {
+ // Remove, if something was added regardless of the error
+ // However, we must not remove an existing process
+ if ( iError != KErrAlreadyExists )
+ {
+ iStorageServer.RemoveProcessL( processId );
+ }
+ return iError;
+ }
+
+ // Make a buffer that will be logged into the opened logging file
+ TBuf8<KProcessStartBufLength> loggingBuf;
+ loggingBuf.Format( KProcessStart, processName, processId );
+
+ delete processName;
+
+ // Get the current universal time
+ TInt64 timeFrom1970( GetTime() );
+
+ // Append the current time in the 64-bit (max 16 characters) hexadecimal text
+ // format
+ loggingBuf.AppendNum( timeFrom1970, EHex );
+
+ // Append udeb/urel information to the process start
+ loggingBuf.Append( KSpace );
+ loggingBuf.AppendNum( iIsUdeb, EHex );
+
+ // Append trace version information
+ loggingBuf.Append( KSpace );
+ loggingBuf.AppendNum( KATTraceVersion, EHex );
+
+ // Append a new line
+ loggingBuf.Append( KNewLine );
+
+ // Write the buffer into the file
+ iError = iFile.Write( loggingBuf );
+
+ // Return, if an error occured
+ if ( iError )
+ {
+ iStorageServer.RemoveProcessL( processId );
+ return iError;
+ }
+
+ LOGMEM;
+
+ // Set the process ID value for this logging session
+ iProcessId = processId;
+ // Set logging session started
+ iLoggingOngoing = ETrue;
+
+ return iError;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::LogProcessStartTraceL()
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::LogProcessStartTraceL( const RMessage2& aMessage )
+ {
+ LOGSTR1( "STSE TInt CATStorageServerSession::LogProcessStartTraceL()" );
+
+ // Panic the client and return, if this method has already been called for this
+ // session object
+ if ( iLoggingOngoing )
+ {
+ PanicClient( EAToolNotAllowed, aMessage );
+ return KErrCancel;
+ }
+
+ iError = KErrNone;
+
+ LOGMEM;
+
+ // READ THE SECOND ARGUMENT (descriptor)
+ // The first argument, file name, is ignored when logging thru trace
+
+ // Length of the second argument (index 1)
+ TInt length = aMessage.GetDesLength( 1 );
+
+ LOGSTR2( "STSE length of the processName: %i", length );
+
+ // Return if errors
+ if ( length == KErrArgument || length == KErrBadDescriptor )
+ {
+ return length;
+ }
+
+ HBufC8* processName = HBufC8::NewL( length );
+ TPtr8 bufPtr( processName->Des() );
+
+ // Read the client side's descriptor at index 1
+ iError = aMessage.Read( 1, bufPtr );
+
+ if ( iError != KErrNone )
+ {
+ // Delete local objects and return
+ delete processName;
+ return iError;
+ }
+
+ // READ THE THIRD ARGUMENT (integer, a process ID)
+ TInt processId = aMessage.Int2();
+
+ // Get the home time for the configuration UI
+ iTime.HomeTime();
+
+ // Add the process into the server's array of processes
+ iError = iStorageServer.AddProcessL( *processName, processId, this,
+ iTime.Int64() );
+
+ // Return without logging, if an error occured
+ if ( iError )
+ {
+ // Remove, if something was added regardless of the error
+ // However, we must not remove an existing process
+ if ( iError != KErrAlreadyExists )
+ {
+ iStorageServer.RemoveProcessL( processId );
+ }
+ return iError;
+ }
+
+ // Make a buffer that will be logged
+ TBuf8<KProcessStartBufLength> loggingBuf;
+
+ loggingBuf.Format( KProcessStart, processName, processId );
+
+ delete processName;
+
+ // Get the current universal time
+ TInt64 timeFrom1970( GetTime() );
+
+ // Append the current time in the 64-bit (max 16 characters) hexadecimal text
+ // format
+ loggingBuf.AppendNum( timeFrom1970, EHex );
+
+ // Append udeb/urel information to the process start
+ loggingBuf.Append( KSpace );
+ loggingBuf.AppendNum( iIsUdeb, EHex );
+
+ // Append version number
+ loggingBuf.Append( KSpace );
+ loggingBuf.AppendNum( KATTraceVersion, EHex );
+
+ // Append a new line
+ loggingBuf.Append( KNewLine );
+
+ // Log to trace
+ TBuf<KProcessStartBufLength> traceBuf;
+ traceBuf.Copy( loggingBuf );
+ RDebug::Print( KTraceMessage, processId ,&traceBuf );
+
+ LOGMEM;
+
+ // Set the process ID value for this logging session
+ iProcessId = processId;
+ // Set logging session started
+ iLoggingOngoing = ETrue;
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::LogDllLoadedL()
+// Logs to the file opened by the function LogProcessStartedL()
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::LogDllLoadedL( const RMessage2& aMessage )
+ {
+ LOGSTR1( "STSE TInt CATStorageServerSession::LogDllLoadedL()" );
+
+ // Panic the client and return, if a logging session is not ongoing
+ // ( can be started by calling the client's LogProcessStarted() )
+ if ( !iLoggingOngoing )
+ {
+ PanicClient( EAToolNotAllowed, aMessage );
+ return KErrCancel;
+ }
+
+ iError = KErrNone;
+
+ // Read the length of the first argument (index 0)
+ TInt length = aMessage.GetDesLength( 0 );
+
+ // Return if errors
+ if ( length == KErrArgument || length == KErrBadDescriptor )
+ {
+ return length;
+ }
+
+ HBufC8* dllName = HBufC8::NewL( length );
+ TPtr8 bufPtr( dllName->Des() );
+
+ // Read the client side's descriptor (the argument 0)
+ iError = aMessage.Read( 0, bufPtr );
+
+ if ( iError != KErrNone )
+ {
+ delete dllName;
+ return iError;
+ }
+
+ // Get the current universal time
+ TInt64 timeFrom1970( GetTime() );
+
+ // Add this dll into the server's array
+ TUint32 startAddress( aMessage.Int1() );
+ TUint32 endAddress( aMessage.Int2() );
+ iError = iStorageServer.AddDllL( iProcessId,
+ TATDllInfo( startAddress, endAddress, timeFrom1970, *dllName ) );
+
+ // Return without logging, if an error occured
+ if ( iError )
+ {
+ delete dllName;
+ return iError;
+ }
+
+ // Make a buffer that will be logged into the opened logging file
+ TBuf8<KDllLoadBufLength> loggingBuf;
+ loggingBuf.Format( KDllLoad, dllName, timeFrom1970, startAddress, endAddress );
+
+ delete dllName;
+
+ // Write the buffer into a file and return the error code
+ return iFile.Write( loggingBuf );
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::LogDllLoadTraceL()
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::LogDllLoadTraceL( const RMessage2& aMessage )
+ {
+ LOGSTR1( "STSE TInt CATStorageServerSession::LogDllLoadTraceL()" );
+
+ // Panic the client and return, if a logging session is not ongoing
+ // ( can be started by calling the client's LogProcessStarted() )
+ if ( !iLoggingOngoing )
+ {
+ PanicClient( EAToolNotAllowed, aMessage );
+ return KErrCancel;
+ }
+
+ iError = KErrNone;
+
+ // Read the length of the first argument (index 0)
+ TInt length = aMessage.GetDesLength( 0 );
+
+ // Return if errors
+ if ( length == KErrArgument || length == KErrBadDescriptor )
+ {
+ return length;
+ }
+
+ HBufC8* dllName = HBufC8::NewL( length );
+ TPtr8 bufPtr( dllName->Des() );
+
+ // Read the client side's descriptor (the argument 0)
+ iError = aMessage.Read( 0, bufPtr );
+
+ if ( iError != KErrNone )
+ {
+ delete dllName;
+ return iError;
+ }
+ // Get the current universal time
+ TInt64 timeFrom1970( GetTime() );
+
+ TUint32 startAddress( aMessage.Int1() );
+ TUint32 endAddress( aMessage.Int2() );
+
+ // Add this dll into the server's array
+ iError = iStorageServer.AddDllL( iProcessId,
+ TATDllInfo( startAddress, endAddress, timeFrom1970, *dllName ) );
+
+ // Return without logging, if an error occured
+ if ( iError )
+ {
+ delete dllName;
+ return iError;
+ }
+
+ // Make a buffer that will be logged
+ TBuf8<KDllLoadBufLength> loggingBuf;
+ loggingBuf.Format( KDllLoad, dllName, timeFrom1970, startAddress, endAddress );
+
+ delete dllName;
+
+ TBuf<KDllLoadBufLength> traceBuf;
+ traceBuf.Copy( loggingBuf );
+ RDebug::Print( KTraceMessage, iProcessId ,&traceBuf );
+ return iError;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::LogDllUnloadedL()
+// Logs to the file opened by the function LogProcessStartedL()
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::LogDllUnloadedL( const RMessage2& aMessage )
+ {
+ LOGSTR1( "STSE TInt CATStorageServerSession::LogDllUnloadedL()" );
+
+ // Panic the client and return, if a logging session is not ongoing
+ // ( can be started by calling the client's LogProcessStarted() )
+ if ( !iLoggingOngoing )
+ {
+ PanicClient( EAToolNotAllowed, aMessage );
+ return KErrCancel;
+ }
+
+ iError = KErrNone;
+
+ // Read the length of the first argument (index 0)
+ TInt length = aMessage.GetDesLength( 0 );
+
+ LOGSTR2( "STSE length %i", length );
+
+ // Return if errors
+ if ( length == KErrArgument || length == KErrBadDescriptor )
+ {
+ return length;
+ }
+
+ HBufC8* dllName = HBufC8::NewL( length );
+ TPtr8 bufPtr( dllName->Des() );
+
+ // Read the client side's descriptor (the argument 0)
+ iError = aMessage.Read( 0, bufPtr );
+
+ if ( iError != KErrNone )
+ {
+ delete dllName;
+ return iError;
+ }
+
+ TUint32 startAddress = aMessage.Int1();
+ TUint32 endAddress = aMessage.Int2();
+
+ // Get the current universal time
+ TInt64 timeFrom1970( GetTime() );
+
+ // Make a buffer that will be logged into the opened logging file
+ TBuf8<KDllUnloadBufLength> loggingBuf;
+ loggingBuf.Format( KDllUnload, dllName, timeFrom1970, startAddress, endAddress );
+
+ // Remove this dll from the server's array
+ iError = iStorageServer.RemoveDllL( iProcessId, bufPtr );
+
+ delete dllName;
+
+ // Return without logging, if an error occured
+ if ( iError )
+ {
+ return iError;
+ }
+
+ // Write the buffer into a file and return the error code
+ return iFile.Write( loggingBuf );
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::LogDllUnloadTraceL()
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::LogDllUnloadTraceL( const RMessage2& aMessage )
+ {
+ LOGSTR1( "STSE TInt CATStorageServerSession::LogDllUnloadTraceL()" );
+
+ // Panic the client and return, if a logging session is not ongoing
+ // ( can be started by calling the client's LogProcessStarted() )
+ if ( !iLoggingOngoing )
+ {
+ PanicClient( EAToolNotAllowed, aMessage );
+ return KErrCancel;
+ }
+
+ iError = KErrNone;
+
+ // Read the length of the first argument (index 0)
+ TInt length = aMessage.GetDesLength( 0 );
+
+ LOGSTR2( "STSE length %i", length );
+
+ // Return if errors
+ if ( length == KErrArgument || length == KErrBadDescriptor )
+ {
+ return length;
+ }
+
+ HBufC8* dllName = HBufC8::NewL( length );
+ TPtr8 bufPtr( dllName->Des() );
+
+ // Read the client side's descriptor (the argument 0)
+ iError = aMessage.Read( 0, bufPtr );
+
+ if ( iError != KErrNone )
+ {
+ delete dllName;
+ return iError;
+ }
+
+ TUint32 startAddress = aMessage.Int1();
+ TUint32 endAddress = aMessage.Int2();
+
+ // Get the current universal time
+ TInt64 timeFrom1970( GetTime() );
+
+ // Make a buffer that will be logged
+ TBuf8<KDllUnloadBufLength> loggingBuf;
+ loggingBuf.Format( KDllUnload, dllName, timeFrom1970, startAddress, endAddress );
+
+ // Remove this dll from the server's array
+ iError = iStorageServer.RemoveDllL( iProcessId, bufPtr );
+
+ delete dllName;
+
+ // Return without logging, if an error occured
+ if ( iError )
+ {
+ return iError;
+ }
+
+ TBuf<KDllLoadBufLength> traceBuf;
+ traceBuf.Copy( loggingBuf );
+ RDebug::Print( KTraceMessage, iProcessId ,&traceBuf );
+ return iError;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::LogMemoryAllocatedL()
+// Constructs a CATMemoryEntry object and appends it into iLeakArray.
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::LogMemoryAllocatedL( const RMessage2& aMessage )
+ {
+ LOGSTR1( "STSE TInt CATStorageServerSession::LogMemoryAllocatedL()" );
+
+ // Panic the client and return, if a logging session is not ongoing
+ // ( can be started by calling the client's LogProcessStarted() )
+ if ( !iLoggingOngoing )
+ {
+ PanicClient( EAToolNotAllowed, aMessage );
+ return KErrCancel;
+ }
+
+ // A pointer to a buffer of call stack's memory addresses
+ CBufFlat* stackBuf = NULL;
+
+ iError = KErrNone;
+
+ // Get the current universal time
+ TInt64 timeFrom1970( GetTime() );
+
+ // Read the first argument (index 0)
+ TUint32 memAddress = aMessage.Int0();
+ if ( memAddress == 0 )
+ {
+ return KErrNotSupported;
+ }
+
+ // Read the length of the descriptor argument (index 1) that should include
+ // call stack memory addresses associated with this memory allocation
+ TInt bufferLength = aMessage.GetDesLength( 1 );
+
+ // Construct a buffer for aCallstack
+ stackBuf = CBufFlat::NewL( bufferLength );
+ CleanupStack::PushL( stackBuf );
+
+ // Buffer position
+ TInt pos = 0;
+
+ stackBuf->ExpandL( pos, bufferLength );
+
+ TPtr8 bufPtr = stackBuf->Ptr( pos );
+
+ // Read the descriptor argument into the buffer
+ aMessage.ReadL( 1, bufPtr );
+
+ // Read the third argument (index 2) that tells the size of this allocation
+ TInt size = aMessage.Int2();
+
+ // Construct a new CATMemoryEntry object.
+ // The ownership of the current stackBuf object is given to the "entry" object.
+ CATMemoryEntry* entry =
+ new (ELeave) CATMemoryEntry( memAddress, stackBuf, timeFrom1970, size );
+
+ // Pop stackBuf from CleanupStack and set it to NULL, because it is not used anymore.
+ CleanupStack::Pop( stackBuf );
+ stackBuf = NULL;
+
+ // Make sure that the same memory area is not tryed to be allocated a second time
+ TIdentityRelation<CATMemoryEntry> matcher( CATMemoryEntry::Match );
+
+ TInt index = iLeakArray.Find( entry, matcher );
+
+ if ( index == KErrNotFound )
+ {
+ TLinearOrder<CATMemoryEntry> order( CATMemoryEntry::Compare );
+
+ // Insert the "entry" object into "iLeakArray". The ownership of
+ // the "entry" object is given to the array.
+ iError = iLeakArray.InsertInOrderAllowRepeats( entry, order );
+
+ // If an insertion to the array was not successful, delete the created
+ // entry manually and return.
+ if ( iError )
+ {
+ delete entry;
+ return iError;
+ }
+
+ // Make a TAllocInfo object, and give values for its members.
+ TAllocInfo allocInfo( memAddress, size );
+
+ // Insert the allocInfo object into iAllocInfoArray
+ iError = iAllocInfoArray.InsertInUnsignedKeyOrder( allocInfo );
+
+ // If an insertion to the array was not successful, delete the created entry
+ // and remove its pointer from iLeakArray.
+ if ( iError )
+ {
+ index = iLeakArray.Find( entry, matcher );
+ // Delete the entry object and remove remove the pointer from the array
+ delete entry;
+ // The index should be in a legal range, because the earlier insertion of
+ // the entry was successful
+ iLeakArray.Remove( index );
+ }
+
+ // Otherwise update the iCurAllocSize, iMaxAllocs and iMaxAllocSize variables
+
+ iCurAllocSize += size;
+
+ // The count can never be negative => associate it to an unsigned int
+ TUint allocCount = iAllocInfoArray.Count();
+ if ( allocCount > iMaxAllocs )
+ {
+ iMaxAllocs = allocCount;
+ }
+
+ if ( iCurAllocSize > iMaxAllocSize )
+ {
+ iMaxAllocSize = iCurAllocSize;
+ }
+
+ return iError;
+ }
+
+ // This shouldn't happen, because the same memory area shouldn't be allocated
+ // more than once (without deallocating it first)
+ else
+ {
+ delete entry;
+ return KErrAlreadyExists;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::LogMemoryAllocTraceL()
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::LogMemoryAllocTraceL( const RMessage2& aMessage )
+ {
+ LOGSTR1( "STSE TInt CATStorageServerSession::LogMemoryAllocTraceL()" );
+
+ // Panic the client and return, if a logging session is not ongoing
+ // ( can be started by calling the client's LogProcessStarted() )
+ if ( !iLoggingOngoing )
+ {
+ PanicClient( EAToolNotAllowed, aMessage );
+ return KErrCancel;
+ }
+
+ // Read the first argument (index 0)
+ TUint32 memAddress = aMessage.Int0();
+ if ( memAddress == 0 )
+ {
+ return KErrNotSupported;
+ }
+
+ // Read the third argument (index 2) that tells the size of this allocation
+ TInt size = aMessage.Int2();
+
+ // Append this allocation into the iAllocInfoArray array. This array is for
+ // providing the configuration UI with information on allocations
+
+ // Make a TAllocInfo object, and give values for its members.
+ TAllocInfo allocInfo( memAddress, size );
+
+ // Insert the allocInfo object into iAllocInfoArray
+ iError = iAllocInfoArray.InsertInUnsignedKeyOrder( allocInfo );
+
+ // Log debug message if duplicated allocation.
+ if ( iError == KErrAlreadyExists )
+ {
+ LOGSTR2( "STSE TInt CATStorageServerSession::LogMemoryAllocTraceL() Error, duplicate allocation :%i", memAddress );
+ }
+
+ // A pointer to a buffer of call stack's memory addresses
+ CBufFlat* stackBuf = NULL;
+
+ // Get the current universal time
+ TInt64 timeFrom1970( GetTime() );
+
+ // Read the length of the descriptor argument (index 1) that should include
+ // call stack memory addresses associated with this memory allocation
+ TInt bufferLength = aMessage.GetDesLength( 1 );
+
+ // Construct a buffer for aCallstack
+ stackBuf = CBufFlat::NewL( bufferLength );
+ CleanupStack::PushL( stackBuf );
+
+ // Buffer position
+ TInt pos( 0 );
+ stackBuf->ExpandL( pos, bufferLength );
+
+ TPtr8 bufPtr = stackBuf->Ptr( pos );
+
+ // Read the descriptor argument (index 1) into the buffer
+ aMessage.ReadL( 1, bufPtr );
+
+ // Variable for the number of memory addresses in the call stack
+ TInt addrCount( 0 );
+ TUint32 callStackAddr;
+
+ // Read the first word of the buffer. This includes the number of
+ // memory addresses stored in the current stackBuf
+ stackBuf->Read( pos, &addrCount, KWordSize );
+
+ // Move the position one word onwards.
+ pos += KWordSize;
+
+ // Create a 16-bit buffer, and a pointer descriptor for it
+ // ALLOCH <Memory address> <Time stamp> <Allocation size> <Call stack address count>
+ // <Call stack address> <Call stack address> ...
+ HBufC* traceBuf = HBufC::NewL( KMemAllocBufLength );
+ TPtr tracePtr( traceBuf->Des() );
+
+ // Pop stackBuf from CleanupStack, since no leavable operations will be done
+ // anymore
+ CleanupStack::Pop( stackBuf );
+
+ // Append the tag implying a memory allocation line in the data file
+ tracePtr.Append( KMemoryAllocHeader );
+
+ // Append the start address of this allocation in the 32-bit (max 8 characters)
+ // hexadecimal text format.
+ tracePtr.AppendNum( memAddress, EHex );
+
+ // Append the current time in the 64-bit (max 16 characters) hexadecimal text
+ // format
+ tracePtr.Append( KSpaceTrace );
+ tracePtr.AppendNum( timeFrom1970, EHex );
+
+ // Append the size of the allocation in the 32-bit (max 8 characters) hexadecimal
+ // text format.
+ tracePtr.Append( KSpaceTrace );
+ tracePtr.AppendNum( size, EHex );
+
+ // Append call stack address count
+ tracePtr.Append( KSpaceTrace );
+ tracePtr.AppendNum( addrCount, EHex );
+
+ // Calculate last item length
+ TInt lastItemLength( KTraceMessage().Length() + KHexa32Length +
+ KSpaceLength + KNewlineLength );
+
+ TUint packetNumber( 1 );
+
+ // Go through all call stack's memory addresses associated with
+ // this memory allocation
+ for ( TInt j = 0; j < addrCount; j++ )
+ {
+ // ALLOCF <Memory address> <Time stamp> <Packet number>
+ // <Call stack address> <Call stack address> ...
+ if ( tracePtr.Length() <= 0 )
+ {
+ // Create alloc fragment message header
+ tracePtr.Append( KMemoryAllocFragment );
+ tracePtr.AppendNum( memAddress, EHex );
+ tracePtr.Append( KSpaceTrace );
+ tracePtr.AppendNum( timeFrom1970, EHex );
+ tracePtr.Append( KSpaceTrace );
+ tracePtr.AppendNum( packetNumber, EHex );
+ // Increase packet number
+ packetNumber++;
+ }
+
+ // Read the next call stack's memory address stored in the buffer.
+ stackBuf->Read( pos, &callStackAddr, KWordSize );
+
+ // Append the read memory address as a hexadecimal number
+ tracePtr.AppendFormat( KHexaNumberTrace, callStackAddr );
+
+ // Move the pos variable one word onwards.
+ pos += KWordSize;
+
+ // Check if buffer max length exceed
+ if ( lastItemLength + tracePtr.Length() >= KMemAllocBufLength )
+ {
+ tracePtr.Append( KNewLineTrace );
+ // Log through debug channel
+ RDebug::Print( KTraceMessage, iProcessId, traceBuf );
+ // Empty trace buffer
+ tracePtr.Delete( 0, tracePtr.MaxLength() );
+ }
+ }
+
+ // Send the last message if exists
+ if ( tracePtr.Length() > 0 )
+ {
+ tracePtr.Append( KNewLineTrace );
+
+ // Log through debug channel
+ RDebug::Print( KTraceMessage, iProcessId, traceBuf );
+ }
+
+ delete traceBuf;
+ delete stackBuf;
+
+ // Update the iCurAllocSize, iMaxAllocs and iMaxAllocSize variables
+ iCurAllocSize += size;
+
+ // The count can never be negative => associate it to an unsigned int
+ TUint allocCount = iAllocInfoArray.Count();
+ if ( allocCount > iMaxAllocs )
+ {
+ iMaxAllocs = allocCount;
+ }
+
+ if ( iCurAllocSize > iMaxAllocSize )
+ {
+ iMaxAllocSize = iCurAllocSize;
+ }
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::LogMemoryFreedL()
+// Removes a TATMemoryEntry object with the specified memory address from
+// iLeakArray, if found.
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::LogMemoryFreedL( const RMessage2& aMessage )
+ {
+ LOGSTR1( "STSE TInt CATStorageServerSession::LogMemoryFreedL()" );
+
+ // Panic the client and return, if a logging session is not ongoing
+ // ( can be started by calling the client's LogProcessStarted() )
+ if ( !iLoggingOngoing )
+ {
+ PanicClient( EAToolNotAllowed, aMessage );
+ return KErrCancel;
+ }
+
+ // Get the memory address
+ TUint32 memAddress = aMessage.Int0();
+
+ // Remove this memory allocation from the leak array
+ TIdentityRelation<CATMemoryEntry> matcher( CATMemoryEntry::Match );
+ CATMemoryEntry* entry = new (ELeave) CATMemoryEntry( memAddress, NULL, 0, 0 );
+ TInt index = iLeakArray.Find( entry, matcher );
+ delete entry;
+
+ // Return, if the requested memory address was not found
+ // (had not been allocated)
+ if ( index == KErrNotFound )
+ {
+ return index;
+ }
+
+ // Delete the CATMemoryEntry object at "index" and remove from the array
+ delete iLeakArray[index];
+ iLeakArray.Remove( index );
+
+ // Remove this memory allocation also from the allocation info array
+ // Make a TAllocInfo object for a "find" operation
+ TAllocInfo allocInfo( memAddress, 0 );
+ index = iAllocInfoArray.FindInUnsignedKeyOrder( allocInfo );
+
+ // The index should not be KErrNotFound, because an object with this memory address
+ // was found in the iLeakArray array. If the index is out of range, something is
+ // badly wrong, so it would be alright to panic in that case.
+ if ( index == KErrNotFound )
+ {
+ PanicClient( EAToolInternalError, aMessage );
+ return KErrCancel;
+ }
+
+ // Decrease the current alloc size and remove the requested allocation
+ // from iAllocInfoArray
+ iCurAllocSize -= iAllocInfoArray[index].iAllocSize;
+ iAllocInfoArray.Remove( index );
+
+ // If we are here, everything has gone alright
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::IsMemoryAdded()
+// Check a memory allocation (memory address) from an internal array.
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::IsMemoryAdded( const RMessage2& aMessage,
+ const TBool aRemoveAlloc )
+ {
+ LOGSTR1( "STSE TInt CATStorageServerSession::IsMemoryAdded()" );
+
+ // Panic the client and return, if a logging session is not ongoing
+ // ( can be started by calling the client's LogProcessStarted() )
+ if ( !iLoggingOngoing )
+ {
+ PanicClient( EAToolNotAllowed, aMessage );
+ return KErrCancel;
+ }
+
+ // Read the first argument (index 0)
+ TUint32 memAddress = aMessage.Int0();
+
+ // Try to find this memory allocation from the allocation info array
+
+ // Make a TAllocInfo object for a "find" operation
+ TAllocInfo allocInfo( memAddress, 0 );
+ TInt index( iAllocInfoArray.FindInUnsignedKeyOrder( allocInfo ) );
+
+ if ( index == KErrNotFound )
+ {
+ return index;
+ }
+ else if ( aRemoveAlloc )
+ {
+ // Otherwise decrease the current alloc size and remove the requested allocation
+ // from iAllocInfoArray
+ iCurAllocSize -= iAllocInfoArray[index].iAllocSize;
+ iAllocInfoArray.Remove( index );
+ }
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::LogMemoryFreedTraceL()
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::LogMemoryFreedTraceL( const RMessage2& aMessage )
+ {
+ LOGSTR1( "STSE TInt CATStorageServerSession::LogMemoryFreedTraceL()" );
+
+ // Panic the client and return, if a logging session is not ongoing
+ // ( can be started by calling the client's LogProcessStarted() )
+ if ( !iLoggingOngoing )
+ {
+ PanicClient( EAToolNotAllowed, aMessage );
+ return KErrCancel;
+ }
+
+ // A pointer to a buffer of call stack's memory addresses
+ CBufFlat* stackBuf = NULL;
+ iError = KErrNone;
+
+ // Read the first argument (index 0)
+ TUint32 memAddress = aMessage.Int0();
+
+ // Remove address from allocation table and its size from alloc size,
+ // if found from table.
+ TAllocInfo allocInfo( memAddress, 0 ); // Dummy info for search.
+ TInt index( iAllocInfoArray.FindInUnsignedKeyOrder( allocInfo ) );
+ if ( index != KErrNotFound )
+ {
+ // Decrease the current alloc size and remove the requested allocation
+ // from table.
+ iCurAllocSize -= iAllocInfoArray[index].iAllocSize;
+ iAllocInfoArray.Remove( index );
+ }
+ else
+ {
+ LOGSTR2( "STSE TInt CATStorageServerSession::LogMemoryFreedTrace() Error, cannot find alloc for free: %i", memAddress );
+ }
+
+ // Read the length of the descriptor argument (index 1) that should include
+ // call stack memory addresses associated with this memory allocation
+ TInt bufferLength = aMessage.GetDesLength( 1 );
+
+ // Construct a buffer for aCallstack
+ stackBuf = CBufFlat::NewL( bufferLength );
+ CleanupStack::PushL( stackBuf );
+
+ // Buffer position
+ TInt pos = 0;
+
+ stackBuf->ExpandL( pos, bufferLength );
+
+ TPtr8 bufPtr = stackBuf->Ptr( pos );
+
+ // Read the descriptor argument (index 1) into the buffer
+ aMessage.ReadL( 1, bufPtr );
+
+ // Variable for the number of memory addresses in the call stack
+ TInt addrCount( 0 );
+ TUint32 callStackAddr( 0 );
+
+ // Read the first word of the buffer. This includes the number of
+ // memory addresses stored in the current stackBuf
+ stackBuf->Read( pos, &addrCount, KWordSize );
+
+ // Move the position one word onwards.
+ pos += KWordSize;
+
+ // Create a 16-bit buffer, and a pointer descriptor for it
+ HBufC* traceBuf = HBufC::NewL( KMemFreedBufLength );
+ TPtr tracePtr( traceBuf->Des() );
+
+ // Pop stackBuf from CleanupStack, since no leavable operations will be done
+ // anymore
+ CleanupStack::Pop( stackBuf );
+
+ // Get the current universal time
+ TInt64 timeFrom1970( GetTime() );
+
+ // Memory deallocation header message.
+ // FREEH <Memory address> <Time stamp> <Call stack address count> <Call stack address>
+ // <Call stack address> ...
+
+ // Append the tag implying a memory free line in the data file
+ tracePtr.Append( KMemoryFreedHeader );
+
+ // Append the start address of this allocation in the 32-bit (max 8 characters)
+ // hexadecimal text format.
+ tracePtr.AppendNum( memAddress, EHex );
+
+ // Append the current time in the 64-bit (max 16 characters) hexadecimal text
+ // format
+ tracePtr.Append( KSpaceTrace );
+ tracePtr.AppendNum( timeFrom1970, EHex );
+
+ // Append call stack address count
+ tracePtr.Append( KSpaceTrace );
+ tracePtr.AppendNum( addrCount, EHex );
+
+ // Packet number
+ TUint packetNumber( 1 );
+
+ // Calculate last item length
+ TInt lastItemLength( KTraceMessage().Length() + KHexa32Length +
+ KSpaceLength + KNewlineLength );
+
+ // Go through all call stack's memory addresses associated with
+ // this memory allocation
+ for ( TInt j = 0; j < addrCount; j++ )
+ {
+ if ( tracePtr.Length() <= 0 )
+ {
+ // Memory deallocation fragment message.
+ // FREEF <Memory address> <Time stamp> <Packet number> <Call stack address count>
+ // <Call stack address>...
+ // Create free fragment message header
+ tracePtr.Append( KMemoryFreedFragment );
+ tracePtr.AppendNum( memAddress, EHex );
+ tracePtr.Append( KSpaceTrace );
+ tracePtr.AppendNum( timeFrom1970, EHex );
+ tracePtr.Append( KSpaceTrace );
+ tracePtr.AppendNum( packetNumber, EHex );
+ // Increase packet number
+ packetNumber++;
+ }
+
+ // Read the next call stack's memory address stored in the buffer.
+ stackBuf->Read( pos, &callStackAddr, KWordSize );
+
+ // Append the read memory address as a hexadecimal number
+ tracePtr.AppendFormat( KHexaNumberTrace, callStackAddr );
+
+ // Move the pos variable one word onwards.
+ pos += KWordSize;
+
+ // Check if buffer max length exceed
+ if ( lastItemLength + tracePtr.Length() >= KMemFreedBufLength )
+ {
+ tracePtr.Append( KNewLineTrace );
+ // Log through debug channel
+ RDebug::Print( KTraceMessage, iProcessId, traceBuf );
+ // Empty trace buffer
+ tracePtr.Delete( 0, tracePtr.MaxLength() );
+ }
+ }
+
+ // Send the last message if exists
+ if ( tracePtr.Length() > 0 )
+ {
+ tracePtr.Append( KNewLineTrace );
+
+ // Log through debug channel
+ RDebug::Print( KTraceMessage, iProcessId, traceBuf );
+ }
+
+ delete traceBuf;
+ delete stackBuf;
+ // If we are here, everything has gone alright
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::LogProcessEndedL()
+// Prints memory leaks and information on process end into a file opened by the
+// function LogProcessStartedL()
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::LogProcessEndedL( const RMessage2& aMessage )
+ {
+ LOGSTR1( "STSE TInt CATStorageServerSession::LogProcessEndedL()" );
+
+ // Panic the client and return, if a logging session is not ongoing
+ // ( can be started by calling the client's LogProcessStarted() )
+ if ( !iLoggingOngoing )
+ {
+ PanicClient( EAToolNotAllowed, aMessage );
+ return KErrCancel;
+ }
+
+ iError = KErrNone;
+
+ // Read the sent process ID
+ TUint processId = aMessage.Int0();
+
+ // The process ID got from the client should equal iProcessId.
+ // If it does not, return KErrNotSupported
+ if ( processId != iProcessId )
+ {
+ return KErrNotSupported;
+ }
+
+ //////////////////////////////////////////////
+ // Log memory leaks
+ //////////////////////////////////////////////
+
+ // Print the information on the memory allocations that were never freed
+ iError = PrintLeaksL( aMessage );
+
+ if ( iError != KErrNone )
+ {
+ return iError;
+ }
+
+ //////////////////////////////////////////////
+ // Log handle leaks
+ //////////////////////////////////////////////
+
+ TUint handleLeakCount = aMessage.Int1();
+
+ if( handleLeakCount == 0 )
+ {
+ LOGSTR1( "STSE TInt CATStorageServerSession::LogProcessEndedL() No handle leaks to report" );
+ }
+ else
+ {
+ // Make a buffer that will be logged
+ TBuf8<KHandleLeakBufLength> loggingBuf;
+
+ // Set handle leak module name to unknown since it can not be defined.
+ // Write the handle leak count from aMessage.
+ loggingBuf.Format( KHandleLeak, &KUnknownModule, handleLeakCount );
+
+ // Write the constructed string into the data file and return if error
+ iError = iFile.Write( loggingBuf );
+
+ if ( iError != KErrNone )
+ {
+ return iError;
+ }
+ }
+
+ //////////////////////////////////////////////
+ // Log process end
+ //////////////////////////////////////////////
+
+ // Make a buffer that will be logged into the opened logging file
+ TBufC8<KProcessEndBufLength> processEndBuf;
+
+ TPtr8 bufPtr = processEndBuf.Des();
+
+ bufPtr.AppendFormat( KProcessEnd, iProcessId );
+
+ // Get the current universal time
+ TInt64 timeFrom1970( GetTime() );
+
+ // Append the current time in the 64-bit (max 16 characters) hexadecimal text
+ // format
+ bufPtr.AppendNum( timeFrom1970, EHex );
+
+ // Append a new line
+ bufPtr.Append( KNewLine );
+
+ // Write the buffer into a file and return the error code
+ iError = iFile.Write( processEndBuf );
+
+ // Close the file and the handle to the file server
+ CloseFsAndFile();
+
+ // Remove the process from the server's array of processes
+ iError = iStorageServer.RemoveProcessL( processId );
+
+ // Reset iProcesssId and set the logging flag false
+ iProcessId = KNullProcessId;
+ iLoggingOngoing = EFalse;
+
+ return iError;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::LogProcessEndTraceL()
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::LogProcessEndTraceL( const RMessage2& aMessage )
+ {
+ LOGSTR1( "STSE TInt CATStorageServerSession::LogProcessEndTraceL()" );
+
+ // Panic the client and return, if a logging session is not ongoing
+ // ( can be started by calling the client's LogProcessStarted() )
+ if ( !iLoggingOngoing )
+ {
+ PanicClient( EAToolNotAllowed, aMessage );
+ return KErrCancel;
+ }
+
+ iError = KErrNone;
+
+ // Read the sent process ID
+ TUint processId = aMessage.Int0();
+
+ // The process ID got from the client should equal iProcessId.
+ // If it does not, return KErrNotSupported
+ if ( processId != iProcessId )
+ {
+ return KErrNotSupported;
+ }
+
+ //////////////////////////////////////////////
+ // Log handle leaks
+ //////////////////////////////////////////////
+
+ TUint handleLeakCount = aMessage.Int1();
+
+ if( handleLeakCount == 0 )
+ {
+ LOGSTR1( "STSE TInt CATStorageServerSession::LogProcessEndTraceL() No handle leaks to report" );
+ }
+ else
+ {
+ // Make a buffer that will be logged
+ TBuf8<KHandleLeakBufLength> loggingBuf;
+
+ // Make a 16-bit buffer that can be logged using RDebug
+ TBuf<KHandleLeakBufLength> traceBuf;
+
+ // Set handle leak module name to unknown since it can not be defined.
+ // Write the handle leak count from aMessage.
+ loggingBuf.Format( KHandleLeak, &KUnknownModule, handleLeakCount );
+
+ traceBuf.Copy( loggingBuf );
+
+ // Log through debug channel
+ RDebug::Print( KTraceMessage, iProcessId , &traceBuf );
+ }
+
+ //////////////////////////////////////////////
+ // Log process end
+ //////////////////////////////////////////////
+
+ // Make a buffer that will be logged
+ TBuf<KProcessEndBufLength> processEndBuf;
+ processEndBuf.AppendFormat( KProcessEndTrace, iProcessId );
+
+ // Get the current universal time
+ TInt64 timeFrom1970( GetTime() );
+
+ // Append the current time in the 64-bit (max 16 characters) hexadecimal text
+ // format
+ processEndBuf.AppendNum( timeFrom1970, EHex );
+
+ // Append a new line
+ processEndBuf.Append( KNewLineTrace );
+
+ // Log through debug channel
+ RDebug::Print( KTraceMessage, iProcessId, &processEndBuf );
+
+ // Remove the process from the server's array of processes
+ iError = iStorageServer.RemoveProcessL( iProcessId );
+
+ // Reset iProcesssId and set the logging flag false
+ iProcessId = KNullProcessId;
+ iLoggingOngoing = EFalse;
+
+ return iError;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::CheckMemoryAddressL()
+// Checks if given memory address can be found
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::CheckMemoryAddressL( const RMessage2& aMessage )
+ {
+ LOGSTR1( "STSE TInt CATStorageServerSession::CheckMemoryAddressL()" );
+
+ // Panic the client and return, if a logging session is not ongoing
+ // ( can be started by calling the client's LogProcessStarted() )
+ if ( !iLoggingOngoing )
+ {
+ PanicClient( EAToolNotAllowed, aMessage );
+ return KErrCancel;
+ }
+
+ iError = KErrNone;
+
+ // Check if memory address can be found in iLeakArray
+ TUint32 memAddress = aMessage.Int0();
+ TIdentityRelation<CATMemoryEntry> matcher( CATMemoryEntry::Match );
+ CATMemoryEntry* entry = new (ELeave) CATMemoryEntry( memAddress, NULL, 0, 0 );
+
+ // Get the index or an error code
+ iError = iLeakArray.Find( entry, matcher );
+ delete entry;
+
+ return iError;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::CheckMemoryAddressTrace()
+// Checks if some memory address can be found
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::CheckMemoryAddressTrace( const RMessage2& aMessage )
+ {
+ LOGSTR1( "STSE TInt CATStorageServerSession::CheckMemoryAddressTrace()" );
+
+ // Panic the client and return, if a logging session is not ongoing
+ // ( can be started by calling the client's LogProcessStarted() )
+ if ( !iLoggingOngoing )
+ {
+ PanicClient( EAToolNotAllowed, aMessage );
+ return KErrCancel;
+ }
+
+ // Always return KErrNone in this mode
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::GetProcessesL()
+// Checks if some memory address can be found
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::GetProcessesL( const RMessage2& aMessage )
+ {
+ LOGSTR1( "STSE TInt CATStorageServerSession::GetProcessesL()" );
+
+ iError = KErrNone;
+
+ TInt processInfoSize = sizeof( TATProcessInfo );
+
+ CBufFlat* processInfoBuf;
+
+ // Buffer position
+ TInt pos( 0 );
+
+ // Calculate the length of the buffer to be constructed for processes
+ // One word will be reserved for the length of the array.
+ TInt bufferLength = KWordSize + KATMaxProcesses * processInfoSize;
+
+ // Construct processInfoBuf and expand it before the beginning (index 0)
+ processInfoBuf = CBufFlat::NewL( bufferLength );
+ CleanupStack::PushL( processInfoBuf );
+ processInfoBuf->ExpandL( pos, bufferLength );
+
+ RArray<TATProcessInfo> processArray = iStorageServer.ProcessInfoArray();
+
+ // Variable for the number of TATProcessInfo objects in processArray
+ TInt count = processArray.Count();
+
+ // The count cannot be greater than KATMaxProcesses, because the client
+ // has reserved a buffer of this size to be filled by the server
+ if ( count > KATMaxProcesses )
+ {
+ count = KATMaxProcesses;
+ }
+
+ // Write the count (4 bytes) into the beginning of processInfoBuf
+ processInfoBuf->Write( pos, &count, KWordSize );
+
+ // Move the position one word onwards.
+ pos += KWordSize;
+
+ // Write all the process info objects into the buffer
+ for ( TInt i = 0; i < count; i++ )
+ {
+ TATProcessInfo& processInfo = processArray[i];
+
+ // Write the current process info into the buffer
+ processInfoBuf->Write( pos, &processInfo, processInfoSize );
+
+ // Move the pos variable onwards.
+ pos += processInfoSize;
+ }
+
+ // Make a pointer descriptor pointing to the start of processInfoBuf
+ TPtr8 bufPtr( processInfoBuf->Ptr(0) );
+
+ // Write the buffer into aMessage at index 0 for the client
+ aMessage.WriteL( 0, bufPtr );
+
+ CleanupStack::PopAndDestroy( processInfoBuf );
+
+ return iError;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::GetDllsL()
+// Checks if some memory address can be found
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::GetDllsL( const RMessage2& aMessage )
+ {
+ LOGSTR1( "STSE TInt CATStorageServerSession::GetDllsL()" );
+
+ // Read the process ID at index 0
+ TUint processId = aMessage.Int0();
+
+ // Size of a DLL descriptor
+ TInt sizeOfDllDesc = sizeof( TBuf8<KMaxLibraryName> );
+
+ // Buffer position
+ TInt pos( 0 );
+
+ // Calculate the length of the buffer to be constructed for DLL names.
+ // One word will be reserved for the length of the array.
+ TInt bufferLength = KWordSize + KATMaxDlls * sizeOfDllDesc;
+
+ CBufFlat* dllBuf;
+ // Construct dllBuf and expand it before the beginning (index 0)
+ dllBuf = CBufFlat::NewL( bufferLength );
+ CleanupStack::PushL( dllBuf );
+ dllBuf->ExpandL( pos, bufferLength );
+
+ RPointerArray<CATDynProcessInfo> dynProcessArray =
+ iStorageServer.DynProcessInfoArray();
+
+ // Construct a CATDynProcessInfo object with the given process ID for searching
+ CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId );
+
+ // Find the index of a CATDynProcessInfo object with the given process ID
+ TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
+ TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order );
+ delete dynProcessInfo;
+ dynProcessInfo = NULL;
+
+ // Return, if a process with the requested process ID was not found
+ if ( index == KErrNotFound )
+ {
+ CleanupStack::PopAndDestroy( dllBuf );
+ return index;
+ }
+
+ // Get the wanted dynamic process info
+ dynProcessInfo = dynProcessArray[index];
+
+ // Fetch a reference to the desired DLL array
+ RArray<TATDllInfo>& dllArray = dynProcessInfo->iDlls;
+
+ // Take the count of names in the array
+ TInt count = dllArray.Count();
+
+ // The count cannot be greater than KATMaxDlls, because the client
+ // has reserved a buffer of this size to be filled by the server
+ if ( count > KATMaxDlls )
+ {
+ count = KATMaxDlls;
+ }
+
+ // Write the count (4 bytes) into the beginning of dllBuf
+ dllBuf->Write( pos, &count, KWordSize );
+
+ // Move the position one word onwards.
+ pos += KWordSize;
+
+ // Go through all DLL names objects sent to the server
+ for ( TInt i = 0; i < count; i++ )
+ {
+ TBuf8<KMaxLibraryName>& dllName = dllArray[i].iName;
+
+ // Write the current DLL name into the buffer
+ dllBuf->Write( pos, &dllName, sizeOfDllDesc );
+
+ // Move the pos variable onwards.
+ pos += sizeOfDllDesc;
+ }
+
+ // Make a pointer descriptor pointing to the start of dllBuf
+ TPtr8 bufPtr( dllBuf->Ptr(0) );
+
+ // Write the whole buffer into aMessage at index 1 for the client
+ aMessage.WriteL( 1, bufPtr );
+
+ CleanupStack::PopAndDestroy( dllBuf );
+
+ // The dynProcessInfo object will not be deleted, because it is still owned by the
+ // server object's dynamic process info array.
+ dynProcessInfo = NULL;
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::GetLoggingModeL()
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::GetLoggingModeL( const RMessage2& aMessage )
+ {
+ LOGSTR1( "STSE TInt CATStorageServerSession::GetLoggingModeL()" );
+
+ iError = KErrNone;
+
+ // Read the process ID at index 0
+ TUint processId = aMessage.Int0();
+
+ // Buffer position
+ TInt pos( 0 );
+
+ // The length of the buffer to be constructed for logging mode
+ TInt bufferLength = KWordSize;
+
+ // Get the dynamic process info array
+ RPointerArray<CATDynProcessInfo> dynProcessArray =
+ iStorageServer.DynProcessInfoArray();
+
+ // Construct a CATDynProcessInfo object with the given process ID for searching
+ CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId );
+
+ // Find the index of a CATDynProcessInfo object with the given process ID
+ TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
+ TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order );
+ delete dynProcessInfo;
+ dynProcessInfo = NULL;
+
+ // Return, if a process with the requested process ID was not found
+ if ( index == KErrNotFound )
+ {
+ return index;
+ }
+
+ // Otherwise get the wanted dynamic process info
+ dynProcessInfo = dynProcessArray[index];
+
+ // Get the desired process's associated session object
+ CATStorageServerSession* sessionObject = dynProcessInfo->iSessionObject;
+ CBufFlat* loggingModeBuf;
+ // Construct allocInfoBuf and expand it before the beginning (index 0)
+ loggingModeBuf = CBufFlat::NewL( bufferLength );
+ CleanupStack::PushL( loggingModeBuf );
+ loggingModeBuf->ExpandL( 0, bufferLength );
+
+ // Write the current logging mode of the requested process into the buffer.
+ loggingModeBuf->Write( pos, &sessionObject->iLogOption, KWordSize );
+
+ // Make a pointer descriptor that points to the data of allocInfoBuf
+ TPtr8 bufPtr( loggingModeBuf->Ptr(0) );
+
+ // Write the whole buffer into aMessage at index 1 for the client
+ aMessage.WriteL( 1, bufPtr );
+
+ CleanupStack::PopAndDestroy( loggingModeBuf );
+
+ return iError;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::StartSubtestL()
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::StartSubtestL( const RMessage2& aMessage )
+ {
+ LOGSTR1( "STSE TInt CATStorageServerSession::StartSubtestL()" );
+
+ iError = KErrNone;
+
+ // Read the process ID at index 0
+ TUint processId = aMessage.Int0();
+
+ // Read the sub test ID at index 1
+ TBuf8<KATMaxSubtestIdLength> subTestName;
+ iError = aMessage.Read( 1, subTestName );
+
+ // Return if reading was not successful
+ if ( iError != KErrNone )
+ {
+ return iError;
+ }
+
+ // Create another (non-8-bit) descriptor for logging to trace
+ // and copy the contents
+ TBuf<KATMaxSubtestIdLength> subTestNameTrace;
+ subTestNameTrace.Copy( subTestName );
+
+ // Read the handle count at index 2
+ TInt handleCount = aMessage.Int2();
+
+ // FIND THE REQUESTED PROCESS
+
+ // Get the dynamic process array
+ RPointerArray<CATDynProcessInfo> dynProcessArray =
+ iStorageServer.DynProcessInfoArray();
+
+ // Construct a CATDynProcessInfo object with the given process ID for searching
+ CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId );
+
+ // Find the index of a CATDynProcessInfo object with the given process ID
+ TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
+ TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order );
+ delete dynProcessInfo;
+ dynProcessInfo = NULL;
+
+ // Return, if a process with the requested process ID was not found
+ if ( index == KErrNotFound )
+ {
+ return index;
+ }
+
+ // Get the wanted dynamic process info
+ dynProcessInfo = dynProcessArray[index];
+
+ // Get the desired process's associated session object
+ const CATStorageServerSession* sessionObject = dynProcessInfo->iSessionObject;
+
+ // Make a buffer for logging thru trace
+ TBuf<KTestStartBufLength> loggingBuf;
+
+ // Copy the line tag into the buffer
+ loggingBuf.Copy( KSubtestStart );
+
+ // Get the current universal time
+ TInt64 timeFrom1970( GetTime() );
+
+ // Append the current time in the 64-bit (max 16 characters) hexadecimal text
+ // format
+ loggingBuf.AppendNum( timeFrom1970, EHex );
+
+ // Append a space
+ loggingBuf.Append( KSpaceTrace );
+
+ // Append the sub test ID
+ loggingBuf.Append( subTestNameTrace );
+
+ // Append a space
+ loggingBuf.Append( KSpaceTrace );
+
+ // Append current handle leak count
+ loggingBuf.AppendNum( handleCount );
+
+ // Append a new line
+ loggingBuf.Append( KNewLineTrace );
+
+ // Log the string through trace
+ iError = sessionObject->LogThroughTrace( loggingBuf );
+
+ // *******************
+ // Send loaded DLL's
+ // *******************
+
+ // Fetch a reference to the desired DLL array
+ RArray<TATDllInfo>& dllArray = dynProcessInfo->iDlls;
+
+ // Take the count of dll info items
+ TInt count( dllArray.Count() );
+ LOGSTR2( "STSE > dllArray.Count( %i )", count );
+
+ // Create buffers
+ TBuf<KDllLoadBufLength> traceBuf;
+ TBuf8<KDllLoadBufLength> dllBuf;
+
+ for ( TInt x = 0; x < count; x++ )
+ {
+ dllBuf.Format( KDllLoad, &dllArray[x].iName, dllArray[x].iLoadTime,
+ dllArray[x].iStartAddress, dllArray[x].iEndAddress );
+ traceBuf.Copy( dllBuf );
+
+ // Log the string through trace
+ iError = sessionObject->LogThroughTrace( traceBuf );
+ if ( iError != KErrNone )
+ {
+ LOGSTR2( "STSE > LogThroughTrace() err( %i )", iError );
+ }
+ }
+ sessionObject = NULL;
+
+ return iError;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::StopSubtestL()
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::StopSubtestL( const RMessage2& aMessage )
+ {
+ LOGSTR1( "STSE TInt CATStorageServerSession::StopSubtestL()" );
+
+ iError = KErrNone;
+
+ // Read the process ID at index 0
+ TUint processId = aMessage.Int0();
+
+ // Read the sub test ID at index 1
+ TBuf8<KATMaxSubtestIdLength> subTestName;
+ iError = aMessage.Read( 1, subTestName );
+
+ // Return if reading was not successful
+ if ( iError != KErrNone )
+ {
+ return iError;
+ }
+
+ // Create another (non-8-bit) descriptor for logging to trace,
+ // and copy the contents
+ TBuf<KATMaxSubtestIdLength> subTestNameTrace;
+ subTestNameTrace.Copy( subTestName );
+
+ // Read the handle count at index 2
+ TInt handleCount = aMessage.Int2();
+
+ // FIND THE REQUESTED PROCESS
+
+ // Get the dynamic process array
+ RPointerArray<CATDynProcessInfo> dynProcessArray =
+ iStorageServer.DynProcessInfoArray();
+
+ // Construct a CATDynProcessInfo object with the given process ID for searching
+ CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId );
+
+ // Find the index of a CATDynProcessInfo object with the given process ID
+ TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
+ TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order );
+ delete dynProcessInfo;
+ dynProcessInfo = NULL;
+
+ // Return, if a process with the requested process ID was not found
+ if ( index == KErrNotFound )
+ {
+ return index;
+ }
+
+ // Get the wanted dynamic process info
+ dynProcessInfo = dynProcessArray[index];
+
+ // Get the desired process's associated session object
+ const CATStorageServerSession* sessionObject = dynProcessInfo->iSessionObject;
+
+ // Make a buffer for logging thru trace
+ TBuf<KTestEndBufLength> loggingBuf;
+
+ // Copy the line tag into the buffer
+ loggingBuf.Copy( KSubtestEnd );
+
+ // Get the current universal time
+ TInt64 timeFrom1970( GetTime() );
+
+ // Append the current time in the 64-bit (max 16 characters) hexadecimal text
+ // format
+ loggingBuf.AppendNum( timeFrom1970, EHex );
+
+ // Append a space
+ loggingBuf.Append( KSpaceTrace );
+
+ // Append the sub test ID
+ loggingBuf.Append( subTestNameTrace );
+
+ // Append a space
+ loggingBuf.Append( KSpaceTrace );
+
+ // Append current handle leak count
+ loggingBuf.AppendNum( handleCount );
+
+ // Append a new line
+ loggingBuf.Append( KNewLineTrace );
+
+ // Log the string through trace
+ iError = sessionObject->LogThroughTrace( loggingBuf );
+
+ sessionObject = NULL;
+
+ return iError;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::StartSubtest2L()
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::StartSubtest2L( const RMessage2& aMessage )
+ {
+ LOGSTR1( "STSE TInt CATStorageServerSession::StartSubtest2L()" );
+
+ iError = KErrNone;
+
+ // Read the sub test ID at index 0
+ TBuf8<KATMaxSubtestIdLength> subTestName;
+ iError = aMessage.Read( 0, subTestName );
+
+ // Return if reading was not successful
+ if ( iError != KErrNone )
+ {
+ return iError;
+ }
+
+ // Create another (non-8-bit) descriptor for logging to trace
+ // and copy the contents
+ TBuf<KATMaxSubtestIdLength> subTestNameTrace;
+ subTestNameTrace.Copy( subTestName );
+
+ // Make a buffer for logging thru trace
+ TBuf<KTestStartBufLength> loggingBuf;
+
+ // Copy the line tag into the buffer
+ loggingBuf.Copy( KSubtestStart );
+
+ // Get the current universal time
+ TInt64 timeFrom1970( GetTime() );
+
+ // Append the current time in the 64-bit (max 16 characters) hexadecimal text
+ // format
+ loggingBuf.AppendNum( timeFrom1970, EHex );
+
+ // Append a space
+ loggingBuf.Append( KSpaceTrace );
+
+ // Append the sub test ID
+ loggingBuf.Append( subTestNameTrace );
+
+ // Append a new line
+ loggingBuf.Append( KNewLineTrace );
+
+ // Log the string through trace
+ iError = LogThroughTrace( loggingBuf );
+
+ // *******************
+ // Send loaded DLL's
+ // *******************
+
+ // Get the dynamic process array
+ RPointerArray<CATDynProcessInfo> dynProcessArray =
+ iStorageServer.DynProcessInfoArray();
+
+ // Construct a CATDynProcessInfo object with the given process ID for searching
+ CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( iProcessId );
+
+ // Find the index of a CATDynProcessInfo object with the given process ID
+ TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
+ TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order );
+ delete dynProcessInfo;
+ dynProcessInfo = NULL;
+
+ // Return, if a process with the requested process ID was not found
+ if ( index == KErrNotFound )
+ {
+ return index;
+ }
+
+ // Get the wanted dynamic process info
+ dynProcessInfo = dynProcessArray[index];
+
+ // Fetch a reference to the desired DLL array
+ RArray<TATDllInfo>& dllArray = dynProcessInfo->iDlls;
+
+ // Take the count of dll info items
+ TInt count( dllArray.Count() );
+ LOGSTR2( "STSE > dllArray.Count( %i )", count );
+
+ // Create buffers
+ TBuf<KDllLoadBufLength> traceBuf;
+ TBuf8<KDllLoadBufLength> dllBuf;
+
+ for ( TInt x = 0; x < count; x++ )
+ {
+ dllBuf.Format( KDllLoad, &dllArray[x].iName, dllArray[x].iLoadTime,
+ dllArray[x].iStartAddress, dllArray[x].iEndAddress );
+ traceBuf.Copy( dllBuf );
+
+ // Log the string through trace
+ iError = LogThroughTrace( traceBuf );
+ if ( iError != KErrNone )
+ {
+ LOGSTR2( "STSE > LogThroughTrace() err( %i )", iError );
+ }
+ }
+
+ return iError;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::StopSubtest2()
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::StopSubtest2( const RMessage2& aMessage )
+ {
+ LOGSTR1( "STSE TInt CATStorageServerSession::StopSubtest2()" );
+
+ iError = KErrNone;
+
+ // Read the sub test ID at index 0
+ TBuf8<KATMaxSubtestIdLength> subTestName;
+ iError = aMessage.Read( 0, subTestName );
+
+ // Return if reading was not successful
+ if ( iError != KErrNone )
+ {
+ return iError;
+ }
+
+ // Create another (non-8-bit) descriptor for logging to trace,
+ // and copy the contents
+ TBuf<KATMaxSubtestIdLength> subTestNameTrace;
+ subTestNameTrace.Copy( subTestName );
+
+ // Make a buffer for logging thru trace
+ TBuf<KTestEndBufLength> loggingBuf;
+
+ // Copy the line tag into the buffer
+ loggingBuf.Copy( KSubtestEnd );
+
+ // Get the current universal time
+ TInt64 timeFrom1970( GetTime() );
+
+ // Append the current time in the 64-bit (max 16 characters) hexadecimal text
+ // format
+ loggingBuf.AppendNum( timeFrom1970, EHex );
+
+ // Append a space
+ loggingBuf.Append( KSpaceTrace );
+
+ // Append the sub test ID
+ loggingBuf.Append( subTestNameTrace );
+
+ // Append a new line
+ loggingBuf.Append( KNewLineTrace );
+
+ // Log the string through trace
+ iError = LogThroughTrace( loggingBuf );
+
+ return iError;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::GetCurrentAllocsL()
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::GetCurrentAllocsL( const RMessage2& aMessage )
+ {
+ LOGSTR1( "STSE TInt CATStorageServerSession::GetCurrentAllocsL()" );
+
+ iError = KErrNone;
+
+ // Read the process ID at index 0
+ TUint processId = aMessage.Int0();
+ TUint32 allocNumber( 0 );
+ TUint32 allocSize( 0 );
+
+ // Buffer position
+ TInt pos( 0 );
+
+ // The length of the buffer to be constructed for allocation number and size
+ TInt bufferLength = KWordSize + KWordSize;
+
+ // Get the dynamic process info array
+ RPointerArray<CATDynProcessInfo> dynProcessArray =
+ iStorageServer.DynProcessInfoArray();
+
+ // Construct a CATDynProcessInfo object with the given process ID for searching
+ CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId );
+
+ // Find the index of a CATDynProcessInfo object with the given process ID
+ TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
+ TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order );
+ delete dynProcessInfo;
+ dynProcessInfo = NULL;
+
+ // Return, if a process with the requested process ID was not found
+ if ( index == KErrNotFound )
+ {
+ return index;
+ }
+
+ // Otherwise get the wanted dynamic process info
+ dynProcessInfo = dynProcessArray[index];
+
+ // Get the desired process's associated session object
+ CATStorageServerSession* sessionObject = dynProcessInfo->iSessionObject;
+
+ // Get the alloc info array of that session object
+ RArray<TAllocInfo> allocInfo = sessionObject->AllocInfoArray();
+
+ // Get the values for current allocations number and size
+ allocNumber = allocInfo.Count();
+
+ // Calculate the total size of the current allocations
+ for ( TUint32 i = 0; i < allocNumber; i++ )
+ {
+ allocSize += allocInfo[i].iAllocSize;
+ }
+
+ LOGSTR2( "STSE allocSize: %u", allocSize );
+ LOGSTR2( "STSE iCurAllocSize: %u", iCurAllocSize );
+
+ CBufFlat* allocInfoBuf;
+ // Construct allocInfoBuf and expand it before the beginning (index 0)
+ allocInfoBuf = CBufFlat::NewL( bufferLength );
+ CleanupStack::PushL( allocInfoBuf );
+ allocInfoBuf->ExpandL( 0, bufferLength );
+
+ // Write the current number of allocations of the requested process into the buffer.
+ allocInfoBuf->Write( pos, &allocNumber, KWordSize );
+
+ // Move the position one word onwards
+ pos += KWordSize;
+
+ // Write the current total size of the allocations of the requested process into the
+ // buffer.
+ allocInfoBuf->Write( pos, &allocSize, KWordSize );
+
+ // Make a pointer descriptor that points to the data of allocInfoBuf
+ TPtr8 bufPtr( allocInfoBuf->Ptr(0) );
+
+ // Write the whole buffer into aMessage at index 1 for the client
+ aMessage.WriteL( 1, bufPtr );
+
+ CleanupStack::PopAndDestroy( allocInfoBuf );
+
+ return iError;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::GetMaxAllocsL()
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::GetMaxAllocsL( const RMessage2& aMessage )
+ {
+ LOGSTR1( "STSE TInt CATStorageServerSession::GetMaxAllocsL()" );
+
+ iError = KErrNone;
+
+ // Read the process ID at index 0
+ TUint processId = aMessage.Int0();
+ TUint32 allocNumber( 0 );
+ TUint32 allocSize( 0 );
+
+ // Buffer position
+ TInt pos( 0 );
+
+ // The length of the buffer to be constructed for allocation number and size
+ TInt bufferLength = KWordSize + KWordSize;
+
+ // Get the dynamic process info array
+ RPointerArray<CATDynProcessInfo> dynProcessArray =
+ iStorageServer.DynProcessInfoArray();
+
+ // Construct a CATDynProcessInfo object with the given process ID for searching
+ CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId );
+
+ // Find the index of a CATDynProcessInfo object with the given process ID
+ TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
+ TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order );
+ delete dynProcessInfo;
+ dynProcessInfo = NULL;
+
+ // Return, if a process with the requested process ID was not found
+ if ( index == KErrNotFound )
+ {
+ return index;
+ }
+
+ // Otherwise get the wanted dynamic process info
+ dynProcessInfo = dynProcessArray[index];
+
+ // Get the desired process's associated session object
+ CATStorageServerSession* sessionObject = dynProcessInfo->iSessionObject;
+
+ // Get values for the maximum allocations number and size
+ allocNumber = sessionObject->iMaxAllocs;
+ allocSize = sessionObject->iMaxAllocSize;
+
+ CBufFlat* allocInfoBuf;
+ // Construct allocInfoBuf and expand it before the beginning (index 0)
+ allocInfoBuf = CBufFlat::NewL( bufferLength );
+ CleanupStack::PushL( allocInfoBuf );
+ allocInfoBuf->ExpandL( 0, bufferLength );
+
+ // Write the maximum number of allocations of the requested process into the buffer.
+ allocInfoBuf->Write( pos, &allocNumber, KWordSize );
+
+ // Move the position one word onwards
+ pos += KWordSize;
+
+ // Write the maximum total size of the allocations of the requested process into the
+ // buffer.
+ allocInfoBuf->Write( pos, &allocSize, KWordSize );
+
+ // Make a pointer descriptor that points to the data of allocInfoBuf
+ TPtr8 bufPtr( allocInfoBuf->Ptr(0) );
+
+ // Write the whole buffer into aMessage at index 1 for the client
+ aMessage.WriteL( 1, bufPtr );
+
+ CleanupStack::PopAndDestroy( allocInfoBuf );
+
+ return iError;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::CancelLoggingL()
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::CancelLoggingL( const RMessage2& aMessage )
+ {
+ LOGSTR1( "STSE TInt CATStorageServerSession::CancelLoggingL()" );
+
+ iError = KErrNone;
+
+ // Read the process ID at index 0
+ TUint processId = aMessage.Int0();
+
+ // FIND THE REQUESTED PROCESS
+
+ // Get the dynamic process array
+ RPointerArray<CATDynProcessInfo> dynProcessArray =
+ iStorageServer.DynProcessInfoArray();
+
+ // Construct a CATDynProcessInfo object with the given process ID for searching
+ CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId );
+
+ // Find the index of a CATDynProcessInfo object with the given process ID
+ TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
+ TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order );
+ delete dynProcessInfo;
+ dynProcessInfo = NULL;
+
+ // Return, if a process with the requested process ID was not found
+ if ( index == KErrNotFound )
+ {
+ return index;
+ }
+
+ // Otherwise get the wanted dynamic process info
+ dynProcessInfo = dynProcessArray[index];
+
+ // Get the session object of the requested process
+ CATStorageServerSession* sessionObject = dynProcessInfo->iSessionObject;
+
+ // Get the current universal time
+ TInt64 timeFrom1970( GetTime() );
+
+ // Make a buffer for logging "logging cancelled"
+ TBuf8<KCancelBufLength> loggingBuf;
+
+ // Copy the "logging cancelled" tag into the buffer with the current time
+ loggingBuf.AppendFormat( KLoggingCancelled, timeFrom1970 );
+
+ // Log the buffer eather to a file or to debug channel depending on the current
+ // logging mode
+
+ if ( sessionObject->iLoggingOngoing &&
+ sessionObject->iLogOption == EATLogToFile )
+ {
+ // Write the buffer into the file
+ sessionObject->iFile.Write( loggingBuf );
+ }
+
+ else if ( sessionObject->iLoggingOngoing &&
+ sessionObject->iLogOption == EATLogToTrace )
+ {
+ // Make a buffer for logging to trace
+ TBuf<KCancelBufLength> traceBuf;
+ traceBuf.Copy( loggingBuf );
+
+ // Write the buffer into the debug channel
+ RDebug::Print( KTraceMessage, processId ,&traceBuf );
+ }
+
+ // Switch off logging of the requested process
+ sessionObject->iLogOption = EATLoggingOff;
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::HandleError
+// Internally used for handling error situations.
+// -----------------------------------------------------------------------------
+//
+void CATStorageServerSession::HandleError( TInt aError )
+ {
+ LOGSTR1( "STSE void CATStorageServerSession::HandleError()" );
+
+ // Get the current universal time
+ TInt64 timeFrom1970( GetTime() );
+
+ // Make a buffer that will be logged into the opened logging file
+ TBufC8<KErrOccuredBufLength> loggingBuf;
+
+ TPtr8 bufPtr( loggingBuf.Des() );
+
+ // Write the error code to the buffer
+ bufPtr.Format( KErrorOccured, aError );
+
+ // Append the current time in the 64-bit (max 16 characters) hexadecimal text
+ // format
+ bufPtr.AppendNum( timeFrom1970, EHex );
+
+ // Append a new line
+ bufPtr.Append( KNewLine );
+
+ // Write the buffer into a file (if possible in the current condition)
+ iFile.Write( loggingBuf );
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::HandleErrorTrace()
+// Internally used for handling error situations.
+// -----------------------------------------------------------------------------
+//
+void CATStorageServerSession::HandleErrorTrace( TInt aError )
+ {
+ LOGSTR1( "STSE void CATStorageServerSession::HandleErrorTrace()" );
+
+ // Get the current universal time
+ TInt64 timeFrom1970( GetTime() );
+
+ // Make a buffer that will be logged
+ TBuf<KErrOccuredBufLength> traceBuf;
+
+ // Write the error code to the buffer
+ traceBuf.Format( KErrorOccuredTrace, aError );
+
+ // Append the current time in the 64-bit (max 16 characters) hexadecimal text
+ // format
+ traceBuf.AppendNum( timeFrom1970, EHex );
+
+ // Append a new line
+ traceBuf.Append( KNewLineTrace );
+
+ RDebug::Print( KTraceMessage, iProcessId , &traceBuf );
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::OpenFsAndFile
+// Internally used for opening a handle to the file server and a file
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::OpenFsAndFile( const TDesC& aFileName,
+ const TDesC8& aProcessName )
+ {
+ LOGSTR1( "STSE TInt CATStorageServerSession::OpenFsAndFile()" );
+
+ // Connect file server, return if error occured
+ iError = iFileServer.Connect();
+ if ( iError )
+ {
+ iFileServer.Close();
+ return iError;
+ }
+
+ // Open a file
+ TBuf<KMaxFileName> fileNameBuf;
+ iError = TATDriveInfo::CreatePath( fileNameBuf, aFileName, iFileServer );
+
+ // Return, if an error occured, and it
+ // is not KErrAlreadyExists
+ if ( iError && iError != KErrAlreadyExists )
+ {
+ iFileServer.Close();
+ return iError;
+ }
+
+ // Save the file name for this session
+ CnvUtfConverter::ConvertFromUnicodeToUtf8( iLogFile, fileNameBuf );
+
+ // Try to open file
+ CheckIfFileAlreadyExist( fileNameBuf );
+
+ // If a data file with the requested name already existed, and was opened
+ // successfully, check the version of the file. If the line telling the version of
+ // the file is not the expected, replace the file
+ // If cannot open the file(error is KErrInUse), generate new filename and
+ // then try to create new file.
+ if ( iError == KErrNone )
+ {
+ CheckFileVersion( fileNameBuf );
+ }
+ else if ( iError == KErrInUse )
+ {
+ GenerateNewFileName( fileNameBuf, aProcessName );
+
+ // Save the file name for this session
+ CnvUtfConverter::ConvertFromUnicodeToUtf8( iLogFile, fileNameBuf );
+ }
+ LOGSTR2( "STSE > iError(%i)", iError );
+
+ // If the file does not exist, create it. Write also the version number of
+ // the file at the beginning of the new file
+ if ( iError == KErrNotFound )
+ {
+ iError = iFile.Create( iFileServer, fileNameBuf, EFileWrite );
+
+ if ( !iError )
+ {
+ iError = iFile.Write( KDataFileVersion );
+ }
+ }
+
+ if ( iError )
+ {
+ iFile.Close();
+ iFileServer.Close();
+ return iError;
+ }
+
+ // Seek the end of the file and set the current file position there
+ TInt offset = 0;
+ iError = iFile.Seek( ESeekEnd, offset );
+
+ return iError;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::GenerateNewFileName
+// Called internally when need generate new file name.
+// -----------------------------------------------------------------------------
+//
+void CATStorageServerSession::GenerateNewFileName( TDes& aFileName,
+ const TDesC8& aProcessName )
+ {
+ LOGSTR1( "STSE void CATStorageServerSession::GenerateNewFileName()" );
+
+ // Extension
+ TBuf<KExtensionLength> extension;
+
+ // Parse file extension
+ ParseExtension( aFileName, extension );
+
+ // Try to find UID3 from current process name
+ TInt uidErr( KErrBadName );
+ TBuf<KMaxFileName> unicodeFile;
+
+ // Converts text encoded using the Unicode transformation format UTF-8
+ // into the Unicode UCS-2 character set.
+ CnvUtfConverter::ConvertToUnicodeFromUtf8( unicodeFile, aProcessName );
+ LOGSTR2( "STSE > unicodeFile(%S)", &unicodeFile );
+
+ // Find square brackets
+ TInt sPos( unicodeFile.Find( KOpenSquareBracket ) );
+ TInt ePos( unicodeFile.Find( KCloseSquareBracket ) );
+ LOGSTR3( "STSE > sPos(%i), ePos(%i)", sPos, ePos );
+
+ if ( sPos != KErrNotFound && ePos != KErrNotFound )
+ {
+ TBuf<KProcessUidLength> processUid;
+ TInt pEnd( ePos - sPos - KOpenSquareBracket().Length() );
+ LOGSTR2( "STSE > pEnd(%i)", pEnd );
+
+ // Copy UID value
+ if ( pEnd > 0 )
+ {
+ processUid.Copy( unicodeFile.Mid(
+ sPos + KOpenSquareBracket().Length(), pEnd ) );
+ LOGSTR2( "STSE > processUid(%S)", &processUid );
+ }
+
+ if ( aFileName.Find( processUid ) == KErrNotFound )
+ {
+ // UID not exist, create new filename
+ // Append uid to filename (<file name>_<uid>.<extension>)
+ aFileName.Append( KUnderLine );
+ aFileName.Append( processUid );
+ aFileName.Append( extension );
+ // Try to open file
+ CheckIfFileAlreadyExist( aFileName );
+
+ if ( iError == KErrNone )
+ {
+ uidErr = KErrNone;
+ CheckFileVersion( aFileName );
+ }
+ }
+ }
+
+ if ( uidErr == KErrBadName && iError != KErrNotFound )
+ {
+ // Need re-create file name, add end off file _xx (xx=01, 02...)
+ LOGSTR2( "STSE > Re-create file name, aFileName(%S)", &aFileName );
+
+ // Parse file extension if exists.
+ ParseExtension( aFileName, extension );
+
+ // Temp file name
+ TBuf<KMaxFileName> tempName;
+
+ for ( TInt i = KNameIndexStart; i < KNameIndexEnd; i++ )
+ {
+ tempName.Delete( 0, tempName.MaxLength() );
+ tempName.Format( KFormat, &aFileName, &KUnderLine, i, &extension );
+ LOGSTR2( "STSE > tempName(%S)", &tempName );
+ // Try to open file
+ CheckIfFileAlreadyExist( tempName );
+
+ if ( iError == KErrNone || iError == KErrNotFound )
+ {
+ aFileName.Copy( tempName );
+ break;
+ }
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::ParseExtension
+// Method is used to parse file name extension.
+// -----------------------------------------------------------------------------
+//
+void CATStorageServerSession::ParseExtension(
+ TDes& aFileName, TDes& aExtension )
+ {
+ LOGSTR2( "STSE void CATStorageServerSession::ParseExtension(%S)",
+ &aFileName );
+
+ // Parse current file name
+ TParse parse;
+ // Set up the TParse object
+ parse.Set( aFileName, NULL, NULL );
+
+ // Tests whether an extension is present.
+ if ( parse.ExtPresent() )
+ {
+ // Gets the extension
+ aExtension.Copy( parse.Ext() );
+ // Remove extension from file name
+ TInt pos( aFileName.Find( aExtension ) );
+ aFileName.Delete( pos, aFileName.Length() );
+ LOGSTR3( "STSE > aFileName(%S), aExtension(%S)",
+ &aFileName, &aExtension );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::CheckIfFileAlreadyExist
+// Method is used to check that file exists and is valid.
+// -----------------------------------------------------------------------------
+//
+void CATStorageServerSession::CheckIfFileAlreadyExist(
+ const TDes& aFileName )
+ {
+ LOGSTR2( "STSE void CATStorageServerSession::CheckIfFileAlreadyExist(%S)",
+ &aFileName );
+
+ iError = iFile.Open( iFileServer, aFileName, EFileWrite );
+ LOGSTR2( "STSE > iError(%i)", iError );
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::CheckFileVersion
+// Method is used to check file version.
+// -----------------------------------------------------------------------------
+//
+void CATStorageServerSession::CheckFileVersion(
+ const TDes& aFileName )
+ {
+ LOGSTR2( "STSE void CATStorageServerSession::CheckFileVersion(%S)",
+ &aFileName );
+
+ TBuf8<KVersionStringLength> versionString;
+
+ // Read version information from the beginning of the file (offset 0)
+ iFile.Read( 0, versionString, KVersionStringLength );
+
+ // Delete the existing file, if the version string read from the file does not
+ // match with KDataFileVersion.
+ if ( versionString.Compare( KDataFileVersion ) != 0 )
+ {
+ // Close the existing, opened file, and delete it
+ iFile.Close();
+ iError = iFileServer.Delete( aFileName );
+
+ // If the deletion was successful, set iError = KErrNotFound, so a new
+ // file will be created in the next few lines
+ if ( iError == KErrNone )
+ {
+ iError = KErrNotFound;
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::CloseFsAndFile
+// Internally used for closing a handle to the file server and a file
+// -----------------------------------------------------------------------------
+//
+void CATStorageServerSession::CloseFsAndFile()
+ {
+ LOGSTR1( "STSE void CATStorageServerSession::CloseFsAndFile()" );
+
+ // Close the file
+ iFile.Close();
+
+ // Close the server session and return the error code
+ iFileServer.Close();
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::PrintLeaksL()
+// Called internally when a process is closed. Prints possible memory leaks
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::PrintLeaksL( const RMessage2& aMessage )
+ {
+ LOGSTR1( "STSE TInt CATStorageServerSession::PrintLeaksL()" );
+
+ // Panic both the client and the server, if this method is called in a wrong
+ // state (logging should be ongoing, and the system should be logging into a file,
+ // not into debug channel)
+ if ( !iLoggingOngoing || iLogOption != EATLogToFile )
+ {
+ PanicClient( EAToolInternalError, aMessage );
+ StorageServerPanic( KCategoryServer, EAToolInternalError );
+ }
+
+ LOGMEM;
+
+ // A pointer to a buffer of call stack's memory addresses
+ CBufFlat* stackBuf = NULL;
+
+ iError = KErrNone;
+
+ TUint32 callStackAddr;
+
+ // Number of leaks
+ TInt leakCount = iLeakArray.Count();
+
+ // Variable for the number of memory addresses in the call stack
+ TInt addrCount( 0 );
+
+ // Buffer position
+ TInt pos( 0 );
+
+ // Go through all the leaks
+ for ( TInt i = 0; i < leakCount; i++ )
+ {
+ pos = 0;
+
+ // Get the call stack buffer of the the leak i.
+ stackBuf = const_cast<CBufFlat*>( iLeakArray[i]->iCallstackBuf );
+
+ // Read the first word of the buffer. This includes the number of
+ // memory addresses stored in the current stackBuf
+ stackBuf->Read( pos, &addrCount, KWordSize );
+
+ // Move the position one word onwards.
+ pos += KWordSize;
+
+ // Construct a buffer for the string to be written into the logging file
+ // because of this memory leak. MEM_LEAK: <Memory address> <Time stamp>
+ // <Allocation size> <Call stack address> <Call stack address> ...
+ HBufC8* leakString =
+ HBufC8::NewL( KMemleakLength +
+ KHexa32Length +
+ KSpaceLength + KHexa64Length +
+ KSpaceLength + KHexa32Length +
+ ( addrCount * (KSpaceLength + KHexa32Length) ) +
+ KNewlineLength
+ );
+
+ // Make a pointer descriptor that points to leakString
+ TPtr8 leakStringPtr( leakString->Des() );
+
+ // Append the tag implying a memory leak line in the data file
+ leakStringPtr.Append( KMemoryLeak );
+
+ // Append the address of the memory leak
+ TUint32 memAddress = iLeakArray[i]->iMemAddress;
+ leakStringPtr.AppendNum( memAddress, EHex );
+
+ // Append the current time in the 64-bit (max 16 characters) hexadecimal text
+ // format
+ leakStringPtr.Append( KSpace );
+ TInt64 allocTime = iLeakArray[i]->iAllocTime;
+ leakStringPtr.AppendNum( allocTime, EHex );
+
+ // Append the size of the allocation in the 32-bit (max 8 characters) hexadecimal
+ // text format.
+ leakStringPtr.Append( KSpace );
+ TInt allocSize = iLeakArray[i]->iAllocSize;
+ leakStringPtr.AppendNum( allocSize, EHex );
+
+ // Go through all call stack's memory addresses associated with
+ // the current memory leak
+ for ( TInt j = 0; j < addrCount; j++ )
+ {
+ // Read the next call stack's memory address stored in the buffer.
+ stackBuf->Read( pos, &callStackAddr, KWordSize );
+
+ // Append the read memory address as a hexadecimal number
+ leakStringPtr.AppendFormat( KHexaNumber, callStackAddr );
+
+ // Move the pos variable one word onwards.
+ pos += KWordSize;
+ }
+
+ leakStringPtr.Append( KNewLine );
+
+ // Set stackBuf to NULL, because it is not used anymore.
+ stackBuf = NULL;
+
+ // Write the constructed string into the data file and return if error
+ iError = iFile.Write( *leakString );
+
+ delete leakString;
+
+ if ( iError != KErrNone )
+ {
+ return iError;
+ }
+
+ } // The outer for
+
+ LOGSTR1( "STSE End of CATStorageServerSession::PrintLeaks()" );
+ LOGMEM;
+
+ // Empty the leak array and delete the referenced objects
+ iLeakArray.ResetAndDestroy();
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::SetLogOption()
+// For setting the logging mode.
+// -----------------------------------------------------------------------------
+//
+void CATStorageServerSession::SetLogOption( const RMessage2& aMessage )
+ {
+ LOGSTR1( "STSE void CATStorageServerSession::SetLogOption()" );
+
+ // Panic both the client and the server, if this method is called in a wrong
+ // state (logging must not be ongoing when changing the mode of operation).
+ // So, the mode cannot be changed "on the fly".
+ if ( iLoggingOngoing )
+ {
+ PanicClient( EAToolInternalError, aMessage );
+ StorageServerPanic( KCategoryServer, EAToolInternalError );
+ }
+
+ iLogOption = static_cast<TATLogOption>( aMessage.Int3() );
+
+ // The default is EATLogToFile
+ if ( iLogOption == EATUseDefault )
+ {
+ iLogOption = KDefaultLoggingMode;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::LogThroughTrace()
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::LogThroughTrace( const TDesC& aLogString ) const
+ {
+ LOGSTR1( "STSE TInt CATStorageServerSession::LogThroughTrace()" );
+
+ // Return KErrNotSupported, if a logging session is not currently ongoing, or
+ // the logging mode is not EATLogToTrace
+ if ( !iLoggingOngoing || iLogOption != EATLogToTrace)
+ {
+ return KErrNotSupported;
+ }
+
+ RDebug::Print( KTraceMessage, iProcessId, &aLogString );
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::AllocInfoArray
+// -----------------------------------------------------------------------------
+//
+RArray<TAllocInfo>& CATStorageServerSession::AllocInfoArray()
+ {
+ LOGSTR1( "STSE RArray<TAllocInfo>& CATStorageServerSession::AllocInfoArray()" );
+
+ return iAllocInfoArray;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::PanicClient
+// Creates a panic in the associated client's code.
+// -----------------------------------------------------------------------------
+//
+void CATStorageServerSession::PanicClient( TInt aPanic, const RMessage2& aMessage )
+ {
+ LOGSTR1( "STSE void CATStorageServerSession::PanicClient()" );
+
+ aMessage.Panic( KCategoryClient, aPanic );
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::GetLoggingFileL()
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::GetLoggingFileL( const RMessage2& aMessage )
+ {
+ LOGSTR1( "STSE TInt CATStorageServerSession::GetLoggingFileL()" );
+
+ iError = KErrNone;
+
+ // Read the process ID at index 0
+ TUint processId = aMessage.Int0();
+
+ // Get the dynamic process info array
+ RPointerArray<CATDynProcessInfo> dynProcessArray =
+ iStorageServer.DynProcessInfoArray();
+
+ // Construct a CATDynProcessInfo object with the given process ID for searching
+ CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId );
+
+ // Find the index of a CATDynProcessInfo object with the given process ID
+ TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
+ TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order );
+ delete dynProcessInfo;
+ dynProcessInfo = NULL;
+
+ // Return, if a process with the requested process ID was not found
+ if ( index == KErrNotFound )
+ {
+ return index;
+ }
+
+ // Otherwise get the wanted dynamic process info
+ dynProcessInfo = dynProcessArray[index];
+
+ // Get the desired process's associated session object
+ CATStorageServerSession* sessionObject = dynProcessInfo->iSessionObject;
+
+ // Write the whole buffer into aMessage at index 1 for the client
+ aMessage.WriteL( 1, sessionObject->iLogFile );
+
+ return iError;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::GetUdebL()
+// -----------------------------------------------------------------------------
+//
+TInt CATStorageServerSession::GetUdebL( const RMessage2& aMessage )
+ {
+ LOGSTR1( "STSE TInt CATStorageServerSession::GetUdebL()" );
+
+ iError = KErrNone;
+
+ // Read the process ID at index 0
+ TUint processId = aMessage.Int0();
+
+ // Get the dynamic process info array
+ RPointerArray<CATDynProcessInfo> dynProcessArray =
+ iStorageServer.DynProcessInfoArray();
+
+ // Construct a CATDynProcessInfo object with the given process ID for searching
+ CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId );
+
+ // Find the index of a CATDynProcessInfo object with the given process ID
+ TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare );
+ TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order );
+ delete dynProcessInfo;
+ dynProcessInfo = NULL;
+
+ // Return, if a process with the requested process ID was not found
+ if ( index == KErrNotFound )
+ {
+ return index;
+ }
+
+ // Otherwise get the wanted dynamic process info
+ dynProcessInfo = dynProcessArray[index];
+
+ // Get the desired process's associated session object
+ CATStorageServerSession* sessionObject = dynProcessInfo->iSessionObject;
+
+ TBuf8<KMaxVersionName> isUdeb;
+ if ( sessionObject->iIsUdeb == 1 )
+ {
+ isUdeb.Copy( KUdeb() );
+ }
+ else if ( sessionObject->iIsUdeb == 0 )
+ {
+ isUdeb.Copy( KUrel() );
+ }
+ else
+ {
+ return KErrNotFound;
+ }
+ // Write the whole buffer into aMessage at index 1 for the client
+ aMessage.WriteL( 1, isUdeb );
+
+ return iError;
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::SetUdeb()
+// -----------------------------------------------------------------------------
+//
+void CATStorageServerSession::SetUdeb( const RMessage2& aMessage )
+ {
+ LOGSTR1( "STSE void CATStorageServerSession::SetUdeb()" );
+
+ iIsUdeb = aMessage.Int0();
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::LogAbnormalEnd()
+// -----------------------------------------------------------------------------
+//
+void CATStorageServerSession::LogAbnormalEnd()
+ {
+ LOGSTR1( "STSE void CATStorageServerSession::LogAbnormalEnd()" );
+
+ // Get the current universal time
+ TInt64 timeFrom1970( GetTime() );
+
+ switch ( iLogOption )
+ {
+ case EATLogToTrace:
+ {
+ // Make a buffer that will be logged
+ TBuf<KEndAbnormalBufLength> traceBuf;
+
+ // Write the process id to the buffer
+ traceBuf.Format( KProcessEndAbnormalTrace, iProcessId );
+
+ // Append the current time in the 64-bit (max 16 characters) hexadecimal text
+ // format
+ traceBuf.AppendNum( timeFrom1970, EHex );
+
+ // Append a new line
+ traceBuf.Append( KNewLineTrace );
+
+ // Write the buffer into the debug channel
+ RDebug::Print( KTraceMessage, iProcessId, &traceBuf );
+ }
+ break;
+
+ case EATLogToFile:
+ {
+ // Make a buffer that will be logged
+ TBuf8<KEndAbnormalBufLength> loggingBuf;
+
+ // Write the process id to the buffer
+ loggingBuf.Format( KProcessEndAbnormal, iProcessId );
+
+ // Append the current time in the 64-bit (max 16 characters) hexadecimal text
+ // format
+ loggingBuf.AppendNum( timeFrom1970, EHex );
+
+ // Append a new line
+ loggingBuf.Append( KNewLine );
+
+ // Write the buffer into a file (if possible in the current condition)
+ iFile.Write( loggingBuf );
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CATStorageServerSession::GetTime()
+// Get the current universal time
+// -----------------------------------------------------------------------------
+//
+TInt64 CATStorageServerSession::GetTime()
+ {
+ LOGSTR1( "STSE void CATStorageServerSession::GetTime()" );
+
+ // Get the current universal time
+ iTime.UniversalTime();
+
+ // Change the time format that tells the number of microseconds from January First,
+ // 0 AD nominal Gregorian, into a format that tells the number of microseconds from
+ // January First, 1970 AD nominal Gregorian. This is a more generic format and
+ // can be directly exploited by the PC code parsing the data file that this
+ // server generates.
+ return ( iTime.Int64() - iMicroSecondsAt1970 );
+ }
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/sis/atstorageserver.pkg Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,37 @@
+;
+; Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+; All rights reserved.
+; This component and the accompanying materials are made available
+; under the terms of "Eclipse Public License v1.0"
+; which accompanies this distribution, and is available
+; at the URL "http://www.eclipse.org/legal/epl-v10.html".
+;
+; Initial Contributors:
+; Nokia Corporation - initial contribution.
+;
+; Contributors:
+;
+; Description:
+;
+;
+; An installation file for AnalyzeTool StorageServer
+;
+
+;Language - standard language definitions
+&EN
+
+; standard SIS file header
+#{"ATStorageServer"},(0xA22E6C80),1,8,1
+
+;Localised Vendor name
+%{"Vendor-EN"}
+
+;Unique Vendor name
+:"Vendor"
+
+;Supports Series 60 v 3.0
+[0x101F7961], 0, 0, 0, {"Series60ProductID"}
+
+; 4 Files to install
+"\epoc32\release\armv5\urel\atoolstorageserver.exe"-"!:\sys\bin\atoolstorageserver.exe"
+"\epoc32\release\armv5\urel\atoolstorageserverclnt.dll"-"!:\sys\bin\atoolstorageserverclnt.dll"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/storageserver/sis/atstorageserver_udeb.pkg Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,37 @@
+;
+; Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+; All rights reserved.
+; This component and the accompanying materials are made available
+; under the terms of "Eclipse Public License v1.0"
+; which accompanies this distribution, and is available
+; at the URL "http://www.eclipse.org/legal/epl-v10.html".
+;
+; Initial Contributors:
+; Nokia Corporation - initial contribution.
+;
+; Contributors:
+;
+; Description:
+;
+;
+; An installation file for AnalyzeTool StorageServer
+;
+
+;Language - standard language definitions
+&EN
+
+; standard SIS file header
+#{"ATStorageServer"},(0xA22E6C80),1,8,1
+
+;Localised Vendor name
+%{"Vendor-EN"}
+
+;Unique Vendor name
+:"Vendor"
+
+;Supports Series 60 v 3.0
+[0x101F7961], 0, 0, 0, {"Series60ProductID"}
+
+; 4 Files to install
+"\epoc32\release\armv5\udeb\atoolstorageserver.exe"-"!:\sys\bin\atoolstorageserver.exe"
+"\epoc32\release\armv5\udeb\atoolstorageserverclnt.dll"-"!:\sys\bin\atoolstorageserverclnt.dll"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/symbian_version.hrh Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,43 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Symbian version configuration file
+*
+*/
+
+#ifndef __SYMBIAN_VERSION_HRH
+#define __SYMBIAN_VERSION_HRH
+
+// S60 and Symbian version number enumeration definitions
+
+#define S60_30 30
+#define S60_31 31
+#define S60_32 32
+#define S60_50 50
+#define S60_51 91
+#define S60_52 92
+#define SYMBIAN_1 50
+#define SYMBIAN_2 91
+#define SYMBIAN_3 92
+#define SYMBIAN_4 101
+
+
+/**
+ * Defines the S60 or Symbian version used by this component. This flag can be
+ * used to variate the source code based on the SDK in use. The value of the
+ * flag should be always changed to reflect the current build environment.
+ */
+#define SYMBIAN_VERSION_SUPPORT SYMBIAN_4
+
+
+#endif // __SYMBIAN_VERSION_HRH
--- a/group/bld.inf Mon May 03 13:58:41 2010 +0300
+++ b/group/bld.inf Thu May 13 23:59:27 2010 +0300
@@ -21,4 +21,6 @@
#include "../osrndtools_plat/group/bld.inf"
#include "../stif/group/bld.inf"
#include "../memspy/group/bld.inf"
-#include "../hti/group/bld.inf"
\ No newline at end of file
+#include "../hti/group/bld.inf"
+#include "../piprofiler/group/bld.inf"
+#include "../analyzetool/group/bld.inf"
\ No newline at end of file
--- a/hti/hti_plat/hti_api/inc/HtiCommPluginInterface.h Mon May 03 13:58:41 2010 +0300
+++ b/hti/hti_plat/hti_api/inc/HtiCommPluginInterface.h Thu May 13 23:59:27 2010 +0300
@@ -113,6 +113,6 @@
TUid iDtor_ID_Key;
};
-#include <HTICommPluginInterface.inl>
+#include <HtiCommPluginInterface.inl>
#endif
--- a/hti/hti_plat/hti_api/inc/HtiServicePluginInterface.h Mon May 03 13:58:41 2010 +0300
+++ b/hti/hti_plat/hti_api/inc/HtiServicePluginInterface.h Thu May 13 23:59:27 2010 +0300
@@ -110,6 +110,6 @@
TUid iDtor_ID_Key;
};
-#include <HTIServicePluginInterface.inl>
+#include <HtiServicePluginInterface.inl>
#endif
--- a/hti/hti_plat/hti_api/inc/HtiVersion.h Mon May 03 13:58:41 2010 +0300
+++ b/hti/hti_plat/hti_api/inc/HtiVersion.h Thu May 13 23:59:27 2010 +0300
@@ -25,13 +25,13 @@
// CONSTANTS
const TUint8 KHtiVersionMajor = 2;
-const TUint8 KHtiVersionMinor = 18;
+const TUint8 KHtiVersionMinor = 22;
const TUint8 KHtiVersionBuild = 0;
const TUint16 KHtiVersionYear = 2010;
-const TUint8 KHtiVersionMonth = 3;
-const TUint8 KHtiVersionWeek = 9;
-const TUint8 KHtiVersionDay = 5;
+const TUint8 KHtiVersionMonth = 4;
+const TUint8 KHtiVersionWeek = 17;
+const TUint8 KHtiVersionDay = 30;
// MACROS
--- a/memspy/CommandLine/Source/MemSpyCommandLine.cpp Mon May 03 13:58:41 2010 +0300
+++ b/memspy/CommandLine/Source/MemSpyCommandLine.cpp Thu May 13 23:59:27 2010 +0300
@@ -390,26 +390,49 @@
TInt err = KErrGeneral;
RProcess proc;
+
+ // Try to run server first
+ err = proc.Create( KMemSpyProcessName0, KNullDesC );
+ if ( err == KErrNone )
+ {
+ TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - Create server process successfully... - this: 0x%08x", this ) );
- // First try with s60 UI
- err = proc.Create( KMemSpyProcessName1, KNullDesC );
- if ( err == KErrNone )
- {
- TFullName fullName;
- proc.FullName( fullName );
- TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - Create S60 UI process successfully... - this: 0x%08x, name: %S"), this, &fullName ) );
+ TRequestStatus status;
+ proc.Rendezvous( status );
+ proc.Resume();
+
+ TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - MemSpy resumed, waiting for Rendezvous... - this: 0x%08x", this ) );
+
+ User::WaitForRequest( status );
+ err = status.Int();
+ proc.Close();
+
+ TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - Rendezvous complete: %d, this: 0x%08x", err, this ) );
+ }
- TRequestStatus status;
- proc.Rendezvous( status );
- proc.Resume();
-
- TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - MemSpy resumed, waiting for Rendezvous... - this: 0x%08x", this ) );
- User::WaitForRequest( status );
- err = status.Int();
- proc.Close();
-
- TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - Rendezvous complete: %d, this: 0x%08x", err, this ) );
- }
+ // If server is not available, try with s60 UI
+ if ( err != KErrNone )
+ {
+ err = proc.Create( KMemSpyProcessName1, KNullDesC );
+ if ( err == KErrNone )
+ {
+ TFullName fullName;
+ proc.FullName( fullName );
+ TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - Create S60 UI process successfully... - this: 0x%08x, name: %S"), this, &fullName ) );
+
+ TRequestStatus status;
+ proc.Rendezvous( status );
+ proc.Resume();
+
+ TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - MemSpy resumed, waiting for Rendezvous... - this: 0x%08x", this ) );
+ User::WaitForRequest( status );
+ err = status.Int();
+ proc.Close();
+
+ TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - Rendezvous complete: %d, this: 0x%08x", err, this ) );
+ }
+ }
+
if ( err != KErrNone )
{
// Try console UI
--- a/memspy/Console/Include/ConsoleMenu.h Mon May 03 13:58:41 2010 +0300
+++ b/memspy/Console/Include/ConsoleMenu.h Thu May 13 23:59:27 2010 +0300
@@ -26,22 +26,22 @@
// Engine includes
#include <memspy/engine/memspyengine.h>
#include <memspy/engine/memspyengineobserver.h>
-
+#include <memspysession.h>
// User includes
#include "ConsoleConstants.h"
// Classes referenced
class CConsoleBase;
-
+class RMemSpySession;
class CMemSpyConsoleMenu : public CActive, public MMemSpyEngineObserver
{
public:
- static CMemSpyConsoleMenu* NewLC( CMemSpyEngine& aEngine, CConsoleBase& aConsole );
+ static CMemSpyConsoleMenu* NewLC( RMemSpySession& aSession, CConsoleBase& aConsole );
~CMemSpyConsoleMenu();
private:
- CMemSpyConsoleMenu( CMemSpyEngine& aEngine, CConsoleBase& aConsole );
+ CMemSpyConsoleMenu( RMemSpySession& aEngine, CConsoleBase& aConsole );
void ConstructL();
public: // API
@@ -74,8 +74,10 @@
void InitiateMemSpyClientServerOperationL( TInt aOpCode );
private: // Data members
- CMemSpyEngine& iEngine;
+ RMemSpySession& iSession;
CConsoleBase& iConsole;
+
+ TMemSpyOutputType iOutputType;
//
TBuf<KMemSpyMaxInputBufferLength> iCommandBuffer;
TPoint iCommandPromptPos;
--- a/memspy/Console/Source/ConsoleDWOperation.cpp Mon May 03 13:58:41 2010 +0300
+++ b/memspy/Console/Source/ConsoleDWOperation.cpp Thu May 13 23:59:27 2010 +0300
@@ -56,7 +56,7 @@
#endif
iWaiter = new(ELeave) CActiveSchedulerWait();
- iOperation = CMemSpyDeviceWideOperations::NewL( iEngine, *this, aOperation );
+ //iOperation = CMemSpyDeviceWideOperations::NewL( iEngine, *this, aOperation );
#ifdef _DEBUG
RDebug::Printf("[MCon] CMemSpyDeviceWideOperationWaiter::ExecuteL() - starting scheduler wait..." );
--- a/memspy/Console/Source/ConsoleMain.cpp Mon May 03 13:58:41 2010 +0300
+++ b/memspy/Console/Source/ConsoleMain.cpp Thu May 13 23:59:27 2010 +0300
@@ -26,6 +26,7 @@
// Engine includes
#include <memspy/engine/memspyengine.h>
+#include <memspysession.h>
// User includes
#include "ConsoleMenu.h"
@@ -54,11 +55,12 @@
CleanupStack::PushL( console );
// Engine
- CMemSpyEngine* engine = CMemSpyEngine::NewL( fsSession );
- CleanupStack::PushL( engine );
+ RMemSpySession session;
+ User::LeaveIfError(session.Connect());
+ CleanupClosePushL(session);
// Menu & event handler AO
- CMemSpyConsoleMenu::NewLC( *engine, *console );
+ CMemSpyConsoleMenu::NewLC( session, *console );
// Play nicely with external processes
RProcess::Rendezvous( KErrNone );
--- a/memspy/Console/Source/ConsoleMenu.cpp Mon May 03 13:58:41 2010 +0300
+++ b/memspy/Console/Source/ConsoleMenu.cpp Thu May 13 23:59:27 2010 +0300
@@ -39,18 +39,17 @@
#include "ConsoleDWOperation.h"
-CMemSpyConsoleMenu::CMemSpyConsoleMenu( CMemSpyEngine& aEngine, CConsoleBase& aConsole )
-: CActive( EPriorityHigh ), iEngine( aEngine ), iConsole( aConsole )
+CMemSpyConsoleMenu::CMemSpyConsoleMenu( RMemSpySession& aSession, CConsoleBase& aConsole )
+: CActive( EPriorityHigh ), iSession( aSession ), iConsole( aConsole ), iOutputType(EOutputTypeDebug)
{
CActiveScheduler::Add( this );
- iEngine.SetObserver( this );
+ // TODO: iEngine.SetObserver( this );
}
CMemSpyConsoleMenu::~CMemSpyConsoleMenu()
{
Cancel();
- iEngine.SetObserver( NULL );
}
@@ -61,9 +60,9 @@
}
-CMemSpyConsoleMenu* CMemSpyConsoleMenu::NewLC( CMemSpyEngine& aEngine, CConsoleBase& aConsole )
+CMemSpyConsoleMenu* CMemSpyConsoleMenu::NewLC( RMemSpySession& aSession, CConsoleBase& aConsole )
{
- CMemSpyConsoleMenu* self = new(ELeave) CMemSpyConsoleMenu( aEngine, aConsole );
+ CMemSpyConsoleMenu* self = new(ELeave) CMemSpyConsoleMenu( aSession, aConsole );
CleanupStack::PushL( self );
self->ConstructL();
return self;
@@ -76,7 +75,7 @@
// First line - sink type (defaults to file)
_LIT( KLine1, "1 or T. Toggle output mode between file or trace [%S]" );
- if ( iEngine.SinkType() == ESinkTypeDebug )
+ if ( iOutputType == EOutputTypeDebug )
{
_LIT( KLine1Trace, "Trace" );
iConsole.Printf( KLine1, &KLine1Trace );
@@ -204,14 +203,7 @@
void CMemSpyConsoleMenu::OnCmdSinkTypeToggleL()
{
- if ( iEngine.SinkType() == ESinkTypeDebug )
- {
- iEngine.InstallSinkL( ESinkTypeFile );
- }
- else
- {
- iEngine.InstallSinkL( ESinkTypeDebug );
- }
+ iOutputType = iOutputType == EOutputTypeFile ? EOutputTypeDebug : EOutputTypeFile;
}
@@ -224,7 +216,7 @@
_LIT( KMsg, "Ouputting Kernel data..." );
RedrawStatusMessage( KMsg );
- iEngine.HelperHeap().OutputHeapDataKernelL();
+ iSession.OutputKernelHeapDataL( iOutputType );
RedrawStatusMessage( KNullDesC );
}
@@ -239,14 +231,7 @@
_LIT( KMsg, "Ouputting Kernel Object listing..." );
RedrawStatusMessage( KMsg );
//
- CMemSpyEngineHelperKernelContainers& kernelContainerManager = iEngine.HelperKernelContainers();
- CMemSpyEngineGenericKernelObjectContainer* model = kernelContainerManager.ObjectsAllL();
- CleanupStack::PushL( model );
- //
- CMemSpyEngineOutputSink& sink = iEngine.Sink();
- model->OutputL( sink );
- //
- CleanupStack::PopAndDestroy( model );
+ iSession.OutputKernelObjectsL( iOutputType );
RedrawStatusMessage( KNullDesC );
}
@@ -258,7 +243,7 @@
RDebug::Printf( "[MCon] CMemSpyConsoleMenu::OnCmdCSVListingStackL() - START" );
#endif
- iEngine.HelperStack().OutputStackInfoForDeviceL();
+ iSession.OutputCompactStackInfoL( iOutputType );
}
@@ -268,7 +253,7 @@
RDebug::Printf( "[MCon] CMemSpyConsoleMenu::OnCmdCSVListingHeapL() - START" );
#endif
- iEngine.HelperHeap().OutputHeapInfoForDeviceL();
+ iSession.OutputCompactHeapInfoL( iOutputType );
}
@@ -296,44 +281,34 @@
TPtr pCmdBuf( cmdBuf->Des() );
pCmdBuf.Copy( iCommandBuffer );
pCmdBuf.Append( KMemSpyConsoleWildcardCharacter );
- //
- CMemSpyEngineObjectContainer& container = iEngine.Container();
- const TInt count = container.Count();
- TFullName fullThreadName;
+
+ TInt err;
+ TProcessId procId;
+ TRAP(err, procId = iSession.GetProcessIdByNameL(pCmdBuf));
//
- TInt index = 0;
-#ifdef _DEBUG
- RDebug::Printf( "[MCon] CMemSpyConsoleMenu::OnCmdHeapDataUserL() - procCount: %d", count );
-#endif
-
- while( index < count )
- {
- CMemSpyProcess& process = container.At( index );
- const TPtrC processName( process.Name() );
-#ifdef _DEBUG
- RDebug::Print( _L("[MCon] CMemSpyConsoleMenu::OnCmdHeapDataUserL() - procName: 0x%08x %S"), &process, &processName );
-#endif
-
- //
- if ( processName.MatchF( pCmdBuf ) >= 0 )
- {
- _LIT( KProcessingRequest, "** Dumping Heap Data for thread: %S" );
- const TInt threadCount = process.Count();
- for( TInt i=0; i<threadCount; i++ )
+ if (err == KErrNone)
+ {
+ RArray<CMemSpyApiThread*> threads;
+
+ TRAP(err, iSession.GetThreadsL(procId, threads));
+ if (err == KErrNone)
+ {
+ _LIT( KProcessingRequest, "** Dumping Heap Data for thread: %S" );
+ TFullName fullThreadName;
+
+ for( TInt i=0; i<threads.Count(); i++ )
{
- CMemSpyThread& thread = process.At( i );
+ CMemSpyApiThread* thread = threads[i];
//
- fullThreadName = thread.FullName();
+ fullThreadName = thread->Name();
iConsole.Printf( KProcessingRequest, &fullThreadName );
iConsole.Write( KMemSpyConsoleNewLine );
//
- TRAP_IGNORE( iEngine.HelperHeap().OutputHeapDataUserL( thread ) );
+ TRAP_IGNORE( iSession.OutputThreadHeapDataL(iOutputType, thread->Id()) );
+
+ delete thread;
}
-
- break;
}
-
- ++index;
}
CleanupStack::PopAndDestroy( cmdBuf );
@@ -369,38 +344,36 @@
TPtr pCmdBuf( cmdBuf->Des() );
pCmdBuf.Copy( iCommandBuffer );
pCmdBuf.Append( KMemSpyConsoleWildcardCharacter );
- //
- CMemSpyEngineObjectContainer& container = iEngine.Container();
- const TInt count = container.Count();
- TFullName fullThreadName;
- //
- TInt index = 0;
- while( index < count )
- {
- CMemSpyProcess& process = container.At( index );
- const TPtrC processName( process.Name() );
- //
- if ( processName.MatchF( pCmdBuf ) >= 0 )
- {
- _LIT( KProcessingRequest, "** Dumping Heap Cell List for thread: %S" );
- const TInt threadCount = process.Count();
- for( TInt i=0; i<threadCount; i++ )
- {
- CMemSpyThread& thread = process.At( i );
- //
- fullThreadName = thread.FullName();
- iConsole.Printf( KProcessingRequest, &fullThreadName );
- iConsole.Write( KMemSpyConsoleNewLine );
- //
- TRAP_IGNORE( iEngine.HelperHeap().OutputCellListingUserL( thread ) );
- }
-
- break;
- }
-
- ++index;
- }
-
+
+ TInt err;
+ TProcessId procId;
+ TRAP(err, procId = iSession.GetProcessIdByNameL(pCmdBuf));
+ //
+ if (err == KErrNone)
+ {
+ RArray<CMemSpyApiThread*> threads;
+
+ TRAP(err, iSession.GetThreadsL(procId, threads));
+ if (err == KErrNone)
+ {
+ _LIT( KProcessingRequest, "** Dumping Heap Cell List for thread: %S" );
+ TFullName fullThreadName;
+
+ for( TInt i=0; i<threads.Count(); i++ )
+ {
+ CMemSpyApiThread* thread = threads[i];
+ //
+ fullThreadName = thread->Name();
+ iConsole.Printf( KProcessingRequest, &fullThreadName );
+ iConsole.Write( KMemSpyConsoleNewLine );
+ //
+ TRAP_IGNORE( iSession.OutputThreadCellListL(iOutputType, thread->Id()) );
+
+ delete thread;
+ }
+ }
+ }
+
CleanupStack::PopAndDestroy( cmdBuf );
DrawMenuL();
}
@@ -604,71 +577,72 @@
void CMemSpyConsoleMenu::InitiateMemSpyClientServerOperationL( TInt aOpCode )
{
-#ifdef _DEBUG
- RDebug::Printf( "[MCon] CMemSpyConsoleMenu::InitiateMemSpyClientServerOperationL() - START - aOpCode: %d, iRunningDeviceWideOperation: %d", aOpCode, iRunningDeviceWideOperation );
-#endif
- //
- if ( aOpCode == EMemSpyClientServerOpExit )
- {
- // Exit console app UI
- CActiveScheduler::Stop();
- }
- else
- {
- CMemSpyDeviceWideOperations::TOperation op = CMemSpyDeviceWideOperations::EPerEntityGeneralSummary;
- switch( aOpCode )
- {
- case EMemSpyClientServerOpSummaryInfo:
- op = CMemSpyDeviceWideOperations::EPerEntityGeneralSummary;
- break;
- case EMemSpyClientServerOpSummaryInfoDetailed:
- op = CMemSpyDeviceWideOperations::EPerEntityGeneralDetailed;
- break;
- //
- case EMemSpyClientServerOpHeapInfo:
- op = CMemSpyDeviceWideOperations::EPerEntityHeapInfo;
- break;
- case EMemSpyClientServerOpHeapCellListing:
- op = CMemSpyDeviceWideOperations::EPerEntityHeapCellListing;
- break;
- case EMemSpyClientServerOpHeapData:
- op = CMemSpyDeviceWideOperations::EPerEntityHeapData;
- break;
- //
- case EMemSpyClientServerOpStackInfo:
- op = CMemSpyDeviceWideOperations::EPerEntityStackInfo;
- break;
- case EMemSpyClientServerOpStackDataUser:
- op = CMemSpyDeviceWideOperations::EPerEntityStackDataUser;
- break;
- case EMemSpyClientServerOpStackDataKernel:
- op = CMemSpyDeviceWideOperations::EPerEntityStackDataKernel;
- break;
-
- // These are not supported by the console UI
- default:
- case EMemSpyClientServerOpBitmapsSave:
- case EMemSpyClientServerOpSendToBackground:
- case EMemSpyClientServerOpBringToForeground:
- User::Leave( KErrNotSupported );
- break;
- }
-
- if ( iRunningDeviceWideOperation )
- {
- User::Leave( KErrInUse );
- }
- else
- {
- iRunningDeviceWideOperation = ETrue;
- TRAP_IGNORE( CMemSpyDeviceWideOperationWaiter::ExecuteLD( iEngine, op ) );
- iRunningDeviceWideOperation = EFalse;
- }
- }
-
-#ifdef _DEBUG
- RDebug::Printf( "[MCon] CMemSpyConsoleMenu::InitiateMemSpyClientServerOperationL() - END - aOpCode: %d", aOpCode );
-#endif
+ // TODO: ....
+//#ifdef _DEBUG
+// RDebug::Printf( "[MCon] CMemSpyConsoleMenu::InitiateMemSpyClientServerOperationL() - START - aOpCode: %d, iRunningDeviceWideOperation: %d", aOpCode, iRunningDeviceWideOperation );
+//#endif
+// //
+// if ( aOpCode == EMemSpyClientServerOpExit )
+// {
+// // Exit console app UI
+// CActiveScheduler::Stop();
+// }
+// else
+// {
+// CMemSpyDeviceWideOperations::TOperation op = CMemSpyDeviceWideOperations::EPerEntityGeneralSummary;
+// switch( aOpCode )
+// {
+// case EMemSpyClientServerOpSummaryInfo:
+// op = CMemSpyDeviceWideOperations::EPerEntityGeneralSummary;
+// break;
+// case EMemSpyClientServerOpSummaryInfoDetailed:
+// op = CMemSpyDeviceWideOperations::EPerEntityGeneralDetailed;
+// break;
+// //
+// case EMemSpyClientServerOpHeapInfo:
+// op = CMemSpyDeviceWideOperations::EPerEntityHeapInfo;
+// break;
+// case EMemSpyClientServerOpHeapCellListing:
+// op = CMemSpyDeviceWideOperations::EPerEntityHeapCellListing;
+// break;
+// case EMemSpyClientServerOpHeapData:
+// op = CMemSpyDeviceWideOperations::EPerEntityHeapData;
+// break;
+// //
+// case EMemSpyClientServerOpStackInfo:
+// op = CMemSpyDeviceWideOperations::EPerEntityStackInfo;
+// break;
+// case EMemSpyClientServerOpStackDataUser:
+// op = CMemSpyDeviceWideOperations::EPerEntityStackDataUser;
+// break;
+// case EMemSpyClientServerOpStackDataKernel:
+// op = CMemSpyDeviceWideOperations::EPerEntityStackDataKernel;
+// break;
+//
+// // These are not supported by the console UI
+// default:
+// case EMemSpyClientServerOpBitmapsSave:
+// case EMemSpyClientServerOpSendToBackground:
+// case EMemSpyClientServerOpBringToForeground:
+// User::Leave( KErrNotSupported );
+// break;
+// }
+//
+// if ( iRunningDeviceWideOperation )
+// {
+// User::Leave( KErrInUse );
+// }
+// else
+// {
+// iRunningDeviceWideOperation = ETrue;
+// TRAP_IGNORE( CMemSpyDeviceWideOperationWaiter::ExecuteLD( iEngine, op ) );
+// iRunningDeviceWideOperation = EFalse;
+// }
+// }
+//
+//#ifdef _DEBUG
+// RDebug::Printf( "[MCon] CMemSpyConsoleMenu::InitiateMemSpyClientServerOperationL() - END - aOpCode: %d", aOpCode );
+//#endif
}
--- a/memspy/Console/group/MemSpyConsole.mmp Mon May 03 13:58:41 2010 +0300
+++ b/memspy/Console/group/MemSpyConsole.mmp Thu May 13 23:59:27 2010 +0300
@@ -25,8 +25,8 @@
#include "../../group/MemSpyCapabilities.mmh"
-EPOCSTACKSIZE 0x4000
-EPOCHEAPSIZE 0x100000 0x4000000
+//EPOCSTACKSIZE 0x4000
+//EPOCHEAPSIZE 0x100000 0x4000000
SOURCEPATH ../Source
@@ -41,6 +41,4 @@
LIBRARY euser.lib
LIBRARY efsrv.lib
-LIBRARY memspydriverclient.lib
-LIBRARY memspyengine.lib
-
+LIBRARY MemSpyClient.lib
--- a/memspy/Engine/BWINS/MemSpyEngineu.def Mon May 03 13:58:41 2010 +0300
+++ b/memspy/Engine/BWINS/MemSpyEngineu.def Thu May 13 23:59:27 2010 +0300
@@ -384,24 +384,32 @@
?Type@CMemSpyThreadInfoItemBase@@QBE?AW4TMemSpyThreadInfoItemType@@XZ @ 383 NONAME ; enum TMemSpyThreadInfoItemType CMemSpyThreadInfoItemBase::Type(void) const
?TypeAsString@CMemSpyEngineGenericKernelObjectList@@SA?AVTPtrC16@@W4TMemSpyDriverContainerType@@@Z @ 384 NONAME ; class TPtrC16 CMemSpyEngineGenericKernelObjectList::TypeAsString(enum TMemSpyDriverContainerType)
?VID@CMemSpyProcess@@QBEKXZ @ 385 NONAME ; unsigned long CMemSpyProcess::VID(void) const
- ?MdcaCount@CMemSpyEngineWindowGroupList@@UBEHXZ @ 386 NONAME ABSENT ; int CMemSpyEngineWindowGroupList::MdcaCount(void) const
- ?GetWindowGroupListL@CMemSpyEngineHelperWindowServer@@QAEXAAV?$RArray@VTMemSpyEngineWindowGroupInfo@@@@@Z @ 387 NONAME ABSENT ; void CMemSpyEngineHelperWindowServer::GetWindowGroupListL(class RArray<class TMemSpyEngineWindowGroupInfo> &)
- ??1CMemSpyEngineWindowGroupList@@UAE@XZ @ 388 NONAME ABSENT ; CMemSpyEngineWindowGroupList::~CMemSpyEngineWindowGroupList(void)
- ?Count@CMemSpyEngineWindowGroupList@@QBEHXZ @ 389 NONAME ABSENT ; int CMemSpyEngineWindowGroupList::Count(void) const
- ?ItemIndex@CMemSpyEngineWindowGroupList@@QBEHABVTMemSpyEngineWindowGroupInfo@@@Z @ 390 NONAME ABSENT ; int CMemSpyEngineWindowGroupList::ItemIndex(class TMemSpyEngineWindowGroupInfo const &) const
- ?WindowGroupListL@CMemSpyEngineHelperWindowServer@@QAEPAVCMemSpyEngineWindowGroupList@@XZ @ 391 NONAME ABSENT ; class CMemSpyEngineWindowGroupList * CMemSpyEngineHelperWindowServer::WindowGroupListL(void)
- ?HelperWindowServer@CMemSpyEngine@@QAEAAVCMemSpyEngineHelperWindowServer@@XZ @ 392 NONAME ABSENT ; class CMemSpyEngineHelperWindowServer & CMemSpyEngine::HelperWindowServer(void)
- ?MdcaPoint@CMemSpyEngineWindowGroupList@@UBE?AVTPtrC16@@H@Z @ 393 NONAME ABSENT ; class TPtrC16 CMemSpyEngineWindowGroupList::MdcaPoint(int) const
- ?At@CMemSpyEngineWindowGroupList@@QBEABVTMemSpyEngineWindowGroupInfo@@H@Z @ 394 NONAME ABSENT ; class TMemSpyEngineWindowGroupInfo const & CMemSpyEngineWindowGroupList::At(int) const
- ?ItemIndex@CMemSpyEngineWindowGroupList@@QBEHABVTMemSpyEngineWindowGroupBasicInfo@@@Z @ 395 NONAME ABSENT ; int CMemSpyEngineWindowGroupList::ItemIndex(class TMemSpyEngineWindowGroupBasicInfo const &) const
- ?At@CMemSpyEngineWindowGroupList@@QBEABVTMemSpyEngineWindowGroupBasicInfo@@H@Z @ 396 NONAME ABSENT ; class TMemSpyEngineWindowGroupBasicInfo const & CMemSpyEngineWindowGroupList::At(int) const
- ?GetWindowGroupListL@CMemSpyEngineHelperWindowServer@@QAEXAAV?$RArray@VTMemSpyEngineWindowGroupBasicInfo@@@@@Z @ 397 NONAME ABSENT ; void CMemSpyEngineHelperWindowServer::GetWindowGroupListL(class RArray<class TMemSpyEngineWindowGroupBasicInfo> &)
- ?GetWindowGroupDetailsL@CMemSpyEngineHelperWindowServer@@QAEXHAAVTMemSpyEngineWindowGroupDetails@@@Z @ 398 NONAME ABSENT ; void CMemSpyEngineHelperWindowServer::GetWindowGroupDetailsL(int, class TMemSpyEngineWindowGroupDetails &)
- ?SwitchToL@CMemSpyEngineHelperWindowServer@@QAEXH@Z @ 399 NONAME ABSENT ; void CMemSpyEngineHelperWindowServer::SwitchToL(int)
+ __E32Dll @ 386 NONAME ABSENT ; int CMemSpyEngineWindowGroupList::MdcaCount(void) const
+ __E32Dll @ 387 NONAME ABSENT ; void CMemSpyEngineHelperWindowServer::GetWindowGroupListL(class RArray<class TMemSpyEngineWindowGroupInfo> &)
+ __E32Dll @ 388 NONAME ABSENT ; CMemSpyEngineWindowGroupList::~CMemSpyEngineWindowGroupList(void)
+ __E32Dll @ 389 NONAME ABSENT ; int CMemSpyEngineWindowGroupList::Count(void) const
+ __E32Dll @ 390 NONAME ABSENT ; int CMemSpyEngineWindowGroupList::ItemIndex(class TMemSpyEngineWindowGroupInfo const &) const
+ __E32Dll @ 391 NONAME ABSENT ; class CMemSpyEngineWindowGroupList * CMemSpyEngineHelperWindowServer::WindowGroupListL(void)
+ __E32Dll @ 392 NONAME ABSENT ; class CMemSpyEngineHelperWindowServer & CMemSpyEngine::HelperWindowServer(void)
+ __E32Dll @ 393 NONAME ABSENT ; class TPtrC16 CMemSpyEngineWindowGroupList::MdcaPoint(int) const
+ __E32Dll @ 394 NONAME ABSENT ; class TMemSpyEngineWindowGroupInfo const & CMemSpyEngineWindowGroupList::At(int) const
+ __E32Dll @ 395 NONAME ABSENT ; int CMemSpyEngineWindowGroupList::ItemIndex(class TMemSpyEngineWindowGroupBasicInfo const &) const
+ __E32Dll @ 396 NONAME ABSENT ; class TMemSpyEngineWindowGroupBasicInfo const & CMemSpyEngineWindowGroupList::At(int) const
+ __E32Dll @ 397 NONAME ABSENT ; void CMemSpyEngineHelperWindowServer::GetWindowGroupListL(class RArray<class TMemSpyEngineWindowGroupBasicInfo> &)
+ __E32Dll @ 398 NONAME ABSENT ; void CMemSpyEngineHelperWindowServer::GetWindowGroupDetailsL(int, class TMemSpyEngineWindowGroupDetails &)
+ __E32Dll @ 399 NONAME ABSENT ; void CMemSpyEngineHelperWindowServer::SwitchToL(int)
?Capabilities@CMemSpyProcess@@QBE?AUSCapabilitySet@@XZ @ 400 NONAME ; struct SCapabilitySet CMemSpyProcess::Capabilities(void) const
?UIDs@CMemSpyProcess@@QBE?AVTUidType@@XZ @ 401 NONAME ; class TUidType CMemSpyProcess::UIDs(void) const
?HelperCondVar@CMemSpyEngine@@QAEAAVCMemSpyEngineHelperCondVar@@XZ @ 402 NONAME ; class CMemSpyEngineHelperCondVar & CMemSpyEngine::HelperCondVar(void)
?GetCondVarSuspendedThreadsL@CMemSpyEngineHelperCondVar@@QAEXABVTMemSpyDriverHandleInfoGeneric@@AAV?$RArray@VTMemSpyDriverCondVarSuspendedThreadInfo@@@@@Z @ 403 NONAME ; void CMemSpyEngineHelperCondVar::GetCondVarSuspendedThreadsL(class TMemSpyDriverHandleInfoGeneric const &, class RArray<class TMemSpyDriverCondVarSuspendedThreadInfo> &)
?HelperWindowServer@CMemSpyEngine@@QAEAAVMMemSpyEngineHelperWindowServer@@XZ @ 404 NONAME ; class MMemSpyEngineHelperWindowServer & CMemSpyEngine::HelperWindowServer(void)
?IsHelperWindowServerSupported@CMemSpyEngine@@QAEHXZ @ 405 NONAME ; int CMemSpyEngine::IsHelperWindowServerSupported(void)
+ __E32Dll @ 406 NONAME ABSENT ; int CMemSpyEngineGenericKernelObjectList::Size(void) const
+ __E32Dll @ 407 NONAME ABSENT ; int CMemSpyEngineGenericKernelObjectList::Size(void)
+ ?Size@CMemSpyEngineGenericKernelObjectList@@QBEHXZ @ 408 NONAME ; int CMemSpyEngineGenericKernelObjectList::Size(void) const
+ ?NewHeapRawInfo@CMemSpyEngineHelperHeap@@QAEAAVTMemSpyHeapData@@ABVTMemSpyHeapInfo@@@Z @ 409 NONAME ABSENT ; class TMemSpyHeapData & CMemSpyEngineHelperHeap::NewHeapRawInfo(class TMemSpyHeapInfo const &)
+ ?NewHeapRawInfo@CMemSpyEngineHelperHeap@@QAE?AVTMemSpyHeapData@@ABVTMemSpyHeapInfo@@@Z @ 410 NONAME ; class TMemSpyHeapData CMemSpyEngineHelperHeap::NewHeapRawInfo(class TMemSpyHeapInfo const &)
+ ?ItemsCount@CMemSpyEngineGenericKernelObjectList@@QBEHXZ @ 411 NONAME ; int CMemSpyEngineGenericKernelObjectList::ItemsCount(void) const
+ ?Priority@CMemSpyThread@@QBE?AW4TThreadPriority@@XZ @ 412 NONAME ; enum TThreadPriority CMemSpyThread::Priority(void) const
+ ?NewL@CMemSpyEngine@@SAPAV1@AAVRFs@@H@Z @ 413 NONAME ; class CMemSpyEngine * CMemSpyEngine::NewL(class RFs &, int)
--- a/memspy/Engine/Include/ClientServer/MemSpyEngineServer.h Mon May 03 13:58:41 2010 +0300
+++ b/memspy/Engine/Include/ClientServer/MemSpyEngineServer.h Thu May 13 23:59:27 2010 +0300
@@ -63,6 +63,8 @@
private: // Internal methods
void DoServiceL( const RMessage2& aMessage );
+ void DoUiServiceL( const RMessage2& aMessage );
+ void DoCmdServiceL( const RMessage2& aMessage );
static TInt ValidateFunction( TInt aFunction, TBool aIncludesThreadId, TBool aIncludesThreadName );
void HandleThreadSpecificOpL( TInt aFunction, const TThreadId& aThreadId );
void HandleThreadSpecificOpL( TInt aFunction, const TDesC& aThreadName );
--- a/memspy/Engine/Source/ClientServer/MemSpyEngineServer.cpp Mon May 03 13:58:41 2010 +0300
+++ b/memspy/Engine/Source/ClientServer/MemSpyEngineServer.cpp Thu May 13 23:59:27 2010 +0300
@@ -19,6 +19,9 @@
// System includes
#include <e32svr.h>
+#include <w32std.h>
+#include <APGTASK.H>
+#include <APGWGNAM.H>
// User includes
#include <memspy/engine/memspyengine.h>
@@ -38,6 +41,12 @@
#include <memspy/engine/memspyenginehelpersysmemtracker.h>
#include <memspy/engine/memspyenginehelpersysmemtrackerconfig.h>
#include <memspy/engine/memspyenginehelperkernelcontainers.h>
+#include <memspy/engine/memspyengineobjectthreadinfocontainer.h>
+
+#include <memspy/engine/memspyprocessdata.h>
+#include <memspy/engine/memspythreaddata.h>
+#include <memspy/engine/memspykernelobjectdata.h>
+#include <memspy/engine/memspythreadinfoitemdata.h>
CMemSpyEngineServer::CMemSpyEngineServer( CMemSpyEngine& aEngine )
@@ -167,8 +176,551 @@
TRACE( RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::ServiceL() - END - this: 0x%08x, fn: 0x%08x, id: %4d, client: %S"), this, aMessage.Function(), iClientThreadId, iClientThreadName ) );
}
+// ---------------------------------------------------------
+// DoServiceL( const RMessage2& aMessage )
+// ---------------------------------------------------------
+//
+void CMemSpyEngineSession::DoServiceL( const RMessage2& aMessage )
+ {
+ TInt function = aMessage.Function() & KMemSpyOpFlagsTypeMask;
+ if (function >= EMemSpyClientServerOpMarkerUiFirst &&
+ function < EMemSpyClientServerOpMarkerUiLast)
+
+ DoUiServiceL(aMessage);
+ else
+ DoCmdServiceL(aMessage);
+ }
-void CMemSpyEngineSession::DoServiceL( const RMessage2& aMessage )
+// ---------------------------------------------------------
+// DoUiServiceL( const RMessage2& aMessage )
+// ---------------------------------------------------------
+//
+void CMemSpyEngineSession::DoUiServiceL( const RMessage2& aMessage )
+ {
+ switch (aMessage.Function() & KMemSpyOpFlagsTypeMask)
+ {
+ case EMemSpyClientServerOpGetProcessCount:
+ {
+ aMessage.WriteL(0, TPckgBuf<TInt>(iEngine.Container().Count()));
+ break;
+ }
+ case EMemSpyClientServerOpGetProcesses:
+ {
+ CMemSpyEngineObjectContainer& list = iEngine.Container();
+
+ TPckgBuf<TInt> a0;
+ aMessage.ReadL(0, a0);
+ TInt realCount = Min(a0(), list.Count());
+
+ for(TInt i=0, offset = 0; i<realCount; i++, offset += sizeof(TMemSpyProcessData))
+ {
+ CMemSpyProcess& process = iEngine.Container().At(i);
+ TMemSpyProcessData data;
+ data.iId = process.Id();
+ data.iName.Copy(process.Name());
+
+ TPckgBuf<TMemSpyProcessData> buffer(data);
+ aMessage.WriteL(1, buffer, offset);
+ }
+
+ a0 = list.Count();
+ aMessage.WriteL(0, a0);
+
+ break;
+ }
+ case EMemSpyClienServerOpGetProcessIdByName:
+ {
+ TFullName processName;
+ aMessage.ReadL(0, processName);
+
+ TBool found(EFalse);
+
+ for (TInt i=0; i<iEngine.Container().Count(); i++)
+ {
+ CMemSpyProcess& process = iEngine.Container().At(i);
+ if (process.Name().FindF(processName) >= 0)
+ {
+ found = ETrue;
+ TPckgBuf<TProcessId> procId(process.Id());
+ aMessage.WriteL(1, procId);
+ }
+ }
+
+ if (!found)
+ {
+ User::Leave(KErrNotFound);
+ }
+
+ break;
+ }
+ case EMemSpyClientServerOpProcessSystemPermanentOrCritical:
+ {
+ TBool ret = EFalse;
+ TPckgBuf<TProcessId> id;
+ aMessage.ReadL( 0, id );
+
+ CMemSpyEngineObjectContainer& container = iEngine.Container();
+ CMemSpyProcess& process = container.ProcessByIdL( id() );
+
+ process.Open();
+
+ if ( process.IsSystemPermanent() || process.IsSystemCritical() )
+ {
+ ret = ETrue;
+ }
+ TPckgBuf<TBool> retBuf( ret );
+ aMessage.WriteL( 1, retBuf );
+
+ break;
+ }
+ case EMemSpyClientServerOpEndProcess:
+ {
+ TPckgBuf<TProcessId> id;
+ aMessage.ReadL( 0, id );
+ TPckgBuf<TMemSpyEndType> type;
+ aMessage.ReadL( 1, type );
+
+ CMemSpyEngineObjectContainer& container = iEngine.Container();
+ CMemSpyProcess& process = container.ProcessByIdL( id() );
+
+ switch ( type() )
+ {
+ case ETerminate:
+ {
+ process.TerminateL();
+ break;
+ }
+ case EPanic:
+ {
+ process.PanicL();
+ break;
+ }
+ case EKill:
+ {
+ process.KillL();
+ break;
+ }
+ }
+ break;
+ }
+ case EMemSpyClientServerOpSwitchToProcess:
+ {/*
+ TInt wgCount;
+ RWsSession wsSession;
+ User::LeaveIfError( wsSession.Connect() );
+ CleanupClosePushL( wsSession );
+ User::LeaveIfError( wgCount = wsSession.NumWindowGroups() );
+ RArray<RWsSession::TWindowGroupChainInfo> wgArray;
+ CleanupClosePushL( wgArray );
+ User::LeaveIfError( wsSession.WindowGroupList( &wgArray ) );
+ TApaTask task( wsSession );
+ TBool brought( EFalse );
+ TInt wgId( KErrNotFound );
+ TThreadId threadId;
+
+ TPckgBuf<TProcessId> id;
+ aMessage.ReadL( 0, id );
+ CMemSpyEngineObjectContainer& container = iEngine.Container();
+ CMemSpyProcess& process = container.ProcessByIdL( id() );
+
+ // loop trough threads in a process
+ for ( TInt i = 0; i < process.MdcaCount(); i++ )
+ {
+ TInt wgCountLocal = wgCount;
+
+ // loop trough all window groups and see if a thread id matches
+ while( !brought && wgCountLocal-- )
+ {
+ wgId = wgArray[wgCountLocal].iId;
+ User::LeaveIfError( wsSession.GetWindowGroupClientThreadId( wgId, threadId ) );
+ if ( threadId == process.At( i ).Id() )
+ {
+ CApaWindowGroupName* wgName = CApaWindowGroupName::NewLC( wsSession, wgId );
+ task.SetWgId( wgId );
+ if ( !wgName->Hidden() && task.Exists() )
+ {
+ task.BringToForeground();
+ brought = ETrue;
+ }
+ CleanupStack::PopAndDestroy( wgName );
+ }
+ }
+ }
+
+ TPckgBuf<TBool> ret( brought );
+ aMessage.WriteL( 1, ret );
+
+ break;*/
+ }
+ case EMemSpyClientServerOpGetThreadCount:
+ {
+ TPckgBuf<TProcessId> pid;
+ aMessage.ReadL(1, pid);
+ CMemSpyProcess& process = iEngine.Container().ProcessByIdL(pid());
+ process.Open();
+ aMessage.WriteL(0, TPckgBuf<TInt>(process.Count()));
+ process.Close();
+ break;
+ }
+ case EMemSpyClientServerOpGetThreads:
+ {
+ TPckgBuf<TProcessId> pid;
+ aMessage.ReadL(2, pid);
+
+ CMemSpyProcess& list = iEngine.Container().ProcessByIdL(pid());
+ list.Open();
+
+ TPckgBuf<TInt> a0;
+ aMessage.ReadL(0, a0);
+ TInt realCount = Min(a0(), list.Count());
+
+ for(TInt i=0, offset = 0; i<realCount; i++, offset += sizeof(TMemSpyThreadData))
+ {
+ CMemSpyThread& thread = list.At(i);
+ thread.Open();
+
+ TMemSpyThreadData data;
+ data.iId = thread.Id();
+ data.iName.Copy(thread.Name());
+ data.iThreadPriority = thread.Priority();
+
+ TPckgBuf<TMemSpyThreadData> buffer(data);
+ aMessage.WriteL(1, buffer, offset);
+
+ thread.Close();
+ }
+
+ a0 = list.Count();
+ aMessage.WriteL(0, a0);
+
+ list.Close();
+
+ break;
+ }
+ case EMemSpyClientServerOpSetThreadPriority:
+ {
+ TPckgBuf<TThreadId> tid;
+ TPckgBuf<TInt> priority;
+ aMessage.ReadL(0, tid);
+ aMessage.ReadL(1, priority);
+
+ CMemSpyProcess* process = NULL;
+ CMemSpyThread* thread = NULL;
+ User::LeaveIfError(iEngine.Container().ProcessAndThreadByThreadId(tid(), process, thread));
+
+ if (thread)
+ {
+ thread->Open();
+ thread->SetPriorityL(static_cast<TThreadPriority>(priority()));
+ thread->Close();
+ }
+ break;
+ }
+ case EMemSpyClientServerOpThreadSystemPermanentOrCritical:
+ {
+ TBool ret = EFalse;
+ TPckgBuf<TThreadId> id;
+ aMessage.ReadL( 0, id );
+
+ CMemSpyEngineObjectContainer& container = iEngine.Container();
+ CMemSpyProcess* process = NULL;
+ CMemSpyThread* thread = NULL;
+ User::LeaveIfError( container.ProcessAndThreadByThreadId( id(), process, thread ) );
+
+ if ( thread )
+ {
+ thread->Open();
+
+ if ( thread->IsSystemPermanent() || thread->IsSystemCritical() )
+ {
+ ret = ETrue;
+ }
+ thread->Close();
+ }
+ TPckgBuf<TBool> retBuf( ret );
+ aMessage.WriteL( 1, retBuf );
+
+ break;
+ }
+ case EMemSpyClientServerOpEndThread:
+ {
+ TPckgBuf<TThreadId> id;
+ aMessage.ReadL( 0, id );
+ TPckgBuf<TMemSpyEndType> type;
+ aMessage.ReadL( 1, type );
+
+ CMemSpyEngineObjectContainer& container = iEngine.Container();
+ CMemSpyProcess* process = NULL;
+ CMemSpyThread* thread = NULL;
+ User::LeaveIfError( container.ProcessAndThreadByThreadId( id(), process, thread ) );
+
+ if( thread )
+ {
+ switch ( type() )
+ {
+ case ETerminate:
+ {
+ thread->TerminateL();
+ break;
+ }
+ case EPanic:
+ {
+ thread->PanicL();
+ break;
+ }
+ case EKill:
+ {
+ thread->KillL();
+ break;
+ }
+ }
+ }
+ break;
+ }
+ case EMemSpyClientServerOpSwitchToThread:
+ {
+ TInt wgCount;
+ RWsSession wsSession;
+ User::LeaveIfError( wsSession.Connect() );
+ CleanupClosePushL( wsSession );
+ User::LeaveIfError( wgCount = wsSession.NumWindowGroups() );
+ RArray<RWsSession::TWindowGroupChainInfo> wgArray;
+ CleanupClosePushL( wgArray );
+ User::LeaveIfError( wsSession.WindowGroupList( &wgArray ) );
+ TApaTask task( wsSession );
+ TBool brought( EFalse );
+ TInt wgId( KErrNotFound );
+ TThreadId threadId;
+
+ TPckgBuf<TThreadId> id;
+ aMessage.ReadL( 0, id );
+
+ // loop trough all window groups and see if a thread id matches
+ while( !brought && wgCount-- )
+ {
+ wgId = wgArray[wgCount].iId;
+ User::LeaveIfError( wsSession.GetWindowGroupClientThreadId( wgId, threadId ) );
+ if ( threadId == id() )
+ {
+ CApaWindowGroupName* wgName = CApaWindowGroupName::NewLC( wsSession, wgId );
+ task.SetWgId( wgId );
+ if ( !wgName->Hidden() && task.Exists() )
+ {
+ task.BringToForeground();
+ brought = ETrue;
+ }
+ CleanupStack::PopAndDestroy( wgName );
+ }
+ }
+ TPckgBuf<TBool> ret( brought );
+ aMessage.WriteL( 1, ret );
+
+ break;
+ }
+ case EMemSpyClientServerOpGetInfoItemType:
+ {
+ TPckgBuf<TInt> index;
+ aMessage.ReadL( 0, index );
+ TPckgBuf<TThreadId> id;
+ aMessage.ReadL( 1, id);
+
+ CMemSpyEngineObjectContainer& container = iEngine.Container();
+ CMemSpyProcess* process = NULL; //not needed
+ CMemSpyThread* thread = NULL;
+ User::LeaveIfError( container.ProcessAndThreadByThreadId( id(), process, thread ) );
+
+ thread->Open();
+ process->Open();
+
+ CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL();
+ TMemSpyThreadInfoItemType retType = threadInfoContainer.Item( index() ).Type();
+
+ TPckgBuf<TMemSpyThreadInfoItemType> ret( retType );
+ aMessage.WriteL( 2, ret );
+
+ thread->Close();
+ process->Close();
+
+ break;
+ }
+ case EMemSpyClientServerOpGetThreadInfoItemsCount:
+ {
+ TPckgBuf<TThreadId> id;
+ aMessage.ReadL( 0, id );
+ TPckgBuf<TMemSpyThreadInfoItemType> type;
+ aMessage.ReadL( 1, type );
+
+ CMemSpyEngineObjectContainer& container = iEngine.Container();
+ CMemSpyProcess* process = NULL;
+ CMemSpyThread* thread = NULL;
+
+ container.ProcessAndThreadByThreadId( id(), process, thread );
+
+ thread->Open();
+ process->Open();
+
+ CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL();
+
+ CMemSpyThreadInfoItemBase& threadInfoItemBase = threadInfoContainer.Item( type() );
+
+ TInt count = threadInfoItemBase.MdcaCount();
+ TPckgBuf<TInt> tempret( count );
+ aMessage.WriteL( 2, tempret );
+
+ thread->Close();
+ process->Close();
+
+ break;
+ }
+ case EMemSpyClientServerOpGetThreadInfoItems:
+ {
+ TPckgBuf<TInt> count;
+ aMessage.ReadL( 0, count );
+ TPckgBuf<TThreadId> id;
+ aMessage.ReadL( 1, id );
+ TPckgBuf<TMemSpyThreadInfoItemType> type;
+ aMessage.ReadL( 2, type );
+
+ CMemSpyEngineObjectContainer& container = iEngine.Container();
+ CMemSpyProcess* process = NULL;
+ CMemSpyThread* thread = NULL;
+ User::LeaveIfError( container.ProcessAndThreadByThreadId( id() , process, thread ) );
+
+ process->Open();
+ thread->Open();
+
+ CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL();
+
+ CMemSpyThreadInfoItemBase& threadInfoItemBase = threadInfoContainer.Item( type() ); //get ThreadInfoItemBaseByType
+
+ TInt itemCount = Min(count(), threadInfoItemBase.MdcaCount());
+
+ for( TInt i=0, offset = 0; i<itemCount; i++, offset += sizeof( TMemSpyThreadInfoItemData ) )
+ {
+ TMemSpyThreadInfoItemData data;
+
+ TPtrC caption(threadInfoItemBase.MdcaPoint(i).Mid(1));
+ TInt tabPos = caption.Locate('\t');
+ if (tabPos != KErrNotFound)
+ caption.Set(caption.Left(tabPos));
+
+ TPtrC value(threadInfoItemBase.MdcaPoint(i));
+ tabPos = value.LocateReverse('\t');
+ if (tabPos != KErrNotFound)
+ value.Set(value.Mid(tabPos + 1));
+
+ data.iCaption.Copy( caption );
+ data.iValue.Copy( value );
+
+ TPckgBuf<TMemSpyThreadInfoItemData> buffer(data);
+ aMessage.WriteL(3, buffer, offset);
+ }
+ aMessage.WriteL(0, count);
+
+ thread->Close();
+ process->Close();
+
+ break;
+ }
+ // --- KernelObjects related functions ---
+ case EMemSpyClientServerOpGetKernelObjectCount:
+ {
+ TInt iCount = EMemSpyDriverContainerTypeLast - EMemSpyDriverContainerTypeFirst;
+ TPckgBuf<TInt> ret( iCount );
+ aMessage.WriteL(0, ret);
+ break;
+ }
+ case EMemSpyClientServerOpGetKernelObjects:
+ {
+ TPckgBuf<TInt> count;
+ aMessage.ReadL(0, count);
+
+ CMemSpyEngineGenericKernelObjectContainer* model = iEngine.HelperKernelContainers().ObjectsAllL(); //contains all the objects
+ CleanupStack::PushL( model );
+
+ for( TInt i=0, offset = 0; i<count(); i++, offset += sizeof( TMemSpyKernelObjectData ) )
+ {
+ TMemSpyKernelObjectData data;
+
+ TPtrC name(model->At(i).Name().Mid(1));
+ TInt tabPos = name.Locate('\t');
+ if (tabPos != KErrNotFound)
+ name.Set(name.Left(tabPos));
+
+ data.iName.Copy(name);
+ data.iType = model->At(i).Type();
+ data.iCount = model->At(i).Count();
+ data.iSize = model->At(i).Count() * model->At(i).Count();
+
+ TPckgBuf<TMemSpyKernelObjectData> buffer(data);
+ aMessage.WriteL(1, buffer, offset);
+ }
+ aMessage.WriteL(0, count);
+ CleanupStack::PopAndDestroy( model );
+ break;
+ }
+ case EMemSpyClientServerOpGetKernelObjectItemCount:
+ {
+ TPckgBuf<TMemSpyDriverContainerType> tempType;
+ aMessage.ReadL(1, tempType); //get type of kernel object
+ TMemSpyDriverContainerType type = tempType();
+
+ CMemSpyEngineHelperKernelContainers& kernelContainerManager = iEngine.HelperKernelContainers();
+ CMemSpyEngineGenericKernelObjectList* iObjectList = kernelContainerManager.ObjectsForSpecificContainerL( type );
+ CleanupStack::PushL( iObjectList );
+
+ TInt count = iObjectList->Count();
+ TPckgBuf<TInt> ret( count );
+ aMessage.WriteL( 0, ret );
+
+ CleanupStack::PopAndDestroy( iObjectList );
+ break;
+ }
+ case EMemSpyClientServerOpGetKernelObjectItems:
+ {
+ TPckgBuf<TInt> count;
+ TPckgBuf<TMemSpyDriverContainerType> tempType;
+ aMessage.ReadL( 0, count ); //get count of items
+ aMessage.ReadL(1, tempType); //get type of kernel object
+ TInt c = count();
+
+ CMemSpyEngineHelperKernelContainers& kernelContainerManager = iEngine.HelperKernelContainers();
+ CMemSpyEngineGenericKernelObjectList* iObjectList = kernelContainerManager.ObjectsForSpecificContainerL( tempType() );
+ CleanupStack::PushL( iObjectList );
+
+ for( TInt i=0, offset = 0; i<c; i++, offset += sizeof( TMemSpyDriverHandleInfoGeneric ) )
+ {
+ TMemSpyDriverHandleInfoGeneric data;
+
+ data = iObjectList->At( i );
+
+ TPckgBuf<TMemSpyDriverHandleInfoGeneric> buffer(data);
+ aMessage.WriteL(2, buffer, offset);
+ }
+
+ CleanupStack::PopAndDestroy( iObjectList );
+ break;
+ }
+ // --- Kernel Heap related functions ---
+ case EMemSpyClientServerOpGetHeap:
+ {
+ TMemSpyHeapInfo heapInfo;
+ iEngine.HelperHeap().GetHeapInfoKernelL( heapInfo );
+ TMemSpyHeapData data = iEngine.HelperHeap().NewHeapRawInfo( heapInfo );
+
+ TPckgBuf<TMemSpyHeapData> buffer(data);
+ aMessage.WriteL(0, buffer);
+
+ break;
+ }
+ }
+ }
+
+// ---------------------------------------------------------
+// DoCmdServiceL( const RMessage2& aMessage )
+// ---------------------------------------------------------
+//
+void CMemSpyEngineSession::DoCmdServiceL( const RMessage2& aMessage )
{
TInt error = KErrNone;
--- a/memspy/Engine/Source/Helpers/MemSpyEngineHelperKernelContainers.cpp Mon May 03 13:58:41 2010 +0300
+++ b/memspy/Engine/Source/Helpers/MemSpyEngineHelperKernelContainers.cpp Thu May 13 23:59:27 2010 +0300
@@ -247,6 +247,16 @@
{
return iType;
}
+
+EXPORT_C TInt CMemSpyEngineGenericKernelObjectList::Size() const
+ {
+ return iSize;
+ }
+
+EXPORT_C TInt CMemSpyEngineGenericKernelObjectList::ItemsCount() const
+ {
+ return iItems.Count();
+ }
EXPORT_C TPtrC CMemSpyEngineGenericKernelObjectList::TypeAsString( TMemSpyDriverContainerType aType )
@@ -392,7 +402,7 @@
AddItemL( aItem.iHandle );
iItems.AppendL( aItem );
//
- UpdateNameL();
+ //UpdateNameL();
}
--- a/memspy/Engine/Source/MemSpyEngine.cpp Mon May 03 13:58:41 2010 +0300
+++ b/memspy/Engine/Source/MemSpyEngine.cpp Thu May 13 23:59:27 2010 +0300
@@ -43,14 +43,14 @@
}
-void CMemSpyEngine::ConstructL( RFs& aFsSession )
+void CMemSpyEngine::ConstructL( RFs& aFsSession, TBool aStartServer )
{
#ifdef _DEBUG
RDebug::Printf( "CMemSpyEngine::ConstructL() - START" );
#endif
iImp = new(ELeave) CMemSpyEngineImp( aFsSession, *this );
- iImp->ConstructL();
+ iImp->ConstructL(aStartServer);
#ifdef _DEBUG
RDebug::Printf( "CMemSpyEngine::ConstructL() - END" );
@@ -60,9 +60,14 @@
EXPORT_C CMemSpyEngine* CMemSpyEngine::NewL( RFs& aFsSession )
{
+ return NewL(aFsSession, ETrue );
+ }
+
+EXPORT_C CMemSpyEngine* CMemSpyEngine::NewL( RFs& aFsSession, TBool aStartServer )
+ {
CMemSpyEngine* self = new(ELeave) CMemSpyEngine();
CleanupStack::PushL( self );
- self->ConstructL( aFsSession );
+ self->ConstructL( aFsSession, aStartServer );
CleanupStack::Pop( self );
return self;
}
--- a/memspy/Engine/Source/MemSpyEngineImp.cpp Mon May 03 13:58:41 2010 +0300
+++ b/memspy/Engine/Source/MemSpyEngineImp.cpp Thu May 13 23:59:27 2010 +0300
@@ -74,7 +74,7 @@
RDebug::Printf( "CMemSpyEngineImp::~CMemSpyEngineImp() - deleting helpers..." );
#endif
delete iHelperSysMemTracker;
- delete iServer;
+ //delete iServer;
delete iHelperKernelContainers;
delete iHelperFbServ;
delete iHelperHeap;
@@ -127,7 +127,7 @@
}
-void CMemSpyEngineImp::ConstructL()
+void CMemSpyEngineImp::ConstructL( TBool aStartServer )
{
#ifdef _DEBUG
RDebug::Printf( "CMemSpyEngineImp::ConstructL() - START" );
@@ -138,8 +138,11 @@
// Starting the server before the driver connection is made
// ensures that only one instance of MemSpy can run (either the S60
// UI or the console UI ).
- iServer = CMemSpyEngineServer::NewL( iEngine );
- //
+ if (aStartServer)
+ {
+ iServer = CMemSpyEngineServer::NewL( iEngine );
+ }
+
iMemSpyDriver = new(ELeave) RMemSpyDriverClient();
const TInt error = Driver().Open();
User::LeaveIfError( error );
--- a/memspy/Engine/Source/ThreadAndProcess/MemSpyEngineObjectProcess.cpp Mon May 03 13:58:41 2010 +0300
+++ b/memspy/Engine/Source/ThreadAndProcess/MemSpyEngineObjectProcess.cpp Thu May 13 23:59:27 2010 +0300
@@ -515,6 +515,25 @@
return iInfo->VID();
}
+EXPORT_C TProcessPriority CMemSpyProcess::Priority() const
+ {
+ return iPriority;
+ }
+
+EXPORT_C TExitCategoryName CMemSpyProcess::ExitCategory() const
+ {
+ return iExitCategory;
+ }
+
+EXPORT_C TInt CMemSpyProcess::ExitReason() const
+ {
+ return iExitReason;
+ }
+
+EXPORT_C TExitType CMemSpyProcess::ExitType() const
+ {
+ return iExitType;
+ }
EXPORT_C TUidType CMemSpyProcess::UIDs() const
{
--- a/memspy/Engine/Source/ThreadAndProcess/MemSpyEngineObjectThreadInfoObjects.cpp Mon May 03 13:58:41 2010 +0300
+++ b/memspy/Engine/Source/ThreadAndProcess/MemSpyEngineObjectThreadInfoObjects.cpp Thu May 13 23:59:27 2010 +0300
@@ -123,6 +123,17 @@
return TPtrC( item->Combined() );
}
+EXPORT_C TPtrC CMemSpyThreadInfoItemBase::Caption(TInt aIndex ) const
+ {
+ CItem* item = iItems[ aIndex ];
+ return TPtrC( item->Caption() );
+ }
+
+EXPORT_C TPtrC CMemSpyThreadInfoItemBase::Value(TInt aIndex ) const
+ {
+ CItem* item = iItems[ aIndex ];
+ return TPtrC( item->Value() );
+ }
EXPORT_C CMemSpyEngine& CMemSpyThreadInfoItemBase::Engine() const
{
--- a/memspy/Engine/eabi/MemSpyEngineu.def Mon May 03 13:58:41 2010 +0300
+++ b/memspy/Engine/eabi/MemSpyEngineu.def Thu May 13 23:59:27 2010 +0300
@@ -536,4 +536,15 @@
_ZTI49CMemSpyEngineHelperSysMemTrackerEntryWindowServer @ 535 NONAME ; #<TI>#
_ZTV49CMemSpyEngineHelperSysMemTrackerEntryWindowServer @ 536 NONAME ; #<VT>#
_ZN13CMemSpyEngine29IsHelperWindowServerSupportedEv @ 537 NONAME
+ _ZN23CMemSpyEngineHelperHeap14NewHeapRawInfoERK15TMemSpyHeapInfo @ 538 NONAME
+ _ZNK36CMemSpyEngineGenericKernelObjectList10ItemsCountEv @ 539 NONAME
+ _ZNK36CMemSpyEngineGenericKernelObjectList4SizeEv @ 540 NONAME
+ _ZNK13CMemSpyThread8PriorityEv @ 541 NONAME
+ _ZN13CMemSpyEngine4NewLER3RFsi @ 542 NONAME
+ _ZNK14CMemSpyProcess10ExitReasonEv @ 543 NONAME
+ _ZNK14CMemSpyProcess12ExitCategoryEv @ 544 NONAME
+ _ZNK14CMemSpyProcess8ExitTypeEv @ 545 NONAME
+ _ZNK14CMemSpyProcess8PriorityEv @ 546 NONAME
+ _ZNK25CMemSpyThreadInfoItemBase5ValueEi @ 547 NONAME
+ _ZNK25CMemSpyThreadInfoItemBase7CaptionEi @ 548 NONAME
--- a/memspy/Engine/group/MemSpyEngine.mmp Mon May 03 13:58:41 2010 +0300
+++ b/memspy/Engine/group/MemSpyEngine.mmp Thu May 13 23:59:27 2010 +0300
@@ -113,15 +113,18 @@
OS_LAYER_SYSTEMINCLUDE
+APP_LAYER_SYSTEMINCLUDE
+
LIBRARY euser.lib
LIBRARY MemSpyDriverClient.lib hal.lib estor.lib
LIBRARY efsrv.lib bafl.lib fbscli.lib
LIBRARY ecom.lib xmlframework.lib charconv.lib
-
+LIBRARY apgrfx.lib
+LIBRARY ws32.lib
#include "MemSpyEngine.config"
+//EXPORTUNFROZEN
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/memspy/MemSpyClient/bwins/MemSpyClientu.def Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,121 @@
+EXPORTS
+ ?CpuUse@CMemSpyApiThread@@QBEHXZ @ 1 NONAME ; int CMemSpyApiThread::CpuUse(void) const
+ ?Name@CMemSpyApiKernelObjectItem@@QBEABVTDesC8@@XZ @ 2 NONAME ; class TDesC8 const & CMemSpyApiKernelObjectItem::Name(void) const
+ ?AccessCount@CMemSpyApiKernelObjectItem@@QBEHXZ @ 3 NONAME ; int CMemSpyApiKernelObjectItem::AccessCount(void) const
+ ?TotalOverhead@CMemSpyApiHeap@@QAEHXZ @ 4 NONAME ; int CMemSpyApiHeap::TotalOverhead(void)
+ ?UniqueID@CMemSpyApiKernelObjectItem@@QBEHXZ @ 5 NONAME ; int CMemSpyApiKernelObjectItem::UniqueID(void) const
+ ?SessionType@CMemSpyApiKernelObjectItem@@QBE?AW4TIpcSessionType@@XZ @ 6 NONAME ; enum TIpcSessionType CMemSpyApiKernelObjectItem::SessionType(void) const
+ ?VID@CMemSpyApiThread@@QBEHXZ @ 7 NONAME ; int CMemSpyApiThread::VID(void) const
+ ?MaxLength@CMemSpyApiHeap@@QAEHXZ @ 8 NONAME ; int CMemSpyApiHeap::MaxLength(void)
+ ?ProcessNumberUsing@CMemSpyApiThread@@QBEHXZ @ 9 NONAME ; int CMemSpyApiThread::ProcessNumberUsing(void) const
+ ?AddressOfKernelOwner@CMemSpyApiKernelObjectItem@@QAEPAEXZ @ 10 NONAME ; unsigned char * CMemSpyApiKernelObjectItem::AddressOfKernelOwner(void)
+ ?FreeCount@CMemSpyApiHeap@@QAEHXZ @ 11 NONAME ; int CMemSpyApiHeap::FreeCount(void)
+ ?ExitType@CMemSpyApiProcess@@QBE?AW4TExitType@@XZ @ 12 NONAME ; enum TExitType CMemSpyApiProcess::ExitType(void) const
+ ?TotalFree@CMemSpyApiHeap@@QAEHXZ @ 13 NONAME ; int CMemSpyApiHeap::TotalFree(void)
+ ?SwitchToThread@RMemSpySession@@QAEHVTThreadId@@H@Z @ 14 NONAME ; int RMemSpySession::SwitchToThread(class TThreadId, int)
+ ?FreeOverhead@CMemSpyApiHeap@@QAEHXZ @ 15 NONAME ; int CMemSpyApiHeap::FreeOverhead(void)
+ ?SlackFreeSpace@CMemSpyApiHeap@@QAEHXZ @ 16 NONAME ; int CMemSpyApiHeap::SlackFreeSpace(void)
+ ?Priority@CMemSpyApiKernelObjectItem@@QBEHXZ @ 17 NONAME ; int CMemSpyApiKernelObjectItem::Priority(void) const
+ ?EndThread@RMemSpySession@@QAEHVTThreadId@@W4TMemSpyEndType@@@Z @ 18 NONAME ; int RMemSpySession::EndThread(class TThreadId, enum TEndType)
+ ?ThreadCount@CMemSpyApiProcess@@QBEHXZ @ 19 NONAME ; int CMemSpyApiProcess::ThreadCount(void) const
+ ?RequestCount@CMemSpyApiThread@@QBEHXZ @ 20 NONAME ; int CMemSpyApiThread::RequestCount(void) const
+ ??1CMemSpyApiProcess@@QAE@XZ @ 21 NONAME ; CMemSpyApiProcess::~CMemSpyApiProcess(void)
+ ?SetThreadPriorityL@RMemSpySession@@QAEXVTThreadId@@H@Z @ 22 NONAME ; void RMemSpySession::SetThreadPriorityL(class TThreadId, int)
+ ?MinLength@CMemSpyApiHeap@@QAEHXZ @ 23 NONAME ; int CMemSpyApiHeap::MinLength(void)
+ ?Restrictions@CMemSpyApiKernelObjectItem@@QBEIXZ @ 24 NONAME ; unsigned int CMemSpyApiKernelObjectItem::Restrictions(void) const
+ ?Id@CMemSpyApiKernelObjectItem@@QBEHXZ @ 25 NONAME ; int CMemSpyApiKernelObjectItem::Id(void) const
+ ?Count@CMemSpyApiKernelObjectItem@@QBEHXZ @ 26 NONAME ; int CMemSpyApiKernelObjectItem::Count(void) const
+ ?ExitCategory@CMemSpyApiProcess@@QBE?AV?$TBuf@$0BA@@@XZ @ 27 NONAME ; class TBuf<16> CMemSpyApiProcess::ExitCategory(void) const
+ ?ControllingOwner@CMemSpyApiKernelObjectItem@@QBEIXZ @ 28 NONAME ; unsigned int CMemSpyApiKernelObjectItem::ControllingOwner(void) const
+ ?Count@CMemSpyApiKernelObject@@QBEHXZ @ 29 NONAME ; int CMemSpyApiKernelObject::Count(void) const
+ ?StartPos@CMemSpyApiKernelObjectItem@@QBEHXZ @ 30 NONAME ; int CMemSpyApiKernelObjectItem::StartPos(void) const
+ ?TimerState@CMemSpyApiKernelObjectItem@@QBE?AW4TMemSpyDriverTimerState@@XZ @ 31 NONAME ; enum TMemSpyDriverTimerState CMemSpyApiKernelObjectItem::TimerState(void) const
+ ?ExitType@CMemSpyApiThread@@QBE?AW4TExitType@@XZ @ 32 NONAME ; enum TExitType CMemSpyApiThread::ExitType(void) const
+ ?BaseAddress@CMemSpyApiHeap@@QAEHXZ @ 33 NONAME ; int CMemSpyApiHeap::BaseAddress(void)
+ ?Version@CMemSpyApiKernelObjectItem@@QBE?AVTVersion@@XZ @ 34 NONAME ; class TVersion CMemSpyApiKernelObjectItem::Version(void) const
+ ?SwitchToProcess@RMemSpySession@@QAEHVTProcessId@@H@Z @ 35 NONAME ; int RMemSpySession::SwitchToProcess(class TProcessId, int)
+ ?MaxSize@CMemSpyApiKernelObjectItem@@QBEHXZ @ 36 NONAME ; int CMemSpyApiKernelObjectItem::MaxSize(void) const
+ ?Type@CMemSpyApiHeap@@QAEAAVTDesC16@@XZ @ 37 NONAME ; class TDesC16 & CMemSpyApiHeap::Type(void)
+ ?AddressOfOwningProcess@CMemSpyApiKernelObjectItem@@QAEPAEXZ @ 38 NONAME ; unsigned char * CMemSpyApiKernelObjectItem::AddressOfOwningProcess(void)
+ ?Id@CMemSpyApiProcess@@QBE?AVTProcessId@@XZ @ 39 NONAME ; class TProcessId CMemSpyApiProcess::Id(void) const
+ ??1CMemSpyApiKernelObjectItem@@QAE@XZ @ 40 NONAME ; CMemSpyApiKernelObjectItem::~CMemSpyApiKernelObjectItem(void)
+ ?BiggestAllocation@CMemSpyApiHeap@@QAEHXZ @ 41 NONAME ; int CMemSpyApiHeap::BiggestAllocation(void)
+ ?ExitReason@CMemSpyApiProcess@@QBEHXZ @ 42 NONAME ; int CMemSpyApiProcess::ExitReason(void) const
+ ?MsgCount@CMemSpyApiKernelObjectItem@@QBEHXZ @ 43 NONAME ; int CMemSpyApiKernelObjectItem::MsgCount(void) const
+ ?AllocationsCount@CMemSpyApiHeap@@QAEHXZ @ 44 NONAME ; int CMemSpyApiHeap::AllocationsCount(void)
+ ?AllocationOverhead@CMemSpyApiHeap@@QAEHXZ @ 45 NONAME ; int CMemSpyApiHeap::AllocationOverhead(void)
+ ?NameOfOwner@CMemSpyApiKernelObjectItem@@QBEABVTDesC8@@XZ @ 46 NONAME ; class TDesC8 const & CMemSpyApiKernelObjectItem::NameOfOwner(void) const
+ ?WaitCount@CMemSpyApiKernelObjectItem@@QBEHXZ @ 47 NONAME ; int CMemSpyApiKernelObjectItem::WaitCount(void) const
+ ?ThreadSystemPermanentOrCritical@RMemSpySession@@QAEHVTThreadId@@H@Z @ 48 NONAME ; int RMemSpySession::ThreadSystemPermanentOrCritical(class TThreadId, int)
+ ?Protection@CMemSpyApiKernelObjectItem@@QBEIXZ @ 49 NONAME ; unsigned int CMemSpyApiKernelObjectItem::Protection(void) const
+ ?Attributes@CMemSpyApiThread@@QBEHXZ @ 50 NONAME ; int CMemSpyApiThread::Attributes(void) const
+ ?BiggestFree@CMemSpyApiHeap@@QAEHXZ @ 51 NONAME ; int CMemSpyApiHeap::BiggestFree(void)
+ ?Bottom@CMemSpyApiKernelObjectItem@@QBEHXZ @ 52 NONAME ; int CMemSpyApiKernelObjectItem::Bottom(void) const
+ ?Size@CMemSpyApiKernelObject@@QBE_JXZ @ 53 NONAME ; long long CMemSpyApiKernelObject::Size(void) const
+ ?ThreadHandles@CMemSpyApiThread@@QBEHXZ @ 54 NONAME ; int CMemSpyApiThread::ThreadHandles(void) const
+ ?SvrSessionType@CMemSpyApiKernelObjectItem@@QBEEXZ @ 55 NONAME ; unsigned char CMemSpyApiKernelObjectItem::SvrSessionType(void) const
+ ?TotalAllocations@CMemSpyApiHeap@@QAEHXZ @ 56 NONAME ; int CMemSpyApiHeap::TotalAllocations(void)
+ ?Name@CMemSpyApiProcess@@QBEABVTDesC16@@XZ @ 57 NONAME ; class TDesC16 const & CMemSpyApiProcess::Name(void) const
+ ?ChunkType@CMemSpyApiKernelObjectItem@@QBEIXZ @ 58 NONAME ; unsigned int CMemSpyApiKernelObjectItem::ChunkType(void) const
+ ?GetKernelObjects@RMemSpySession@@QAEHAAV?$RArray@PAVCMemSpyApiKernelObject@@@@@Z @ 59 NONAME ; int RMemSpySession::GetKernelObjects(class RArray<class CMemSpyApiKernelObject *> &)
+ ?HeaderSizeF@CMemSpyApiHeap@@QAEHXZ @ 60 NONAME ; int CMemSpyApiHeap::HeaderSizeF(void)
+ ?Id@CMemSpyApiThread@@QBE?AVTThreadId@@XZ @ 61 NONAME ; class TThreadId CMemSpyApiThread::Id(void) const
+ ?MsgLimit@CMemSpyApiKernelObjectItem@@QBEHXZ @ 62 NONAME ; int CMemSpyApiKernelObjectItem::MsgLimit(void) const
+ ?AddressOfDataBssStackChunk@CMemSpyApiKernelObjectItem@@QAEPAEXZ @ 63 NONAME ; unsigned char * CMemSpyApiKernelObjectItem::AddressOfDataBssStackChunk(void)
+ ?MapAttr@CMemSpyApiKernelObjectItem@@QBEIXZ @ 64 NONAME ; unsigned int CMemSpyApiKernelObjectItem::MapAttr(void) const
+ ?Top@CMemSpyApiKernelObjectItem@@QBEHXZ @ 65 NONAME ; int CMemSpyApiKernelObjectItem::Top(void) const
+ ?Resetting@CMemSpyApiKernelObjectItem@@QBEEXZ @ 66 NONAME ; unsigned char CMemSpyApiKernelObjectItem::Resetting(void) const
+ ?HeaderSizeA@CMemSpyApiHeap@@QAEHXZ @ 67 NONAME ; int CMemSpyApiHeap::HeaderSizeA(void)
+ ?EndProcess@RMemSpySession@@QAEHVTProcessId@@W4TMemSpyEndType@@@Z @ 68 NONAME ; int RMemSpySession::EndProcess(class TProcessId, enum TEndType)
+ ?AddressOfCodeSeg@CMemSpyApiKernelObjectItem@@QAEPAEXZ @ 69 NONAME ; unsigned char * CMemSpyApiKernelObjectItem::AddressOfCodeSeg(void)
+ ?TotalAccessCount@CMemSpyApiKernelObjectItem@@QBEGXZ @ 70 NONAME ; unsigned short CMemSpyApiKernelObjectItem::TotalAccessCount(void) const
+ ?GetThreadsL@RMemSpySession@@QAEXVTProcessId@@AAV?$RArray@PAVCMemSpyApiThread@@@@W4TSortType@@@Z @ 71 NONAME ; void RMemSpySession::GetThreadsL(class TProcessId, class RArray<class CMemSpyApiThread *> &, enum TSortType)
+ ?Changes@CMemSpyApiKernelObjectItem@@QBEIXZ @ 72 NONAME ; unsigned int CMemSpyApiKernelObjectItem::Changes(void) const
+ ?ProcessId@CMemSpyApiThread@@QBE?AVTProcessId@@XZ @ 73 NONAME ; class TProcessId CMemSpyApiThread::ProcessId(void) const
+ ??0RMemSpySession@@QAE@XZ @ 74 NONAME ; RMemSpySession::RMemSpySession(void)
+ ?Type@CMemSpyApiKernelObjectItem@@QBE?AW4TMemSpyDriverContainerType@@XZ @ 75 NONAME ; enum TMemSpyDriverContainerType CMemSpyApiKernelObjectItem::Type(void) const
+ ?AddressOfServer@CMemSpyApiKernelObjectItem@@QAEPAEXZ @ 76 NONAME ; unsigned char * CMemSpyApiKernelObjectItem::AddressOfServer(void)
+ ?Size@CMemSpyApiHeap@@QAEHXZ @ 77 NONAME ; int CMemSpyApiHeap::Size(void)
+ ??1CMemSpyApiKernelObject@@QAE@XZ @ 78 NONAME ; CMemSpyApiKernelObject::~CMemSpyApiKernelObject(void)
+ ??1CMemSpyApiHeap@@QAE@XZ @ 79 NONAME ; CMemSpyApiHeap::~CMemSpyApiHeap(void)
+ ?ChunkSize@CMemSpyApiHeap@@QAEHXZ @ 80 NONAME ; int CMemSpyApiHeap::ChunkSize(void)
+ ?UnitsMask@CMemSpyApiKernelObjectItem@@QBEIXZ @ 81 NONAME ; unsigned int CMemSpyApiKernelObjectItem::UnitsMask(void) const
+ ?Size@CMemSpyApiKernelObjectItem@@QBEKXZ @ 82 NONAME ; unsigned long CMemSpyApiKernelObjectItem::Size(void) const
+ ?State@CMemSpyApiKernelObjectItem@@QBEEXZ @ 83 NONAME ; unsigned char CMemSpyApiKernelObjectItem::State(void) const
+ ?Shared@CMemSpyApiHeap@@QAEHXZ @ 84 NONAME ; int CMemSpyApiHeap::Shared(void)
+ ?Type@CMemSpyApiKernelObject@@QBE?AW4TMemSpyDriverContainerType@@XZ @ 85 NONAME ; enum TMemSpyDriverContainerType CMemSpyApiKernelObject::Type(void) const
+ ?Fragmentation@CMemSpyApiHeap@@QAEHXZ @ 86 NONAME ; int CMemSpyApiHeap::Fragmentation(void)
+ ?Name@CMemSpyApiKernelObject@@QBEABVTDesC16@@XZ @ 87 NONAME ; class TDesC16 const & CMemSpyApiKernelObject::Name(void) const
+ ?TimerType@CMemSpyApiKernelObjectItem@@QBE?AW4TMemSpyDriverTimerType@@XZ @ 88 NONAME ; enum TMemSpyDriverTimerType CMemSpyApiKernelObjectItem::TimerType(void) const
+ ?ProcessSystemPermanentOrCritical@RMemSpySession@@QAEHVTProcessId@@H@Z @ 89 NONAME ; int RMemSpySession::ProcessSystemPermanentOrCritical(class TProcessId, int)
+ ?SecurityZone@CMemSpyApiKernelObjectItem@@QBEIXZ @ 90 NONAME ; unsigned int CMemSpyApiKernelObjectItem::SecurityZone(void) const
+ ?CreatorId@CMemSpyApiKernelObjectItem@@QBEIXZ @ 91 NONAME ; unsigned int CMemSpyApiKernelObjectItem::CreatorId(void) const
+ ?MapCount@CMemSpyApiKernelObjectItem@@QBEHXZ @ 92 NONAME ; int CMemSpyApiKernelObjectItem::MapCount(void) const
+ ?NameDetail@CMemSpyApiKernelObjectItem@@QBEABVTDesC8@@XZ @ 93 NONAME ; class TDesC8 const & CMemSpyApiKernelObjectItem::NameDetail(void) const
+ ?OpenChannels@CMemSpyApiKernelObjectItem@@QAEHXZ @ 94 NONAME ; int CMemSpyApiKernelObjectItem::OpenChannels(void)
+ ?Order@CMemSpyApiKernelObjectItem@@QBEEXZ @ 95 NONAME ; unsigned char CMemSpyApiKernelObjectItem::Order(void) const
+ ?ProcessPriority@CMemSpyApiThread@@QBE?AW4TProcessPriority@@XZ @ 96 NONAME ; enum TProcessPriority CMemSpyApiThread::ProcessPriority(void) const
+ ?GetProcessesL@RMemSpySession@@QAEXAAV?$RArray@PAVCMemSpyApiProcess@@@@W4TSortType@@@Z @ 97 NONAME ; void RMemSpySession::GetProcessesL(class RArray<class CMemSpyApiProcess *> &, enum TSortType)
+ ?Handle@CMemSpyApiKernelObjectItem@@QBEPAXXZ @ 98 NONAME ; void * CMemSpyApiKernelObjectItem::Handle(void) const
+ ?ParseMask@CMemSpyApiKernelObjectItem@@QBEIXZ @ 99 NONAME ; unsigned int CMemSpyApiKernelObjectItem::ParseMask(void) const
+ ?Attributes@CMemSpyApiKernelObjectItem@@QBEHXZ @ 100 NONAME ; int CMemSpyApiKernelObjectItem::Attributes(void) const
+ ?DebugAllocatorLibrary@CMemSpyApiHeap@@QAEHXZ @ 101 NONAME ; int CMemSpyApiHeap::DebugAllocatorLibrary(void)
+ ?ThreadNumberUsing@CMemSpyApiThread@@QBEHXZ @ 102 NONAME ; int CMemSpyApiThread::ThreadNumberUsing(void) const
+ ?Overhead@CMemSpyApiHeap@@QAEHXZ @ 103 NONAME ; int CMemSpyApiHeap::Overhead(void)
+ ?Connect@RMemSpySession@@QAEHXZ @ 104 NONAME ; int RMemSpySession::Connect(void)
+ ??1CMemSpyApiThread@@QAE@XZ @ 105 NONAME ; CMemSpyApiThread::~CMemSpyApiThread(void)
+ ?SID@CMemSpyApiThread@@QBEHXZ @ 106 NONAME ; int CMemSpyApiThread::SID(void) const
+ ?AddressOfOwningThread@CMemSpyApiKernelObjectItem@@QAEPAEXZ @ 107 NONAME ; unsigned char * CMemSpyApiKernelObjectItem::AddressOfOwningThread(void)
+ ?GetKernelObjectItems@RMemSpySession@@QAEHAAV?$RArray@PAVCMemSpyApiKernelObjectItem@@@@W4TMemSpyDriverContainerType@@@Z @ 108 NONAME ; int RMemSpySession::GetKernelObjectItems(class RArray<class CMemSpyApiKernelObjectItem *> &, enum TMemSpyDriverContainerType)
+ ?ProcessHandles@CMemSpyApiThread@@QBEHXZ @ 109 NONAME ; int CMemSpyApiThread::ProcessHandles(void) const
+ ?ThreadPriority@CMemSpyApiThread@@QBE?AW4TThreadPriority@@XZ @ 110 NONAME ; enum TThreadPriority CMemSpyApiThread::ThreadPriority(void) const
+ ?GetHeap@RMemSpySession@@QAEPAVCMemSpyApiHeap@@XZ @ 111 NONAME ; class CMemSpyApiHeap * RMemSpySession::GetHeap(void)
+ ?Name@CMemSpyApiThread@@QBEABVTDesC16@@XZ @ 112 NONAME ; class TDesC16 const & CMemSpyApiThread::Name(void) const
+ ?OutputThreadCellListL@RMemSpySession@@QAEXW4TMemSpyOutputType@@VTThreadId@@@Z @ 113 NONAME ; void RMemSpySession::OutputThreadCellListL(enum TMemSpyOutputType, class TThreadId)
+ ?OutputCompactHeapInfoL@RMemSpySession@@QAEXW4TMemSpyOutputType@@@Z @ 114 NONAME ; void RMemSpySession::OutputCompactHeapInfoL(enum TMemSpyOutputType)
+ ?GetProcessIdByNameL@RMemSpySession@@QAE?AVTProcessId@@ABVTDesC16@@@Z @ 115 NONAME ; class TProcessId RMemSpySession::GetProcessIdByNameL(class TDesC16 const &)
+ ?OutputThreadHeapDataL@RMemSpySession@@QAEXW4TMemSpyOutputType@@VTThreadId@@@Z @ 116 NONAME ; void RMemSpySession::OutputThreadHeapDataL(enum TMemSpyOutputType, class TThreadId)
+ ?OutputKernelHeapDataL@RMemSpySession@@QAEXW4TMemSpyOutputType@@@Z @ 117 NONAME ; void RMemSpySession::OutputKernelHeapDataL(enum TMemSpyOutputType)
+ ?OutputCompactStackInfoL@RMemSpySession@@QAEXW4TMemSpyOutputType@@@Z @ 118 NONAME ; void RMemSpySession::OutputCompactStackInfoL(enum TMemSpyOutputType)
+ ?OutputKernelObjectsL@RMemSpySession@@QAEXW4TMemSpyOutputType@@@Z @ 119 NONAME ; void RMemSpySession::OutputKernelObjectsL(enum TMemSpyOutputType)
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/memspy/MemSpyClient/eabi/MemSpyClientu.def Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,138 @@
+EXPORTS
+ _ZN14CMemSpyApiHeap11BaseAddressEv @ 1 NONAME
+ _ZN14CMemSpyApiHeap11BiggestFreeEv @ 2 NONAME
+ _ZN14CMemSpyApiHeap11HeaderSizeAEv @ 3 NONAME
+ _ZN14CMemSpyApiHeap11HeaderSizeFEv @ 4 NONAME
+ _ZN14CMemSpyApiHeap12FreeOverheadEv @ 5 NONAME
+ _ZN14CMemSpyApiHeap13FragmentationEv @ 6 NONAME
+ _ZN14CMemSpyApiHeap13TotalOverheadEv @ 7 NONAME
+ _ZN14CMemSpyApiHeap14SlackFreeSpaceEv @ 8 NONAME
+ _ZN14CMemSpyApiHeap16AllocationsCountEv @ 9 NONAME
+ _ZN14CMemSpyApiHeap16TotalAllocationsEv @ 10 NONAME
+ _ZN14CMemSpyApiHeap17BiggestAllocationEv @ 11 NONAME
+ _ZN14CMemSpyApiHeap18AllocationOverheadEv @ 12 NONAME
+ _ZN14CMemSpyApiHeap21DebugAllocatorLibraryEv @ 13 NONAME
+ _ZN14CMemSpyApiHeap4SizeEv @ 14 NONAME
+ _ZN14CMemSpyApiHeap4TypeEv @ 15 NONAME
+ _ZN14CMemSpyApiHeap6SharedEv @ 16 NONAME
+ _ZN14CMemSpyApiHeap8OverheadEv @ 17 NONAME
+ _ZN14CMemSpyApiHeap9ChunkSizeEv @ 18 NONAME
+ _ZN14CMemSpyApiHeap9FreeCountEv @ 19 NONAME
+ _ZN14CMemSpyApiHeap9MaxLengthEv @ 20 NONAME
+ _ZN14CMemSpyApiHeap9MinLengthEv @ 21 NONAME
+ _ZN14CMemSpyApiHeap9TotalFreeEv @ 22 NONAME
+ _ZN14CMemSpyApiHeapD1Ev @ 23 NONAME
+ _ZN14CMemSpyApiHeapD2Ev @ 24 NONAME
+ _ZN14RMemSpySession10EndProcessE10TProcessId14TMemSpyEndType @ 25 NONAME
+ _ZN14RMemSpySession11GetThreadsLE10TProcessIdR6RArrayIP16CMemSpyApiThreadE9TSortType @ 26 NONAME
+ _ZN14RMemSpySession13GetProcessesLER6RArrayIP17CMemSpyApiProcessE9TSortType @ 27 NONAME
+ _ZN14RMemSpySession14SwitchToThreadE9TThreadIdi @ 28 NONAME
+ _ZN14RMemSpySession15SwitchToProcessE10TProcessIdi @ 29 NONAME
+ _ZN14RMemSpySession16GetKernelObjectsER6RArrayIP22CMemSpyApiKernelObjectE @ 30 NONAME
+ _ZN14RMemSpySession20GetKernelObjectItemsER6RArrayIP26CMemSpyApiKernelObjectItemE26TMemSpyDriverContainerType @ 31 NONAME
+ _ZN14RMemSpySession31ThreadSystemPermanentOrCriticalE9TThreadIdi @ 32 NONAME
+ _ZN14RMemSpySession32ProcessSystemPermanentOrCriticalE10TProcessIdi @ 33 NONAME
+ _ZN14RMemSpySession7ConnectEv @ 34 NONAME
+ _ZN14RMemSpySession7GetHeapEv @ 35 NONAME
+ _ZN14RMemSpySession9EndThreadE9TThreadId14TMemSpyEndType @ 36 NONAME
+ _ZN14RMemSpySessionC1Ev @ 37 NONAME
+ _ZN14RMemSpySessionC2Ev @ 38 NONAME
+ _ZN16CMemSpyApiThreadD1Ev @ 39 NONAME
+ _ZN16CMemSpyApiThreadD2Ev @ 40 NONAME
+ _ZN17CMemSpyApiProcessD1Ev @ 41 NONAME
+ _ZN17CMemSpyApiProcessD2Ev @ 42 NONAME
+ _ZN22CMemSpyApiKernelObjectD1Ev @ 43 NONAME
+ _ZN22CMemSpyApiKernelObjectD2Ev @ 44 NONAME
+ _ZN26CMemSpyApiKernelObjectItem12OpenChannelsEv @ 45 NONAME
+ _ZN26CMemSpyApiKernelObjectItem15AddressOfServerEv @ 46 NONAME
+ _ZN26CMemSpyApiKernelObjectItem16AddressOfCodeSegEv @ 47 NONAME
+ _ZN26CMemSpyApiKernelObjectItem20AddressOfKernelOwnerEv @ 48 NONAME
+ _ZN26CMemSpyApiKernelObjectItem21AddressOfOwningThreadEv @ 49 NONAME
+ _ZN26CMemSpyApiKernelObjectItem22AddressOfOwningProcessEv @ 50 NONAME
+ _ZN26CMemSpyApiKernelObjectItem26AddressOfDataBssStackChunkEv @ 51 NONAME
+ _ZN26CMemSpyApiKernelObjectItemD1Ev @ 52 NONAME
+ _ZN26CMemSpyApiKernelObjectItemD2Ev @ 53 NONAME
+ _ZNK16CMemSpyApiThread10AttributesEv @ 54 NONAME
+ _ZNK16CMemSpyApiThread12RequestCountEv @ 55 NONAME
+ _ZNK16CMemSpyApiThread13ThreadHandlesEv @ 56 NONAME
+ _ZNK16CMemSpyApiThread14ProcessHandlesEv @ 57 NONAME
+ _ZNK16CMemSpyApiThread14ThreadPriorityEv @ 58 NONAME
+ _ZNK16CMemSpyApiThread15ProcessPriorityEv @ 59 NONAME
+ _ZNK16CMemSpyApiThread17ThreadNumberUsingEv @ 60 NONAME
+ _ZNK16CMemSpyApiThread18ProcessNumberUsingEv @ 61 NONAME
+ _ZNK16CMemSpyApiThread2IdEv @ 62 NONAME
+ _ZNK16CMemSpyApiThread3SIDEv @ 63 NONAME
+ _ZNK16CMemSpyApiThread3VIDEv @ 64 NONAME
+ _ZNK16CMemSpyApiThread4NameEv @ 65 NONAME
+ _ZNK16CMemSpyApiThread6CpuUseEv @ 66 NONAME
+ _ZNK16CMemSpyApiThread8ExitTypeEv @ 67 NONAME
+ _ZNK16CMemSpyApiThread9ProcessIdEv @ 68 NONAME
+ _ZNK17CMemSpyApiProcess10ExitReasonEv @ 69 NONAME
+ _ZNK17CMemSpyApiProcess11ThreadCountEv @ 70 NONAME
+ _ZNK17CMemSpyApiProcess12ExitCategoryEv @ 71 NONAME
+ _ZNK17CMemSpyApiProcess2IdEv @ 72 NONAME
+ _ZNK17CMemSpyApiProcess4NameEv @ 73 NONAME
+ _ZNK17CMemSpyApiProcess8ExitTypeEv @ 74 NONAME
+ _ZNK22CMemSpyApiKernelObject4NameEv @ 75 NONAME
+ _ZNK22CMemSpyApiKernelObject4SizeEv @ 76 NONAME
+ _ZNK22CMemSpyApiKernelObject4TypeEv @ 77 NONAME
+ _ZNK22CMemSpyApiKernelObject5CountEv @ 78 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem10AttributesEv @ 79 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem10NameDetailEv @ 80 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem10ProtectionEv @ 81 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem10TimerStateEv @ 82 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem11AccessCountEv @ 83 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem11NameOfOwnerEv @ 84 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem11SessionTypeEv @ 85 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem12RestrictionsEv @ 86 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem12SecurityZoneEv @ 87 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem14SvrSessionTypeEv @ 88 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem16ControllingOwnerEv @ 89 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem16TotalAccessCountEv @ 90 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem2IdEv @ 91 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem3TopEv @ 92 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem4NameEv @ 93 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem4SizeEv @ 94 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem4TypeEv @ 95 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem5CountEv @ 96 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem5OrderEv @ 97 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem5StateEv @ 98 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem6BottomEv @ 99 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem6HandleEv @ 100 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem7ChangesEv @ 101 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem7MapAttrEv @ 102 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem7MaxSizeEv @ 103 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem7VersionEv @ 104 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem8MapCountEv @ 105 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem8MsgCountEv @ 106 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem8MsgLimitEv @ 107 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem8PriorityEv @ 108 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem8StartPosEv @ 109 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem8UniqueIDEv @ 110 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem9ChunkTypeEv @ 111 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem9CreatorIdEv @ 112 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem9ParseMaskEv @ 113 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem9ResettingEv @ 114 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem9TimerTypeEv @ 115 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem9UnitsMaskEv @ 116 NONAME
+ _ZNK26CMemSpyApiKernelObjectItem9WaitCountEv @ 117 NONAME
+ _ZN14RMemSpySession18SetThreadPriorityLE9TThreadIdi @ 118 NONAME
+ _ZN14RMemSpySession19GetProcessIdByNameLERK7TDesC16 @ 119 NONAME
+ _ZN14RMemSpySession20OutputKernelObjectsLE17TMemSpyOutputType @ 120 NONAME
+ _ZN14RMemSpySession21OutputKernelHeapDataLE17TMemSpyOutputType @ 121 NONAME
+ _ZN14RMemSpySession21OutputThreadCellListLE17TMemSpyOutputType9TThreadId @ 122 NONAME
+ _ZN14RMemSpySession21OutputThreadHeapDataLE17TMemSpyOutputType9TThreadId @ 123 NONAME
+ _ZN14RMemSpySession22OutputCompactHeapInfoLE17TMemSpyOutputType @ 124 NONAME
+ _ZN14RMemSpySession23OutputCompactStackInfoLE17TMemSpyOutputType @ 125 NONAME
+ _ZN14RMemSpySession14DumpKernelHeapEv @ 126 NONAME
+ _ZN14RMemSpySession15GetInfoItemTypeEi9TThreadIdR25TMemSpyThreadInfoItemType @ 127 NONAME
+ _ZN14RMemSpySession18GetThreadInfoItemsER6RArrayIP24CMemSpyApiThreadInfoItemE9TThreadId25TMemSpyThreadInfoItemType @ 128 NONAME
+ _ZN14RMemSpySession26OutputAllContainerContentsEv @ 129 NONAME
+ _ZN24CMemSpyApiThreadInfoItemD1Ev @ 130 NONAME
+ _ZN24CMemSpyApiThreadInfoItemD2Ev @ 131 NONAME
+ _ZNK17CMemSpyApiProcess3SIDEv @ 132 NONAME
+ _ZNK17CMemSpyApiProcess3VIDEv @ 133 NONAME
+ _ZNK17CMemSpyApiProcess8PriorityEv @ 134 NONAME
+ _ZNK24CMemSpyApiThreadInfoItem5ValueEv @ 135 NONAME
+ _ZNK24CMemSpyApiThreadInfoItem7CaptionEv @ 136 NONAME
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/memspy/MemSpyClient/group/MemSpyClient.mmp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,55 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include <data_caging_paths.hrh>
+#include <platform_paths.hrh>
+
+TARGETTYPE dll
+TARGET MemSpyClient.dll
+UID 0 0x2002EA8E
+VENDORID VID_DEFAULT
+SMPSAFE
+
+CAPABILITY PowerMgmt SwEvent ReadUserData WriteUserData ReadDeviceData WriteDeviceData
+
+SOURCEPATH ../src
+SOURCE memspysession.cpp
+SOURCE memspyapiprocess.cpp
+SOURCE memspyapikernelobject.cpp
+SOURCE memspyapiheap.cpp
+SOURCE memspyapikernelobjectitem.cpp
+SOURCE memspyapithread.cpp
+SOURCE memspyapithreadinfoitem.cpp
+
+USERINCLUDE ../inc
+
+OS_LAYER_SYSTEMINCLUDE
+
+LIBRARY euser.lib
+LIBRARY ecom.lib
+LIBRARY efsrv.lib
+LIBRARY estor.lib
+LIBRARY bafl.lib
+LIBRARY ws32.lib
+LIBRARY cone.lib
+LIBRARY eikcore.lib
+LIBRARY fbscli.lib
+LIBRARY PlatformEnv.lib
+
+LIBRARY MemSpyEngine.lib
+
+EXPORTUNFROZEN
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/memspy/MemSpyClient/group/bld.inf Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,37 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include <platform_paths.hrh>
+
+PRJ_EXPORTS
+// Public API
+../inc/memspysession.h OS_LAYER_PLATFORM_EXPORT_PATH(memspysession.h)
+../inc/memspyprocessdata.h OS_LAYER_PLATFORM_EXPORT_PATH(memspy/engine/memspyprocessdata.h)
+../inc/memspykernelobjectdata.h OS_LAYER_PLATFORM_EXPORT_PATH(memspy/engine/memspykernelobjectdata.h)
+../inc/memspyheapdata.h OS_LAYER_PLATFORM_EXPORT_PATH(memspy/engine/memspyheapdata.h)
+../inc/memspythreaddata.h OS_LAYER_PLATFORM_EXPORT_PATH(memspy/engine/memspythreaddata.h)
+../inc/memspythreadinfoitemdata.h OS_LAYER_PLATFORM_EXPORT_PATH(memspy/engine/memspythreadinfoitemdata.h)
+
+../inc/memspyapiprocess.h OS_LAYER_PLATFORM_EXPORT_PATH(memspy/api/memspyapiprocess.h)
+../inc/memspyapikernelobject.h OS_LAYER_PLATFORM_EXPORT_PATH(memspy/api/memspyapikernelobject.h)
+../inc/memspyapikernelobjectitem.h OS_LAYER_PLATFORM_EXPORT_PATH(memspy/api/memspyapikernelobjectitem.h)
+../inc/memspyapiheap.h OS_LAYER_PLATFORM_EXPORT_PATH(memspy/api/memspyapiheap.h)
+../inc/memspyapithread.h OS_LAYER_PLATFORM_EXPORT_PATH(memspy/api/memspyapithread.h)
+../inc/memspyapithreadinfoitem.h OS_LAYER_PLATFORM_EXPORT_PATH(memspy/api/memspyapithreadinfoitem.h)
+
+PRJ_MMPFILES
+MemSpyClient.mmp
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/memspy/MemSpyClient/inc/memspyapiprocess.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,65 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+* Contains the declaration of CMemSpyProcess class
+*/
+
+#ifndef MEMSPYAPIPROCESS_H
+#define MEMSPYAPIPROCESS_H
+
+// System includes
+#include <e32base.h>
+
+class TMemSpyProcessData;
+
+NONSHARABLE_CLASS( CMemSpyApiProcess )
+ {
+public:
+ IMPORT_C ~CMemSpyApiProcess();
+
+ static CMemSpyApiProcess* NewL(const TMemSpyProcessData& aData);
+
+ static CMemSpyApiProcess* NewLC(const TMemSpyProcessData& aData);
+
+public:
+ IMPORT_C TProcessId Id() const;
+
+ IMPORT_C const TDesC& Name() const;
+
+ IMPORT_C TExitCategoryName ExitCategory() const;
+
+ IMPORT_C TInt ExitReason() const;
+
+ IMPORT_C TExitType ExitType() const;
+
+ IMPORT_C TInt ThreadCount() const;
+
+ IMPORT_C TUint32 SID() const;
+
+ IMPORT_C TUint32 VID() const;
+
+ IMPORT_C TProcessPriority Priority() const;
+
+
+private:
+ CMemSpyApiProcess();
+
+ void ConstructL(const TMemSpyProcessData& aData);
+
+private:
+ TMemSpyProcessData *iProcessData;
+};
+
+
+#endif // MEMSPYAPIPROCESS_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/memspy/MemSpyClient/inc/memspyapithreadinfoitem.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,50 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+* Contains the declaration of CMemSpyProcess class
+*/
+
+#ifndef MEMSPYAPITHREADINFOITEM_H
+#define MEMSPYAPITHREADINFOITEM_H
+
+// System includes
+#include <e32base.h>
+
+class TMemSpyThreadInfoItemData;
+
+NONSHARABLE_CLASS( CMemSpyApiThreadInfoItem )
+ {
+public:
+ IMPORT_C ~CMemSpyApiThreadInfoItem();
+
+ static CMemSpyApiThreadInfoItem* NewL(const TMemSpyThreadInfoItemData& aData);
+
+ static CMemSpyApiThreadInfoItem* NewLC(const TMemSpyThreadInfoItemData& aData);
+
+public:
+ IMPORT_C const TDesC& Caption() const;
+
+ IMPORT_C const TDesC& Value() const;
+
+private:
+ CMemSpyApiThreadInfoItem();
+
+ void ConstructL(const TMemSpyThreadInfoItemData& aData);
+
+private:
+ TMemSpyThreadInfoItemData *iInfoItem;
+};
+
+
+#endif // MEMSPYAPITHREADINFOITEM_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/memspy/MemSpyClient/inc/memspykernelobjectdata.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,43 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+* Contains the declaration of TMemSpyProcessData class
+*/
+
+#ifndef MEMSPYKERNELOBJECTDATA_H
+#define MEMSPYKERNELOBJECTDATA_H
+
+#include <memspy/driver/memspydriverenumerationsshared.h>
+
+// Constants
+const TInt KBufSize = 128;
+
+// TMemSpyProcess data class holds data to be sent to the UI
+class TMemSpyKernelObjectData
+ {
+public:
+ //constructor & destructor
+ inline TMemSpyKernelObjectData()
+ : iCount(0), iSize(0)
+ {
+ }
+
+public:
+ TMemSpyDriverContainerType iType;
+ TFullName iName;
+ TInt iCount;
+ TInt64 iSize;
+ };
+
+#endif // MEMSPYKERNELOBJECTDATA_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/memspy/MemSpyClient/inc/memspyprocessdata.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+* Contains the declaration of TMemSpyProcessData class
+*/
+
+#ifndef MEMSPYPROCESSDATA_H
+#define MEMSPYPROCESSDATA_H
+
+#include <memspy/driver/memspydriverobjectsshared.h>
+
+// TMemSpyProcess data class holds data to be sent to the UI
+class TMemSpyProcessData
+ {
+public:
+ //constructor & destructor
+ inline TMemSpyProcessData()
+ : iId(0), iThreadCount(0), iExitCategory(0), iExitReason(0)
+ {
+ }
+
+public:
+ TProcessId iId;
+ TFullName iName;
+ TProcessPriority iPriority;
+ TExitCategoryName iExitCategory;
+ TInt iExitReason;
+ TExitType iExitType;
+ TInt iThreadCount;
+ TUint32 iSID;
+ TUint32 iVID;
+ //TMemSpyDriverProcessInfo iInfo;
+ };
+
+#endif // MEMSPYPROCESSDATA_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/memspy/MemSpyClient/inc/memspysession.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,134 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef MEMSPYSESSION_H
+#define MEMSPYSESSION_H
+
+
+// System includes
+#include <e32base.h>
+#include <u32std.h>
+
+//user includes
+#include <memspy/engine/memspyprocessdata.h> //for Processes
+#include <memspy/api/memspyapiprocess.h>
+
+#include <memspy/engine/memspythreaddata.h> //for Threads
+#include <memspy/api/memspyapithread.h>
+#include <memspy/api/memspyapithreadinfoitem.h>
+#include <memspy/engine/memspythreadinfoitemdata.h>
+#include <memspy/engine/memspyengineobjectthreadinfoobjects.h>
+
+#include <memspy/engine/memspykernelobjectdata.h> //for KernelObjects
+#include <memspy/api/memspyapikernelobject.h>
+
+#include <memspy/api/memspyapikernelobjectitem.h> //for KernelObjectItems
+
+#include <memspy/engine/memspyheapdata.h> //for Heap
+#include <memspy/api/memspyapiheap.h>
+
+#include <memspyengineclientinterface.h>
+
+// Constants
+const TInt KMemSpyVersion = 2;
+
+enum TSortType
+ {
+ ESortProcById,
+ ESortProcByName,
+ ESortProcByThreadCount,
+ ESortProcByCodeSegs,
+ ESortProcByHeapUsage,
+ ESortProcByStackUsage
+ };
+
+enum TMemSpyOutputType
+ {
+ EOutputTypeDebug = 0,
+ EOutputTypeFile
+ };
+
+
+NONSHARABLE_CLASS( RMemSpySession ) : public RSessionBase
+ {
+public:
+ IMPORT_C RMemSpySession();
+ IMPORT_C TInt Connect();
+
+public: //API
+ IMPORT_C void OutputKernelHeapDataL(TMemSpyOutputType aOutputType); //EMemSpyClientServerOpHeapData
+ IMPORT_C void OutputThreadHeapDataL(TMemSpyOutputType aOutputType, TThreadId aThreadId); //EMemSpyClientServerOpHeapData
+ IMPORT_C void OutputThreadCellListL(TMemSpyOutputType aOutputType, TThreadId aThreadId);//EMemSpyClientServerOpHeapCellListing
+ IMPORT_C void OutputKernelObjectsL(TMemSpyOutputType aOutputType);// EMemSpyClientServerOpEnumerateKernelContainerAll
+ IMPORT_C void OutputCompactStackInfoL(TMemSpyOutputType aOutputType);// EMemSpyClientServerOpStackInfoCompact
+ IMPORT_C void OutputCompactHeapInfoL(TMemSpyOutputType aOutputType);// EMemSpyClientServerOpHeapInfoCompact
+
+ IMPORT_C void GetProcessesL(RArray<CMemSpyApiProcess*> &aProcesses, TSortType aSortType = ESortProcById);
+
+ IMPORT_C TProcessId GetProcessIdByNameL(const TDesC& aProcessName);
+
+ IMPORT_C void GetThreadsL(TProcessId aProcessId, RArray<CMemSpyApiThread*> &aThreads, TSortType aSortType = ESortProcById);
+
+ IMPORT_C TInt ProcessSystemPermanentOrCritical( TProcessId aId, TBool aValue ); //aValue -> return value
+
+ IMPORT_C void SetThreadPriorityL(TThreadId aId, TInt aPriority);
+ IMPORT_C TInt EndProcess( TProcessId aId, TMemSpyEndType aType );
+
+ IMPORT_C TInt SwitchToProcess( TProcessId aId, TBool aBrought );
+
+
+ //Threads operations
+ /**
+ *
+ */
+ IMPORT_C void GetThreadsL(TProcessId aProcessId, RArray<CMemSpyApiProcess*> &aThreads, TSortType aSortType = ESortProcById);
+
+ IMPORT_C TInt ThreadSystemPermanentOrCritical( TThreadId aId, TBool aValue );
+
+ IMPORT_C TInt EndThread( TThreadId aId, TMemSpyEndType aType );
+
+ IMPORT_C TInt SwitchToThread( TThreadId aId, TBool aBrought );
+
+ IMPORT_C TInt GetInfoItemType( TInt aIndex, TThreadId aId, TMemSpyThreadInfoItemType &aType );
+
+ IMPORT_C void GetThreadInfoItems( RArray<CMemSpyApiThreadInfoItem*> &aInfoItems, TThreadId aId, TMemSpyThreadInfoItemType aType );
+
+ //KernelObjects operations
+ /**
+ *
+ */
+ IMPORT_C TInt GetKernelObjects( RArray<CMemSpyApiKernelObject*> &aKernelObjects );
+
+ IMPORT_C TInt GetKernelObjectItems( RArray<CMemSpyApiKernelObjectItem*> &aKernelObjectItems, TMemSpyDriverContainerType aForContainer );
+
+ IMPORT_C void OutputAllContainerContents();
+
+ /**
+ *
+ */
+ IMPORT_C CMemSpyApiHeap* GetHeap();
+
+ IMPORT_C void DumpKernelHeap();
+
+private:
+ TInt StartServer();
+
+ void SetOutputTypeL(TMemSpyOutputType aOutputType);
+ };
+
+#endif // MEMSPYSESSION_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/memspy/MemSpyClient/inc/memspythreadinfoitemdata.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,39 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+* Contains the declaration of TMemSpyProcessData class
+*/
+
+#ifndef MEMSPYTHREADINFOITEMDATA_H
+#define MEMSPYTHREADINFOITEMDATA_H
+
+#include <memspy/driver/memspydriverobjectsshared.h>
+
+const TInt KMaxBufSize = 32;
+
+// TMemSpyProcess data class holds data to be sent to the UI
+class TMemSpyThreadInfoItemData
+ {
+public:
+ //constructor & destructor
+ inline TMemSpyThreadInfoItemData()
+ {
+ }
+
+public:
+ TBuf<KMaxBufSize> iCaption;
+ TBuf<KMaxBufSize> iValue;
+ };
+
+#endif // MEMSPYTHREADINFOITEMDATA_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/memspy/MemSpyClient/src/memspyapiprocess.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,98 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include <memspy/api/memspyapiprocess.h>
+#include <memspy/engine/memspyengine.h>
+#include <memspy/engine/memspyprocessdata.h>
+#include <memspy/engine/memspyengineobjectprocess.h>
+#include <memspy/engine/memspyengineobjectcontainer.h>
+
+
+EXPORT_C CMemSpyApiProcess::~CMemSpyApiProcess()
+ {
+ delete iProcessData;
+ }
+
+EXPORT_C TProcessId CMemSpyApiProcess::Id() const
+ {
+ return iProcessData->iId;
+ }
+
+EXPORT_C const TDesC& CMemSpyApiProcess::Name() const
+ {
+ return iProcessData->iName;
+ }
+
+EXPORT_C TExitCategoryName CMemSpyApiProcess::ExitCategory() const
+ {
+ return iProcessData->iExitCategory;
+ }
+
+EXPORT_C TInt CMemSpyApiProcess::ExitReason() const
+ {
+ return iProcessData->iExitReason;
+ }
+
+EXPORT_C TExitType CMemSpyApiProcess::ExitType() const
+ {
+ return iProcessData->iExitType;
+ }
+
+EXPORT_C TInt CMemSpyApiProcess::ThreadCount() const
+ {
+ return iProcessData->iThreadCount;
+ }
+
+EXPORT_C TUint32 CMemSpyApiProcess::SID() const
+ {
+ return iProcessData->iSID;
+ }
+
+EXPORT_C TUint32 CMemSpyApiProcess::VID() const
+ {
+ return iProcessData->iSID;
+ }
+
+EXPORT_C TProcessPriority CMemSpyApiProcess::Priority() const
+ {
+ return iProcessData->iPriority;
+ }
+
+CMemSpyApiProcess::CMemSpyApiProcess() : iProcessData(0)
+ {
+ }
+
+void CMemSpyApiProcess::ConstructL(const TMemSpyProcessData& aData)
+ {
+ iProcessData = new (ELeave) TMemSpyProcessData(aData);
+ }
+
+CMemSpyApiProcess* CMemSpyApiProcess::NewL(const TMemSpyProcessData& aData)
+ {
+ CMemSpyApiProcess* self = CMemSpyApiProcess::NewLC(aData);
+ CleanupStack::Pop(self);
+ return (self);
+ }
+
+CMemSpyApiProcess* CMemSpyApiProcess::NewLC(const TMemSpyProcessData& aData)
+ {
+ CMemSpyApiProcess* self = new (ELeave) CMemSpyApiProcess;
+ CleanupStack::PushL(self);
+ self->ConstructL(aData);
+ return (self);
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/memspy/MemSpyClient/src/memspyapithreadinfoitem.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,60 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include <memspy/api/memspyapithreadinfoitem.h>
+#include <memspy/engine/memspyengine.h>
+#include <memspy/engine/memspythreadinfoitemdata.h>
+
+EXPORT_C CMemSpyApiThreadInfoItem::~CMemSpyApiThreadInfoItem()
+ {
+ delete iInfoItem;
+ }
+
+EXPORT_C const TDesC& CMemSpyApiThreadInfoItem::Caption() const
+ {
+ return iInfoItem->iCaption;
+ }
+
+EXPORT_C const TDesC& CMemSpyApiThreadInfoItem::Value() const
+ {
+ return iInfoItem->iValue;
+ }
+
+CMemSpyApiThreadInfoItem::CMemSpyApiThreadInfoItem() : iInfoItem(0)
+ {
+ }
+
+void CMemSpyApiThreadInfoItem::ConstructL(const TMemSpyThreadInfoItemData& aData)
+ {
+ iInfoItem = new (ELeave) TMemSpyThreadInfoItemData(aData);
+ }
+
+CMemSpyApiThreadInfoItem* CMemSpyApiThreadInfoItem::NewL(const TMemSpyThreadInfoItemData& aData)
+ {
+ CMemSpyApiThreadInfoItem* self = CMemSpyApiThreadInfoItem::NewLC(aData);
+ CleanupStack::Pop(self);
+ return (self);
+ }
+
+CMemSpyApiThreadInfoItem* CMemSpyApiThreadInfoItem::NewLC(const TMemSpyThreadInfoItemData& aData)
+ {
+ CMemSpyApiThreadInfoItem* self = new (ELeave) CMemSpyApiThreadInfoItem;
+ CleanupStack::PushL(self);
+ self->ConstructL(aData);
+ return (self);
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/memspy/MemSpyClient/src/memspysession.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,501 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include "memspysession.h"
+#include <memspyengineclientinterface.h>
+
+#include <memspy/api/memspyapiprocess.h>
+#include <memspy/api/memspyapikernelobject.h>
+#include <memspy/api/memspyapikernelobjectitem.h>
+#include <memspy/api/memspyapithreadinfoitem.h>
+//KernelObjects
+#include <memspy/driver/memspydriverenumerationsshared.h>
+// IMPLEMENTATION
+
+EXPORT_C RMemSpySession::RMemSpySession()
+ {
+ }
+
+
+EXPORT_C TInt RMemSpySession::Connect()
+ {
+ TInt error(KErrNone);
+
+ for (TInt i=0; i<2; i++) // Two retries max
+ {
+ TInt error = CreateSession(KMemSpyServerName, TVersion(KMemSpyVersion, 0, 0));
+
+ if (error != KErrNotFound && error != KErrServerTerminated)
+ return error;
+
+ error = StartServer();
+
+ if (error != KErrNone && error != KErrAlreadyExists)
+ return error;
+ }
+
+ return error;
+ }
+
+TInt RMemSpySession::StartServer()
+ {
+ RProcess server;
+ _LIT(KCommand, "start");
+ const TUid KServerUid3 = {0xE5883BC2};
+ TInt error = server.Create(KMemSpyServerName, KCommand);//, KServerUid3);
+
+ if (error != KErrNone)
+ return error;
+
+ TRequestStatus startStatus, stopStatus;
+ server.Logon(stopStatus);
+ if (stopStatus != KRequestPending)
+ {
+ User::WaitForRequest(stopStatus);
+ server.Kill(0);
+ server.Close();
+ return stopStatus.Int();
+ }
+
+ server.Rendezvous(startStatus);
+ server.Resume();
+ User::WaitForRequest(startStatus, stopStatus);
+ if (startStatus == KRequestPending)
+ {
+ // not started yet, i.e. stopStatus was signaled
+ server.Close();
+ return stopStatus.Int();
+ }
+
+ // Rendezvous was called - the server is ready
+
+ // We first need to cancel Logon
+ server.LogonCancel(stopStatus);
+ // We don't need this anymore
+ server.Close();
+ // Wait for LogonCancel to complete
+ User::WaitForRequest(stopStatus);
+
+ // Everything went OK
+ return KErrNone;
+ }
+
+//inline void RMemSpySession::Close()
+// {
+// RSessionBase::Close();
+// }
+//
+//inline TMemSpySinkType RMemSpySession::GetSinkType()
+// {
+// TPckgBuf<TMemSpySinkType> OutBuf;
+// TIpcArgs args( &OutBuf );
+// SendReceive( EGetSinkType, args );
+// return OutBuf();
+// }
+//
+//inline void RMemSpySession::OutputKernelObjects()
+// {
+// SendReceive( EOutputKernelObjects );
+// }
+//
+//inline void RMemSpySession::OutputToDebug()
+// {
+// SendReceive( EOutputToDebug );
+// }
+//
+//inline void RMemSpySession::OutputToFile()
+// {
+// SendReceive( EOutputToFile );
+// }
+//
+//inline void RMemSpySession::SetServerTimeOutStatus( TUint32 aValue, TBool aEnabled )
+// {
+// TPckgBuf<TUint32> In1(aValue);
+// TPckgBuf<TBool> In2(aEnabled);
+// TIpcArgs args( &In1, &In2 );
+// SendReceive( ESetServerTimeOutStatus, args );
+// }
+
+//inline void RMemSpySession::OutputProcessInfo( TMemSpyProcess aProcess )
+// {
+// TProcessId iId = aProcess.iId;
+// TPckgBuf<TProcessId> In( iId );
+// TIpcArgs args( &In );
+// SendReceive( EOutputProcessInfo, args );
+// }
+
+////Processes operations
+//inline TInt RMemSpySession::ProcessesCount()
+// {
+// TPckgBuf<TInt> Out;
+// TIpcArgs args( &Out );
+// SendReceive( EProcessesCount, args );
+// return Out();
+// }
+//
+//inline TMemSpyProcess RMemSpySession::GetProcessByIndex( TInt aIndex )
+// {
+// TPckgBuf<TInt> In( aIndex );
+// TPckgBuf<TMemSpyProcess> Out;
+// TIpcArgs args( &In, &Out );
+// SendReceive( EProcessByIndex, args );
+// return Out();
+// }
+//
+//inline TInt RMemSpySession::ProcessIndexById( TProcessId aId )
+// {
+// TPckgBuf<TProcessId> In( aId );
+// TPckgBuf<TInt> Out;
+// TIpcArgs args( &In, &Out );
+// SendReceive( EProcessIndexById, args );
+// return Out();
+// }
+//
+//inline TBool RMemSpySession::ProcessIsDead( TMemSpyProcess aProcess )
+// {
+// TProcessId iId = aProcess.iId;
+// TPckgBuf<TProcessId> In( iId );
+// TPckgBuf<TBool> Out;
+// TIpcArgs args( &In, &Out );
+// SendReceive( EProcessIsDead, args );
+// return Out();
+// }
+
+EXPORT_C void RMemSpySession::GetProcessesL(RArray<CMemSpyApiProcess*> &aProcesses, TSortType aSortType)
+ {
+ TPckgBuf<TInt> count;
+ User::LeaveIfError(SendReceive(EMemSpyClientServerOpGetProcessCount, TIpcArgs(&count)));
+
+ TInt requestedCount = count();
+ HBufC8* buffer = HBufC8::NewLC(requestedCount * sizeof(TMemSpyProcessData));
+ TPtr8 bufferPtr(buffer->Des());
+
+ User::LeaveIfError(SendReceive(EMemSpyClientServerOpGetProcesses, TIpcArgs(&count, &bufferPtr)));
+ aProcesses.Reset();
+
+ TInt receivedCount = Min(count(), requestedCount);
+ for(TInt i=0, offset = 0; i<requestedCount; i++, offset+=sizeof(TMemSpyProcessData))
+ {
+ TPckgBuf<TMemSpyProcessData> data;
+ data.Copy(bufferPtr.Ptr()+offset, sizeof(TMemSpyProcessData));
+ aProcesses.AppendL(CMemSpyApiProcess::NewLC(data()));
+ }
+ CleanupStack::Pop(aProcesses.Count());
+ CleanupStack::PopAndDestroy(buffer);
+ }
+
+EXPORT_C TProcessId RMemSpySession::GetProcessIdByNameL(const TDesC& aProcessName)
+ {
+ TPckgBuf<TProcessId> procId;
+ User::LeaveIfError(SendReceive(EMemSpyClienServerOpGetProcessIdByName,
+ TIpcArgs(&aProcessName, &procId)));
+
+ return procId();
+ }
+
+EXPORT_C TInt RMemSpySession::ProcessSystemPermanentOrCritical( TProcessId aId, TBool aValue )
+ {
+ TPckgBuf<TProcessId> arg1( aId );
+ TPckgBuf<TBool> arg2( aValue );
+ TIpcArgs args( &arg1, &arg2 );
+
+ TInt error = SendReceive( EMemSpyClientServerOpProcessSystemPermanentOrCritical, args );
+
+ return error;
+ }
+
+EXPORT_C TInt RMemSpySession::EndProcess( TProcessId aId, TMemSpyEndType aType )
+ {
+ TPckgBuf<TProcessId> arg1( aId );
+ TPckgBuf<TMemSpyEndType> arg2( aType );
+ TIpcArgs args( &arg1, &arg2 );
+
+ TInt error = SendReceive( EMemSpyClientServerOpEndProcess, args );
+
+ return error;
+ }
+
+EXPORT_C TInt RMemSpySession::SwitchToProcess( TProcessId aId, TBool aBrought )
+ {
+ TPckgBuf<TProcessId> arg1( aId );
+ TPckgBuf<TBool> arg2( aBrought );
+ TIpcArgs args( &arg1, &arg2 );
+
+ TInt error = SendReceive( EMemSpyClientServerOpSwitchToProcess, args );
+
+ return error;
+ }
+
+EXPORT_C void RMemSpySession::GetThreadsL(TProcessId aProcessId, RArray<CMemSpyApiThread*> &aThreads, TSortType aSortType)
+ {
+ TPckgBuf<TInt> count;
+ TPckgBuf<TProcessId> pid(aProcessId);
+ User::LeaveIfError(SendReceive(EMemSpyClientServerOpGetThreadCount, TIpcArgs(&count, &pid)));
+
+ TInt requestedCount = count();
+ HBufC8* buffer = HBufC8::NewLC(requestedCount * sizeof(TMemSpyThreadData));
+ TPtr8 bufferPtr(buffer->Des());
+
+ User::LeaveIfError(SendReceive(EMemSpyClientServerOpGetThreads, TIpcArgs(&count, &bufferPtr, &pid)));
+ aThreads.Reset();
+
+ TInt receivedCount = Min(count(), requestedCount);
+ for(TInt i=0, offset = 0; i<requestedCount; i++, offset+=sizeof(TMemSpyThreadData))
+ {
+ TPckgBuf<TMemSpyThreadData> data;
+ data.Copy(bufferPtr.Ptr()+offset, sizeof(TMemSpyThreadData));
+ aThreads.AppendL(CMemSpyApiThread::NewLC(data()));
+ }
+ CleanupStack::Pop(aThreads.Count());
+ CleanupStack::PopAndDestroy(buffer);
+ }
+
+EXPORT_C void RMemSpySession::SetThreadPriorityL(TThreadId aId, TInt aPriority)
+ {
+ TPckgBuf<TThreadId> arg1( aId );
+ TPckgBuf<TInt> arg2( aPriority );
+
+ User::LeaveIfError(SendReceive( EMemSpyClientServerOpSetThreadPriority, TIpcArgs(&arg1, &arg2)));
+ }
+
+EXPORT_C TInt RMemSpySession::ThreadSystemPermanentOrCritical( TThreadId aId, TBool aValue )
+ {
+ TPckgBuf<TThreadId> arg1( aId );
+ TPckgBuf<TBool> arg2( aValue );
+ TIpcArgs args( &arg1, &arg2 );
+
+ TInt error = SendReceive( EMemSpyClientServerOpThreadSystemPermanentOrCritical, args );
+
+ return error;
+ }
+
+EXPORT_C TInt RMemSpySession::EndThread( TThreadId aId, TMemSpyEndType aType )
+ {
+ TPckgBuf<TThreadId> arg1( aId );
+ TPckgBuf<TMemSpyEndType> arg2( aType );
+ TIpcArgs args( &arg1, &arg2 );
+
+ TInt error = SendReceive( EMemSpyClientServerOpEndThread, args );
+
+ return error;
+ }
+
+EXPORT_C TInt RMemSpySession::SwitchToThread( TThreadId aId, TBool aBrought )
+ {
+ TPckgBuf<TThreadId> arg1( aId );
+ TPckgBuf<TBool> arg2( aBrought );
+ TIpcArgs args( &arg1, &arg2 );
+
+ TInt error = SendReceive( EMemSpyClientServerOpSwitchToThread, args );
+
+ return error;
+ }
+
+EXPORT_C TInt RMemSpySession::GetInfoItemType( TInt aIndex, TThreadId aId, TMemSpyThreadInfoItemType &aType )
+ {
+ TPckgBuf<TInt> arg1( aIndex );
+ TPckgBuf<TThreadId> arg2( aId );
+ TPckgBuf<TMemSpyThreadInfoItemType> arg3;
+ TIpcArgs args( &arg1, &arg2, &arg3 );
+
+ TInt error = SendReceive( EMemSpyClientServerOpGetInfoItemType, args );
+
+ aType = arg3();
+
+ return error;
+ }
+
+EXPORT_C void RMemSpySession::GetThreadInfoItems( RArray<CMemSpyApiThreadInfoItem*> &aInfoItems, TThreadId aId, TMemSpyThreadInfoItemType aType )
+ {
+ TPckgBuf<TThreadId> id( aId );
+ TPckgBuf<TMemSpyThreadInfoItemType> type( aType );
+ TPckgBuf<TInt> count;
+
+ TInt error = SendReceive( EMemSpyClientServerOpGetThreadInfoItemsCount, TIpcArgs( &id, &type, &count ) );
+ TInt itemCount = count();
+
+ if( error == KErrNone )
+ {
+ if( itemCount == 0 )
+ {
+ aInfoItems.Reset();
+ }
+ else
+ {
+ HBufC8* buffer = HBufC8::NewLC( itemCount * sizeof(TMemSpyThreadInfoItemData) );
+ TPtr8 bufferPtr(buffer->Des());
+
+ TPckgBuf<TInt> requestedCount( itemCount );
+
+ TIpcArgs args( &requestedCount, &id, &type, &bufferPtr );
+ TInt error = SendReceive( EMemSpyClientServerOpGetThreadInfoItems, args );
+
+ for(TInt i=0, offset = 0; i < itemCount; i++, offset+=sizeof(TMemSpyThreadInfoItemData))
+ {
+ TPckgBuf<TMemSpyThreadInfoItemData> data;
+ data.Copy(bufferPtr.Ptr()+offset, sizeof(TMemSpyThreadInfoItemData));
+ aInfoItems.AppendL(CMemSpyApiThreadInfoItem::NewL(data()));
+ }
+
+ CleanupStack::PopAndDestroy(buffer);
+ }
+ }
+ }
+
+//Kernel Objects specific operations
+EXPORT_C TInt RMemSpySession::GetKernelObjects( RArray<CMemSpyApiKernelObject*> &aKernelObjects )
+ {
+ TPckgBuf<TInt> count;
+ TInt error = SendReceive( EMemSpyClientServerOpGetKernelObjectCount, TIpcArgs(&count) );
+
+ if( error == KErrNone )
+ {
+ TInt requestedCount = count();
+ HBufC8* buffer = HBufC8::NewLC(requestedCount * sizeof(TMemSpyKernelObjectData));
+ TPtr8 bufferPtr(buffer->Des());
+
+ TPckgBuf<TInt> count(requestedCount);
+ TIpcArgs args( &count, &bufferPtr );
+ TInt error = SendReceive( EMemSpyClientServerOpGetKernelObjects, args );
+
+ for(TInt i=0, offset = 0; i<requestedCount; i++, offset+=sizeof(TMemSpyKernelObjectData))
+ {
+ TPckgBuf<TMemSpyKernelObjectData> data;
+ data.Copy(bufferPtr.Ptr()+offset, sizeof(TMemSpyKernelObjectData));
+ aKernelObjects.AppendL(CMemSpyApiKernelObject::NewL(data()));
+ }
+
+ CleanupStack::PopAndDestroy(buffer);
+ }
+ return KErrNone;
+ }
+
+EXPORT_C TInt RMemSpySession::GetKernelObjectItems( RArray<CMemSpyApiKernelObjectItem*> &aKernelObjectItems, TMemSpyDriverContainerType aForContainer )
+ {
+ TPckgBuf<TInt> count;
+ TPckgBuf<TMemSpyDriverContainerType> type(aForContainer);
+ TInt error = SendReceive( EMemSpyClientServerOpGetKernelObjectItemCount, TIpcArgs(&count, &type) );
+
+ if (error == KErrNone)
+ {
+ TInt requestedCount = count();
+ HBufC8* buffer = HBufC8::NewLC(requestedCount * sizeof(TMemSpyDriverHandleInfoGeneric));
+ TPtr8 bufferPtr(buffer->Des());
+
+ TPckgBuf<TInt> count(requestedCount);
+ TIpcArgs args( &count, &type, &bufferPtr );
+ TInt error = SendReceive( EMemSpyClientServerOpGetKernelObjectItems, args );
+
+ for(TInt i=0, offset = 0; i<requestedCount; i++, offset+=sizeof(TMemSpyDriverHandleInfoGeneric))
+ {
+ TPckgBuf<TMemSpyDriverHandleInfoGeneric> data;
+ data.Copy(bufferPtr.Ptr()+offset, sizeof(TMemSpyDriverHandleInfoGeneric));
+ aKernelObjectItems.AppendL( CMemSpyApiKernelObjectItem::NewL( data() ) );
+ }
+
+ CleanupStack::PopAndDestroy(buffer);
+ }
+ return KErrNone;
+ }
+
+EXPORT_C void RMemSpySession::OutputAllContainerContents()
+ {
+ SendReceive( EMemSpyClientServerOpOutputAllContainerContents );
+ }
+
+
+//Heap specific operations
+EXPORT_C CMemSpyApiHeap* RMemSpySession::GetHeap()
+ {
+ CMemSpyApiHeap* aHeap;
+ TInt error = KErrNone;
+
+ HBufC8* buffer = HBufC8::NewLC( sizeof(TMemSpyHeapData) );
+ TPtr8 bufferPtr(buffer->Des());
+ TIpcArgs args( &bufferPtr );
+
+ error = SendReceive( EMemSpyClientServerOpGetHeap, args );
+
+ if( error == KErrNone )
+ {
+ TPckgBuf<TMemSpyHeapData> data;
+ data.Copy(bufferPtr.Ptr(), sizeof(TMemSpyHeapData));
+ aHeap = CMemSpyApiHeap::NewL( data() );
+ }
+ CleanupStack::PopAndDestroy(buffer);
+
+ return aHeap;
+ }
+
+EXPORT_C void RMemSpySession::DumpKernelHeap()
+ {
+ SendReceive( EMemSpyClientServerOpDumpKernelHeap );
+ }
+
+EXPORT_C void RMemSpySession::OutputKernelHeapDataL(TMemSpyOutputType aOutputType)
+ {
+ SetOutputTypeL(aOutputType);
+
+ User::LeaveIfError(SendReceive(EMemSpyClientServerOpHeapData | KMemSpyOpFlagsIncludesThreadId,
+ TIpcArgs(KMemSpyClientServerThreadIdKernel)));
+
+ }
+EXPORT_C void RMemSpySession::OutputThreadHeapDataL(TMemSpyOutputType aOutputType, TThreadId aThreadId)
+ {
+ SetOutputTypeL(aOutputType);
+
+ User::LeaveIfError(SendReceive(EMemSpyClientServerOpHeapData | KMemSpyOpFlagsIncludesThreadId,
+ TIpcArgs(aThreadId)));
+ }
+EXPORT_C void RMemSpySession::OutputThreadCellListL(TMemSpyOutputType aOutputType, TThreadId aThreadId)
+ {
+ SetOutputTypeL(aOutputType);
+
+ User::LeaveIfError(SendReceive(EMemSpyClientServerOpHeapCellListing | KMemSpyOpFlagsIncludesThreadId,
+ TIpcArgs(aThreadId)));
+ }
+
+EXPORT_C void RMemSpySession::OutputKernelObjectsL(TMemSpyOutputType aOutputType)
+ {
+ SetOutputTypeL(aOutputType);
+
+ User::LeaveIfError(SendReceive(EMemSpyClientServerOpEnumerateKernelContainerAll));
+ }
+
+EXPORT_C void RMemSpySession::OutputCompactStackInfoL(TMemSpyOutputType aOutputType)
+ {
+ SetOutputTypeL(aOutputType);
+
+ User::LeaveIfError(SendReceive(EMemSpyClientServerOpStackInfoCompact));
+ }
+
+EXPORT_C void RMemSpySession::OutputCompactHeapInfoL(TMemSpyOutputType aOutputType)
+ {
+ SetOutputTypeL(aOutputType);
+
+ User::LeaveIfError(SendReceive(EMemSpyClientServerOpHeapInfoCompact));
+ }
+
+void RMemSpySession::SetOutputTypeL(TMemSpyOutputType aOutputType)
+ {
+ TInt operation = aOutputType == EOutputTypeFile ?
+ EMemSpyClientServerOpSwitchOutputSinkFile :
+ EMemSpyClientServerOpSwitchOutputSinkTrace;
+
+ User::LeaveIfError(SendReceive(operation));
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/memspy/MemSpyServer/Include/MemSpyServerSession.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,62 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+* MemSpyServer headder file to declare MemSpyServer class
+*
+*/
+
+#ifndef MEMSPYSERVERSESSION_H
+#define MEMSPYSERVERSESSION_H
+
+// System includes
+#include <e32base.h>
+#include <BADESCA.H>
+
+// User includes
+#include <memspyengineclientinterface.h>
+#include <memspy/engine/memspyengineobjectthreadinfoobjects.h>
+
+ // Classes referenced
+class CMemSpyEngine;
+
+
+NONSHARABLE_CLASS( CMemSpyServerSession ) : public CSession2
+ {
+public:
+ static CMemSpyServerSession* NewL( CMemSpyEngine& aEngine, const RMessage2& aMessage );
+ ~CMemSpyServerSession();
+
+private:
+ CMemSpyServerSession( CMemSpyEngine& aEngine );
+ void ConstructL( const RMessage2& aMessage );
+
+private: // From CSession2
+ void ServiceL( const RMessage2& aMessage );
+
+private: // Internal methods
+ void DoServiceL( const RMessage2& aMessage );
+ void DoUiServiceL( const RMessage2& aMessage );
+ void DoCmdServiceL( const RMessage2& aMessage );
+ static TInt ValidateFunction( TInt aFunction, TBool aIncludesThreadId, TBool aIncludesThreadName );
+ void HandleThreadSpecificOpL( TInt aFunction, const TThreadId& aThreadId );
+ void HandleThreadSpecificOpL( TInt aFunction, const TDesC& aThreadName );
+ void HandleThreadAgnosticOpL( TInt aFunction, const RMessage2& aMessage );
+
+private:
+ CMemSpyEngine& iEngine;
+ HBufC* iClientThreadName;
+ TUint32 iClientThreadId;
+ };
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/memspy/MemSpyServer/Source/MemSpyServerMain.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,75 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+* MemSpyServer Main class
+*/
+
+// System includes
+#include <e32std.h>
+#include <e32base.h>
+#include <f32file.h>
+
+// Engine includes
+#include <memspy/engine/memspyengine.h>
+
+// User includes
+//#include "MemSpyServer.h"
+
+static void RunServerL()
+ {
+ // Scheduler
+ CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
+ CleanupStack::PushL( scheduler );
+ CActiveScheduler::Install( scheduler );
+
+ // F32
+ RFs fsSession;
+ User::LeaveIfError(fsSession.Connect());
+ CleanupClosePushL(fsSession);
+
+ // MemSpyEngine initialization
+ CMemSpyEngine* engine = CMemSpyEngine::NewL(fsSession);
+ CleanupStack::PushL(engine);
+
+ // Play nicely with external processes
+ RProcess::Rendezvous( KErrNone );
+
+ // Start wait loop.
+ CActiveScheduler::Start();
+
+ // Tidy up
+ CleanupStack::PopAndDestroy( 3, scheduler );
+ }
+
+TInt E32Main()
+ {
+ __UHEAP_MARK;
+
+ CTrapCleanup* cleanupTrap = CTrapCleanup::New();
+
+ TInt r = KErrNoMemory;
+ if ( cleanupTrap )
+ {
+ TRAPD(err, RunServerL());
+ if ( err != KErrNone )
+ {
+ RDebug::Print(_L("[MemSpyCmdLine] E32Main() - MemSpyServer - error: %d"), err);
+ }
+ delete cleanupTrap;
+ }
+
+ __UHEAP_MARKEND;
+
+ return r;
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/memspy/MemSpyServer/Source/MemSpyServerSession.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,953 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+* Implementation of the new MemSpyServer
+*/
+
+// System includes
+#include <e32svr.h>
+#include <e32cmn.h>
+#include <e32base.h>
+#include <w32std.h>
+//#include <apgtask.h>
+//#include <apgwgnam.h>
+
+//user includes
+#include "MemSpyServerSession.h"
+
+// User includes
+#include <memspy/engine/memspyengine.h>
+#include <memspy/engine/memspyenginelogger.h>
+#include <memspyengineclientinterface.h>
+#include <memspy/engine/memspyengineobjectthread.h>
+#include <memspy/engine/memspyengineobjectprocess.h>
+#include <memspy/engine/memspyengineobjectcontainer.h>
+#include <memspy/engine/memspyenginehelperchunk.h>
+#include <memspy/engine/memspyenginehelpercodesegment.h>
+#include <memspy/engine/memspyenginehelperheap.h>
+#include <memspy/engine/memspyenginehelperstack.h>
+#include <memspy/engine/memspyenginehelperthread.h>
+#include <memspy/engine/memspyenginehelperprocess.h>
+#include <memspy/engine/memspyenginehelperfilesystem.h>
+#include <memspy/engine/memspyenginehelperram.h>
+#include <memspy/engine/memspyenginehelpersysmemtracker.h>
+#include <memspy/engine/memspyenginehelpersysmemtrackerconfig.h>
+#include <memspy/engine/memspyenginehelperkernelcontainers.h>
+#include <memspy/engine/memspyenginehelperserver.h>
+
+//cigasto
+#include <memspysession.h>
+//#include <memspy/driver/memspydriverclient.h>
+
+// ---------------------------------------------------------
+// CMemSpyServerSession( CMemSpyEngine& aEngine )
+// ---------------------------------------------------------
+//
+CMemSpyServerSession::CMemSpyServerSession( CMemSpyEngine& aEngine )
+: iEngine( aEngine )
+ {
+ }
+
+// ---------------------------------------------------------
+// ~CMemSpyServerSession()
+// ---------------------------------------------------------
+//
+CMemSpyServerSession::~CMemSpyServerSession()
+ {
+#ifdef _DEBUG
+ TPtrC pThreadName( KNullDesC );
+ if ( iClientThreadName )
+ {
+ pThreadName.Set( *iClientThreadName );
+ }
+
+ RDebug::Print( _L("[MemSpy] CMemSpyServerSession::~CMemSpyServerSession() - DEAD SESSION - this: 0x%08x, id: %4d, name: %S"), this, iClientThreadId, iClientThreadName );
+#endif
+
+ delete iClientThreadName;
+ }
+
+// ---------------------------------------------------------
+// ConstructL( const RMessage2& aMessage )
+// ---------------------------------------------------------
+//
+void CMemSpyServerSession::ConstructL( const RMessage2& aMessage )
+ {
+ RThread thread;
+ const TInt error = aMessage.Client( thread );
+ CleanupClosePushL( thread );
+
+ TRACE( RDebug::Printf( "[MemSpy] CMemSpyServerSession::ConstructL() - this: 0x%08x - opening client thread - err: %d", this, error ) );
+
+ User::LeaveIfError( error );
+
+ const TFullName threadName( thread.FullName() );
+ iClientThreadName = threadName.AllocL();
+ iClientThreadId = thread.Id();
+
+ CleanupStack::PopAndDestroy( &thread );
+
+ TRACE( RDebug::Print( _L("[MemSpy] CMemSpyServerSession::ConstructL() - NEW SESSION - this: 0x%08x, id: %4d, client: %S"), this, iClientThreadId, iClientThreadName ) );
+ }
+
+// ---------------------------------------------------------
+// NewL( CMemSpyEngine& aEngine, const RMessage2& aMessage )
+// Two-phased constructor
+// ---------------------------------------------------------
+//
+CMemSpyServerSession* CMemSpyServerSession::NewL( CMemSpyEngine& aEngine, const RMessage2& aMessage )
+ {
+ CMemSpyServerSession* self = new(ELeave) CMemSpyServerSession( aEngine );
+ CleanupStack::PushL( self );
+ self->ConstructL( aMessage );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// ---------------------------------------------------------
+// ServiceL( const RMessage2& aMessage )
+// Method from which the clients request arrives
+// ---------------------------------------------------------
+//
+void CMemSpyServerSession::ServiceL( const RMessage2& aMessage )
+ {
+ TRACE( RDebug::Print( _L("[MemSpy] CMemSpyServerSession::ServiceL() - START - this: 0x%08x, fn: 0x%08x, id: %4d, client: %S"), this, aMessage.Function(), iClientThreadId, iClientThreadName ) );
+
+ TRAPD( error, DoServiceL( aMessage ) );
+ if ( error != KErrNone )
+ {
+ RDebug::Print( _L("[MemSpy] CMemSpyServerSession::ServiceL() - SERVICE ERROR - this: 0x%08x, fn: %d, err: %d, client: %S"), this, aMessage.Function(), error, iClientThreadName );
+ }
+ aMessage.Complete( error );
+
+ TRACE( RDebug::Print( _L("[MemSpy] CMemSpyServerSession::ServiceL() - END - this: 0x%08x, fn: 0x%08x, id: %4d, client: %S"), this, aMessage.Function(), iClientThreadId, iClientThreadName ) );
+ }
+
+// ---------------------------------------------------------
+// DoCmdServiceL( const RMessage2& aMessage )
+// ---------------------------------------------------------
+//
+void CMemSpyServerSession::DoCmdServiceL( const RMessage2& aMessage )
+ {
+ TInt error = KErrNone;
+
+ // Check function attributes
+ const TInt function = aMessage.Function() & KMemSpyOpFlagsTypeMask;
+ const TInt argSpec = aMessage.Function() & KMemSpyOpFlagsInclusionMask;
+ const TBool byThreadId = ( argSpec == KMemSpyOpFlagsIncludesThreadId );
+ const TBool byThreadName = ( argSpec == KMemSpyOpFlagsIncludesThreadName );
+
+ TRACE( RDebug::Printf( "[MemSpy] CMemSpyServerSession::DoServiceL() - START - unmodified function: 0x%08x, opCode: %d [TID: %d, TN: %d]", aMessage.Function(), function, byThreadId, byThreadName ) );
+
+ switch (function)
+ {
+ case EGetProcessCount:
+ {
+ aMessage.WriteL(0, TPckgBuf<TInt>(iEngine.Container().Count()));
+ break;
+ }
+ case EGetProcesses:
+ {
+ CMemSpyEngineObjectContainer& list = iEngine.Container();
+
+ TPckgBuf<TInt> a0;
+ aMessage.ReadL(0, a0);
+ TInt realCount = Min(a0(), list.Count());
+
+ for(TInt i=0, offset = 0; i<realCount; i++, offset += sizeof(TMemSpyProcessData))
+ {
+ CMemSpyProcess& process = iEngine.Container().At(i);
+ TMemSpyProcessData data;
+ data.iId = process.Id();
+ data.iName.Copy(process.Name());
+
+ TPckgBuf<TMemSpyProcessData> buffer(data);
+ aMessage.WriteL(1, buffer, offset);
+ }
+
+ a0 = list.Count();
+ aMessage.WriteL(0, a0);
+
+ break;
+ }
+ case EProcessSystemPermanentOrCritical:
+ {
+ TBool ret = EFalse;
+ TPckgBuf<TProcessId> id;
+ aMessage.ReadL( 0, id );
+
+ CMemSpyEngineObjectContainer& container = iEngine.Container();
+ CMemSpyProcess& process = container.ProcessByIdL( id() );
+
+ process.Open();
+
+ if ( process.IsSystemPermanent() || process.IsSystemCritical() )
+ {
+ ret = ETrue;
+ }
+ TPckgBuf<TBool> retBuf( ret );
+ aMessage.WriteL( 1, retBuf );
+
+ break;
+ }
+ case EEndProcess:
+ {
+ TPckgBuf<TProcessId> id;
+ aMessage.ReadL( 0, id );
+ TPckgBuf<TEndType> type;
+ aMessage.ReadL( 1, type );
+
+ CMemSpyEngineObjectContainer& container = iEngine.Container();
+ CMemSpyProcess& process = container.ProcessByIdL( id() );
+
+ switch ( type() )
+ {
+ case ETerminate:
+ {
+ process.TerminateL();
+ break;
+ }
+ case EPanic:
+ {
+ process.PanicL();
+ break;
+ }
+ case EKill:
+ {
+ process.KillL();
+ break;
+ }
+ }
+ break;
+ }
+ case ESwitchToProcess:
+ {/*
+ TInt wgCount;
+ RWsSession wsSession;
+ User::LeaveIfError( wsSession.Connect() );
+ CleanupClosePushL( wsSession );
+ User::LeaveIfError( wgCount = wsSession.NumWindowGroups() );
+ RArray<RWsSession::TWindowGroupChainInfo> wgArray;
+ CleanupClosePushL( wgArray );
+ User::LeaveIfError( wsSession.WindowGroupList( &wgArray ) );
+ TApaTask task( wsSession );
+ TBool brought( EFalse );
+ TInt wgId( KErrNotFound );
+ TThreadId threadId;
+
+ TPckgBuf<TProcessId> id;
+ aMessage.ReadL( 0, id );
+ CMemSpyEngineObjectContainer& container = iEngine.Container();
+ CMemSpyProcess& process = container.ProcessByIdL( id() );
+
+ // loop trough threads in a process
+ for ( TInt i = 0; i < process.MdcaCount(); i++ )
+ {
+ TInt wgCountLocal = wgCount;
+
+ // loop trough all window groups and see if a thread id matches
+ while( !brought && wgCountLocal-- )
+ {
+ wgId = wgArray[wgCountLocal].iId;
+ User::LeaveIfError( wsSession.GetWindowGroupClientThreadId( wgId, threadId ) );
+ if ( threadId == process.At( i ).Id() )
+ {
+ CApaWindowGroupName* wgName = CApaWindowGroupName::NewLC( wsSession, wgId );
+ task.SetWgId( wgId );
+ if ( !wgName->Hidden() && task.Exists() )
+ {
+ task.BringToForeground();
+ brought = ETrue;
+ }
+ CleanupStack::PopAndDestroy( wgName );
+ }
+ }
+ }
+
+ TPckgBuf<TBool> ret( brought );
+ aMessage.WriteL( 1, ret );
+
+ break;*/
+ }
+ case EGetThreadCount:
+ {
+ TPckgBuf<TProcessId> pid;
+ aMessage.ReadL(1, pid);
+ CMemSpyProcess& process = iEngine.Container().ProcessByIdL(pid());
+ process.Open();
+ aMessage.WriteL(0, TPckgBuf<TInt>(process.Count()));
+ process.Close();
+ break;
+ }
+ case EGetThreads:
+ {
+ TPckgBuf<TProcessId> pid;
+ aMessage.ReadL(2, pid);
+
+ CMemSpyProcess& list = iEngine.Container().ProcessByIdL(pid());
+ list.Open();
+
+ TPckgBuf<TInt> a0;
+ aMessage.ReadL(0, a0);
+ TInt realCount = Min(a0(), list.Count());
+
+ for(TInt i=0, offset = 0; i<realCount; i++, offset += sizeof(TMemSpyThreadData))
+ {
+ CMemSpyThread& thread = list.At(i);
+ thread.Open();
+
+ TMemSpyThreadData data;
+ data.iId = thread.Id();
+ data.iName.Copy(thread.Name());
+ data.iThreadPriority = thread.Priority();
+
+ TPckgBuf<TMemSpyThreadData> buffer(data);
+ aMessage.WriteL(1, buffer, offset);
+
+ thread.Close();
+ }
+
+ a0 = list.Count();
+ aMessage.WriteL(0, a0);
+
+ list.Close();
+
+ break;
+ }
+ case ESetThreadPriority:
+ {
+ TPckgBuf<TThreadId> tid;
+ TPckgBuf<TInt> priority;
+ aMessage.ReadL(0, tid);
+ aMessage.ReadL(1, priority);
+
+ CMemSpyProcess* process = NULL;
+ CMemSpyThread* thread = NULL;
+ User::LeaveIfError(iEngine.Container().ProcessAndThreadByThreadId(tid(), process, thread));
+
+ if (thread)
+ {
+ thread->Open();
+ thread->SetPriorityL(static_cast<TThreadPriority>(priority()));
+ thread->Close();
+ }
+ break;
+ }
+ case EThreadSystemPermanentOrCritical:
+ {
+ TBool ret = EFalse;
+ TPckgBuf<TThreadId> id;
+ aMessage.ReadL( 0, id );
+
+ CMemSpyEngineObjectContainer& container = iEngine.Container();
+ CMemSpyProcess* process = NULL;
+ CMemSpyThread* thread = NULL;
+ User::LeaveIfError( container.ProcessAndThreadByThreadId( id(), process, thread ) );
+
+ if ( thread )
+ {
+ thread->Open();
+
+ if ( thread->IsSystemPermanent() || thread->IsSystemCritical() )
+ {
+ ret = ETrue;
+ }
+ thread->Close();
+ }
+ TPckgBuf<TBool> retBuf( ret );
+ aMessage.WriteL( 1, retBuf );
+
+ break;
+ }
+ case EEndThread:
+ {
+ TPckgBuf<TThreadId> id;
+ aMessage.ReadL( 0, id );
+ TPckgBuf<TEndType> type;
+ aMessage.ReadL( 1, type );
+
+ CMemSpyEngineObjectContainer& container = iEngine.Container();
+ CMemSpyProcess* process = NULL;
+ CMemSpyThread* thread = NULL;
+ User::LeaveIfError( container.ProcessAndThreadByThreadId( id(), process, thread ) );
+
+ if( thread )
+ {
+ switch ( type() )
+ {
+ case ETerminate:
+ {
+ thread->TerminateL();
+ break;
+ }
+ case EPanic:
+ {
+ thread->PanicL();
+ break;
+ }
+ case EKill:
+ {
+ thread->KillL();
+ break;
+ }
+ }
+ }
+ break;
+ }
+ // --- KernelObjects related functions ---
+ case EGetKernelObjectTypeCount:
+ {
+ TInt iCount = EMemSpyDriverContainerTypeLast - EMemSpyDriverContainerTypeFirst;
+ TPckgBuf<TInt> ret( iCount );
+ aMessage.WriteL(0, ret);
+ break;
+ }
+ case EGetKernelObjects:
+ {
+ TPckgBuf<TInt> count;
+ aMessage.ReadL(0, count);
+
+ CMemSpyEngineGenericKernelObjectContainer* model = iEngine.HelperKernelContainers().ObjectsAllL(); //contains all the objects
+ CleanupStack::PushL( model );
+
+ for( TInt i=0, offset = 0; i<count(); i++, offset += sizeof( TMemSpyKernelObjectData ) )
+ {
+ TMemSpyKernelObjectData data;
+
+ TPtrC name(model->At(i).Name().Mid(1));
+ TInt tabPos = name.Locate('\t');
+ if (tabPos != KErrNotFound)
+ name.Set(name.Left(tabPos));
+
+ data.iName.Copy(name);
+ data.iType = model->At(i).Type();
+ data.iCount = model->At(i).Count();
+ data.iSize = model->At(i).Count() * model->At(i).Count();
+
+ TPckgBuf<TMemSpyKernelObjectData> buffer(data);
+ aMessage.WriteL(1, buffer, offset);
+ }
+ aMessage.WriteL(0, count);
+ CleanupStack::PopAndDestroy( model );
+ break;
+ }
+ case EGetKernelObjectItemsCount:
+ {
+ TPckgBuf<TMemSpyDriverContainerType> tempType;
+ aMessage.ReadL(1, tempType); //get type of kernel object
+ TMemSpyDriverContainerType type = tempType();
+
+ CMemSpyEngineHelperKernelContainers& kernelContainerManager = iEngine.HelperKernelContainers();
+ CMemSpyEngineGenericKernelObjectList* iObjectList = kernelContainerManager.ObjectsForSpecificContainerL( type );
+ CleanupStack::PushL( iObjectList );
+
+ TInt count = iObjectList->Count();
+ TPckgBuf<TInt> ret( count );
+ aMessage.WriteL( 0, ret );
+
+ CleanupStack::PopAndDestroy( iObjectList );
+ break;
+ }
+ case EGetKernelObjectItems:
+ {
+ TPckgBuf<TInt> count;
+ TPckgBuf<TMemSpyDriverContainerType> tempType;
+ aMessage.ReadL( 0, count ); //get count of items
+ aMessage.ReadL(1, tempType); //get type of kernel object
+ TInt c = count();
+
+ CMemSpyEngineHelperKernelContainers& kernelContainerManager = iEngine.HelperKernelContainers();
+ CMemSpyEngineGenericKernelObjectList* iObjectList = kernelContainerManager.ObjectsForSpecificContainerL( tempType() );
+ CleanupStack::PushL( iObjectList );
+
+ for( TInt i=0, offset = 0; i<c; i++, offset += sizeof( TMemSpyDriverHandleInfoGeneric ) )
+ {
+ TMemSpyDriverHandleInfoGeneric data;
+
+ data = iObjectList->At( i );
+
+ TPckgBuf<TMemSpyDriverHandleInfoGeneric> buffer(data);
+ aMessage.WriteL(2, buffer, offset);
+ }
+
+ CleanupStack::PopAndDestroy( iObjectList );
+ break;
+ }
+ // --- Kernel Heap related functions ---
+ case EGetHeap:
+ {
+ TMemSpyHeapInfo heapInfo;
+ iEngine.HelperHeap().GetHeapInfoKernelL( heapInfo );
+ TMemSpyHeapData data = iEngine.HelperHeap().NewHeapRawInfo( heapInfo );
+
+ TPckgBuf<TMemSpyHeapData> buffer(data);
+ aMessage.WriteL(0, buffer);
+
+ break;
+ }
+ }
+// else if( function == EProcessByIndex )
+// {
+// TMemSpyProcess iProcess;
+// TInt in;
+// TPckgBuf<TInt> index( in );
+// aMessage.ReadL( 0, index );
+// CMemSpyProcess& process = iEngine.Container().At( index() );
+// //fill the data structure
+// iProcess.iId = process.Id(); //process ID
+// iProcess.iName.Append( process.Name() ); //raw process name
+// iProcess.iThreadCount = process.Count(); //thread count
+// iProcess.iPriority = process.Priority();
+// //
+// TPckgBuf<TMemSpyProcess> buf( iProcess );
+// aMessage.WriteL( 1, buf );
+// aMessage.Complete( KErrNone );
+// }
+// else if( function == EProcessIndexById )
+// {
+// TProcessId iId;
+// TPckgBuf<TProcessId> buf( iId );
+// aMessage.ReadL( 0, buf );
+// TInt index = iEngine.Container().ProcessIndexById( buf() );
+// TPckgBuf<TInt> out( index );
+// aMessage.WriteL( 1, out );
+// aMessage.Complete( KErrNone );
+// }
+// else if( function == EOutputProcessInfo )
+// {
+// TProcessId iId;
+// TPckgBuf<TProcessId> buf( iId );
+// aMessage.ReadL( 0, buf );
+// CMemSpyProcess& process = iEngine.Container().ProcessByIdL( buf() );
+// iEngine.HelperProcess().OutputProcessInfoL( process );
+// }
+// else if( function == EProcessIsDead )
+// {
+// TProcessId iId;
+// TPckgBuf<TProcessId> buf( iId );
+// aMessage.ReadL( 0, buf );
+// CMemSpyProcess& process = iEngine.Container().ProcessByIdL( buf() );
+// TBool dead = process.IsDead();
+// TPckgBuf<TBool> out( dead );
+// aMessage.WriteL( 1, out );
+// aMessage.Complete( KErrNone );
+// }
+// else if( function == ESortProcessesBy )
+// {
+// TSortType type;
+// TPckgBuf<TSortType> buf(type);
+// aMessage.ReadL( 0, buf );
+// if( buf() == ESortProcById )
+// {
+// iEngine.Container().SortById();
+// }
+// else if( buf() == ESortProcByName )
+// {
+// iEngine.Container().SortByName();
+// }
+// else if( buf() == ESortProcByThreadCount )
+// {
+// iEngine.Container().SortByThreadCount();
+// }
+// else if( buf() == ESortProcByCodeSegs )
+// {
+// iEngine.Container().SortByCodeSegs();
+// }
+// else if( buf() == ESortProcByHeapUsage )
+// {
+// iEngine.Container().SortByHeapUsage();
+// }
+// else if( buf() == ESortProcByStackUsage )
+// {
+// iEngine.Container().SortByStackUsage();
+// }
+// }
+// else if( function == EOpenCloseCurrentProcess )
+// {
+// TProcessId id;
+// TBool open;
+// TPckgBuf<TProcessId> buf(id);
+// TPckgBuf<TBool> buf2(open);
+// aMessage.ReadL( 0, buf );
+// aMessage.ReadL( 1, buf2 );
+// if( buf2() == 1 )
+// {
+// iEngine.Container().ProcessByIdL( buf() ).Open();
+// }
+// else
+// {
+// iEngine.Container().ProcessByIdL( buf() ).Close();
+// }
+// }
+
+// // Check function is supported and argument combination is valid
+// error = ValidateFunction( function, byThreadId, byThreadName );
+// TRACE( RDebug::Printf( "[MemSpy] CMemSpyServerSession::DoServiceL() - validation result: %d", error ) );
+//
+// // Process function request
+// if ( error == KErrNone )
+// {
+// if ( byThreadId )
+// {
+// TRACE( RDebug::Printf( "[MemSpy] CMemSpyServerSession::DoServiceL() - [TID] thread-specific..." ) );
+//
+// const TThreadId threadId( aMessage.Int0() );
+// HandleThreadSpecificOpL( function, threadId );
+// }
+// else if ( byThreadName )
+// {
+// TRACE( RDebug::Printf( "[MemSpy] CMemSpyServerSession::DoServiceL() - [TN] thread-specific..." ) );
+//
+// error = aMessage.GetDesLength( 0 /*slot 0*/ );
+//
+// if ( error > 0 && error <= KMaxFullName )
+// {
+// TFullName* threadName = new(ELeave) TFullName();
+// CleanupStack::PushL( threadName );
+// aMessage.ReadL( 0, *threadName );
+// HandleThreadSpecificOpL( function, *threadName );
+// CleanupStack::PopAndDestroy( threadName );
+// }
+// else
+// {
+// error = KErrArgument;
+// }
+// }
+// else
+// {
+// TRACE( RDebug::Printf( "[MemSpy] CMemSpyServerSession::DoServiceL() - thread-agnostic..." ) );
+//
+// HandleThreadAgnosticOpL( function, aMessage );
+// }
+// }
+
+ User::LeaveIfError( error );
+
+ TRACE( RDebug::Printf( "[MemSpy] CMemSpyServerSession::DoServiceL() - HELLOOOOOO" ) );
+ TRACE( RDebug::Printf( "[MemSpy] CMemSpyServerSession::DoServiceL() - END" ) );
+ }
+
+// ---------------------------------------------------------
+// ValidateFunction( TInt aFunction, TBool aIncludesThreadId, TBool aIncludesThreadName )
+// Validates the MemSpy operation types
+// ---------------------------------------------------------
+//
+TInt CMemSpyServerSession::ValidateFunction( TInt aFunction, TBool aIncludesThreadId, TBool aIncludesThreadName )
+ {
+ TInt err = KErrNotSupported;
+
+ // Check the operation is within op-code range
+ if ( aFunction >= EMemSpyClientServerOpMarkerFirst && aFunction < EMemSpyClientServerOpMarkerLast )
+ {
+ // Check the operation doesn't include unnecessary or not supported information
+ const TBool includesThreadIdentifier = ( aIncludesThreadId || aIncludesThreadName );
+ if ( includesThreadIdentifier && aFunction >= EMemSpyClientServerOpMarkerThreadAgnosticFirst )
+ {
+ // Passing a thread identifier to a thread agnostic operation
+ err = KErrArgument;
+ }
+ else
+ {
+ err = KErrNone;
+ }
+ }
+ //
+ if ( err != KErrNone )
+ {
+ RDebug::Printf( "[MemSpy] CMemSpyServerSession::ValidateFunction() - function request did not validate - [withId: %d, withName: %d]", aIncludesThreadId, aIncludesThreadName );
+ }
+ //
+ return err;
+ }
+
+// ---------------------------------------------------------
+// HandleThreadSpecificOpL( TInt aFunction, const TThreadId& aThreadId )
+// ---------------------------------------------------------
+//
+void CMemSpyServerSession::HandleThreadSpecificOpL( TInt aFunction, const TThreadId& aThreadId )
+ {
+// TRACE( RDebug::Printf( "[MemSpy] CMemSpyServerSession::HandleThreadSpecificOpL() - START - aFunction: %d, aThreadId: %d", aFunction, (TUint) aThreadId ) );
+//
+// ASSERT( (TUint) aThreadId != 0 );
+// TInt error = KErrNone;
+//
+// // Check if its a kernel thread identifier
+// const TBool isKernel = ( static_cast<TUint32>( aThreadId ) == KMemSpyClientServerThreadIdKernel );
+//
+// // Treat as thread specific operation
+// CMemSpyProcess* process = NULL;
+// CMemSpyThread* thread = NULL;
+// if ( !isKernel )
+// {
+// error = iEngine.Container().ProcessAndThreadByThreadId( aThreadId, process, thread );
+// TRACE( RDebug::Printf( "[MemSpy] CMemSpyServerSession::HandleThreadSpecificOpL() - search result: %d, proc: 0x%08x, thread: 0x%08x", error, process, thread ) );
+// }
+// else
+// {
+// // Kernel is only supported for a couple of operations
+// if ( aFunction == EMemSpyClientServerOpHeapInfo || aFunction == EMemSpyClientServerOpHeapData )
+// {
+// }
+// else
+// {
+// TRACE( RDebug::Printf( "[MemSpy] CMemSpyServerSession::HandleThreadSpecificOpL() - trying to call unsupported function for kernel thread!" ) );
+// error = KErrArgument;
+// }
+// }
+//
+// // Must be no error so far and we must have a valid thread & process when performing a non-kernel op
+// // or then if we are performing a kernel op, we don't need the thread or process.
+// if ( error == KErrNone && ( ( thread && process && !isKernel ) || ( isKernel ) ) )
+// {
+//#ifdef _DEBUG
+// if ( thread )
+// {
+// HBufC* threadName = thread->FullName().AllocLC();
+// _LIT( KTrace2, "[MemSpy] CMemSpyServerSession::HandleThreadSpecificOpL() - thread: %S" );
+// RDebug::Print( KTrace2, threadName );
+// CleanupStack::PopAndDestroy( threadName );
+// }
+// else if ( isKernel )
+// {
+// _LIT( KTrace2, "[MemSpy] CMemSpyServerSession::HandleThreadSpecificOpL() - thread: Kernel" );
+// RDebug::Print( KTrace2 );
+// }
+//#endif
+//
+// // Got a valid thread object - now work out which operation to perform...
+// switch( aFunction )
+// {
+// case EMemSpyClientServerOpSummaryInfo:
+// iEngine.HelperProcess().OutputProcessInfoL( *process );
+// break;
+// case EMemSpyClientServerOpSummaryInfoDetailed:
+// iEngine.HelperProcess().OutputProcessInfoDetailedL( *process );
+// break;
+// case EMemSpyClientServerOpHeapInfo:
+// if ( isKernel )
+// {
+// iEngine.HelperHeap().OutputHeapInfoKernelL();
+// }
+// else
+// {
+// iEngine.HelperHeap().OutputHeapInfoUserL( *thread );
+// }
+// break;
+// case EMemSpyClientServerOpHeapCellListing:
+// iEngine.HelperHeap().OutputCellListingUserL( *thread );
+// break;
+// case EMemSpyClientServerOpHeapData:
+// if ( isKernel )
+// {
+// iEngine.HelperHeap().OutputHeapDataKernelL();
+// }
+// else
+// {
+// iEngine.HelperHeap().OutputHeapDataUserL( *thread );
+// }
+// break;
+// case EMemSpyClientServerOpStackInfo:
+// iEngine.HelperStack().OutputStackInfoL( *thread );
+// break;
+// case EMemSpyClientServerOpStackDataUser:
+// iEngine.HelperStack().OutputStackDataL( *thread, EMemSpyDriverDomainUser, EFalse );
+// break;
+// case EMemSpyClientServerOpStackDataKernel:
+// iEngine.HelperStack().OutputStackDataL( *thread, EMemSpyDriverDomainKernel, EFalse );
+// break;
+// case EMemSpyClientServerOpOpenFiles:
+// iEngine.HelperFileSystem().ListOpenFilesL( aThreadId );
+// break;
+//
+// default:
+// error = KErrNotSupported;
+// break;
+// }
+// }
+//
+// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadSpecificOpL() - END - aFunction: %d, aThreadId: %d, error: %d", aFunction, (TUint) aThreadId, error ) );
+// User::LeaveIfError( error );
+ }
+
+// ---------------------------------------------------------
+// HandleThreadSpecificOpL( TInt aFunction, const TDesC& aThreadName )
+// Gets thread ID from aThreadName
+// and calls HandleThreadSpecificOpL( , const TThreadId& aThreadId )
+// ---------------------------------------------------------
+//
+void CMemSpyServerSession::HandleThreadSpecificOpL( TInt aFunction, const TDesC& aThreadName )
+ {
+// TRACE( RDebug::Print( _L("[MemSpy] CMemSpyServerSession::HandleThreadSpecificOpL() - START - aFunction: %d, aThreadName: %S"), aFunction, &aThreadName ) );
+// //
+// CMemSpyProcess* process = NULL;
+// CMemSpyThread* thread = NULL;
+// TInt error = iEngine.Container().ProcessAndThreadByPartialName( aThreadName, process, thread );
+// User::LeaveIfError( error );
+// //
+// const TThreadId threadId( thread->Id() );
+// HandleThreadSpecificOpL( aFunction, threadId );
+// //
+// TRACE( RDebug::Print( _L("[MemSpy] CMemSpyServerSession::HandleThreadSpecificOpL() - END - aFunction: %d, aThreadName: %S"), aFunction, &aThreadName ) );
+ }
+
+// ---------------------------------------------------------
+// HandleThreadAgnosticOpL( TInt aFunction, const RMessage2& aMessage )
+// ---------------------------------------------------------
+//
+void CMemSpyServerSession::HandleThreadAgnosticOpL( TInt aFunction, const RMessage2& aMessage )
+ {
+// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - START" ) );
+// //
+// if ( aFunction == EMemSpyClientServerOpHeapInfoCompact )
+// {
+// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpHeapInfoCompact") );
+// iEngine.HelperHeap().OutputHeapInfoForDeviceL();
+// }
+// else if ( aFunction == EMemSpyClientServerOpStackInfoCompact )
+// {
+// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpStackInfoCompact") );
+// iEngine.HelperStack().OutputStackInfoForDeviceL();
+// }
+// else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingTimerStart )
+// {
+// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingTimerStart") );
+// iEngine.HelperSysMemTracker().StartL();
+// }
+// else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingTimerStop )
+// {
+// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingTimerStop") );
+// iEngine.HelperSysMemTracker().StopL();
+// }
+// else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingReset )
+// {
+// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingReset") );
+// iEngine.HelperSysMemTracker().Reset();
+// }
+// else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingForceUpdate )
+// {
+// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingForceUpdate") );
+// iEngine.HelperSysMemTracker().CheckForChangesNowL();
+// }
+// else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingTimerPeriodSet )
+// {
+// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingTimerPeriodSet") );
+//
+// // Get current config
+// TMemSpyEngineHelperSysMemTrackerConfig config;
+// iEngine.HelperSysMemTracker().GetConfig( config );
+//
+// // Set new timer value
+// config.iTimerPeriod = aMessage.Int0();
+//
+// // And update config... which will leave if the config is invalid
+// iEngine.HelperSysMemTracker().SetConfigL( config );
+// }
+// else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingCategoriesSet )
+// {
+// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingCategoriesSet") );
+// // Get current config
+// TMemSpyEngineHelperSysMemTrackerConfig config;
+// iEngine.HelperSysMemTracker().GetConfig( config );
+//
+// // Set new categories
+// config.iEnabledCategories = aMessage.Int0();
+//
+// // And update config... which will leave if the config is invalid
+// iEngine.HelperSysMemTracker().SetConfigL( config );
+// }
+// else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingThreadNameFilterSet )
+// {
+// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingThreadNameFilterSet") );
+// // Get current config
+// TMemSpyEngineHelperSysMemTrackerConfig config;
+// iEngine.HelperSysMemTracker().GetConfig( config );
+//
+// // Set new filter
+// RBuf buf;
+// buf.CleanupClosePushL();
+// TInt len = aMessage.GetDesLength( 0 );
+// if ( len > 0 )
+// {
+// buf.CreateL( len );
+// aMessage.ReadL( 0, buf, 0 );
+// config.iThreadNameFilter.Copy( buf );
+// }
+// else
+// {
+// config.iThreadNameFilter.Zero();
+// }
+// CleanupStack::PopAndDestroy( &buf );
+//
+// // And update config... which will leave if the config is invalid
+// iEngine.HelperSysMemTracker().SetConfigL( config );
+// }
+// else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingHeapDumpSet )
+// {
+// // Get current config
+// TMemSpyEngineHelperSysMemTrackerConfig config;
+// iEngine.HelperSysMemTracker().GetConfig( config );
+//
+// // Set new Heap Dump value
+// config.iDumpData = aMessage.Int0();
+//
+// // And update config... which will leave if the config is invalid
+// iEngine.HelperSysMemTracker().SetConfigL( config );
+// }
+// else if ( aFunction == EMemSpyClientServerOpSwitchOutputSinkTrace )
+// {
+// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSwitchOutputSinkTrace") );
+// iEngine.InstallSinkL( ESinkTypeDebug );
+// }
+// else if ( aFunction == EMemSpyClientServerOpSwitchOutputSinkFile )
+// {
+// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSwitchOutputSinkFile") );
+// iEngine.InstallSinkL( ESinkTypeFile );
+// }
+// else if ( aFunction == EMemSpyClientServerOpEnumerateKernelContainer )
+// {
+// const TMemSpyDriverContainerType type = CMemSpyEngineHelperKernelContainers::MapToType( static_cast< TObjectType >( aMessage.Int0() ) );
+//
+// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpEnumerateKernelContainer - type: %d", type ) );
+//
+// CMemSpyEngineGenericKernelObjectList* model = iEngine.HelperKernelContainers().ObjectsForSpecificContainerL( type );
+// CleanupStack::PushL( model );
+// model->OutputL( iEngine.Sink() );
+// CleanupStack::PopAndDestroy( model );
+// }
+// else if ( aFunction == EMemSpyClientServerOpEnumerateKernelContainerAll )
+// {
+// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpEnumerateKernelContainerAll") );
+// CMemSpyEngineGenericKernelObjectContainer* model = iEngine.HelperKernelContainers().ObjectsAllL();
+// CleanupStack::PushL( model );
+// model->OutputL( iEngine.Sink() );
+// CleanupStack::PopAndDestroy( model );
+// }
+// else if ( aFunction == EMemSpyClientServerOpOpenFiles )
+// {
+// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpOpenFiles") );
+// iEngine.ListOpenFilesL();
+// }
+// else if ( aFunction == EMemSpyClientServerOpDisableAknIconCache )
+// {
+// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpDisableAknIconCache") );
+// iEngine.HelperRAM().SetAknIconCacheStatusL( EFalse );
+// }
+// else
+// {
+// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - [device-wide operation] => invoking UI") );
+// iEngine.NotifyClientServerOperationRequestL( aFunction );
+// }
+// //
+// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - END" ) );
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/memspy/MemSpyServer/group/MemSpyServer.mmp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,60 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include <bldvariant.hrh>
+#include <data_caging_paths.hrh>
+#include <platform_paths.hrh>
+
+TARGETTYPE EXE
+TARGET MemSpyServer.exe
+UID 0 0x2002EA8D
+SECUREID 0xE5883BC2
+VENDORID 0x101FB657 // Nokia
+
+EPOCSTACKSIZE 0x4000
+EPOCHEAPSIZE 0x100000 0x4000000
+
+
+SOURCEPATH ../Source
+//SOURCE MemSpyServer.cpp
+//SOURCE MemSpyServerSession.cpp
+SOURCE MemSpyServerMain.cpp
+
+USERINCLUDE ../Include
+
+CAPABILITY ReadUserData WriteUserData ReadDeviceData WriteDeviceData
+
+OS_LAYER_SYSTEMINCLUDE
+
+APP_LAYER_SYSTEMINCLUDE
+
+LIBRARY MemSpyDriverClient.lib
+LIBRARY MemSpyEngine.lib
+
+LIBRARY euser.lib
+LIBRARY ecom.lib
+LIBRARY efsrv.lib
+LIBRARY estor.lib
+LIBRARY bafl.lib
+LIBRARY ws32.lib
+LIBRARY cone.lib
+LIBRARY eikcore.lib
+LIBRARY fbscli.lib
+LIBRARY PlatformEnv.lib
+LIBRARY flogger.lib
+LIBRARY apgrfx.lib
+
--- a/memspy/memspy_plat/memspy_api/include/MemSpyEngineClientInterface.h Mon May 03 13:58:41 2010 +0300
+++ b/memspy/memspy_plat/memspy_api/include/MemSpyEngineClientInterface.h Thu May 13 23:59:27 2010 +0300
@@ -48,6 +48,7 @@
// Literal constants
_LIT( KMemSpyServerName, "MemSpyServer" );
+_LIT( KMemSpyProcessName0, "MemSpyServer.exe" );
_LIT( KMemSpyProcessName1, "MemSpyUI.exe" );
_LIT( KMemSpyProcessName2, "MemSpyConsole.exe" );
@@ -258,12 +259,72 @@
EMemSpyClientServerOpSystemWideMemoryTrackingHeapDumpSet,
/**
+ * [INTERNAL REQUEST]
+ */
+ EMemSpyClientServerOpMarkerUiFirst,
+
+ EMemSpyClientServerOpGetProcessCount = EMemSpyClientServerOpMarkerUiFirst,
+
+ EMemSpyClientServerOpGetProcesses,
+
+ EMemSpyClienServerOpGetProcessIdByName,
+
+ EMemSpyClientServerOpGetThreadCount,
+
+ EMemSpyClientServerOpGetThreads,
+
+ EMemSpyClientServerOpSetThreadPriority,
+
+ EMemSpyClientServerOpProcessSystemPermanentOrCritical,
+
+ EMemSpyClientServerOpEndProcess,
+
+ EMemSpyClientServerOpSwitchToProcess,
+
+ //Threads operations
+ EMemSpyClientServerOpThreadSystemPermanentOrCritical,
+
+ EMemSpyClientServerOpEndThread,
+
+ EMemSpyClientServerOpSwitchToThread,
+
+ EMemSpyClientServerOpGetInfoItemType,
+
+ EMemSpyClientServerOpGetThreadInfoItemsCount,
+
+ EMemSpyClientServerOpGetThreadInfoItems,
+
+
+ //Kernel Objects operations
+ EMemSpyClientServerOpGetKernelObjectCount,
+
+ EMemSpyClientServerOpGetKernelObjects,
+
+ EMemSpyClientServerOpGetKernelObjectItemCount,
+
+ EMemSpyClientServerOpGetKernelObjectItems,
+
+ EMemSpyClientServerOpGetHeap,
+
+ EMemSpyClientServerOpMarkerUiLast,
+
+ EMemSpyClientServerOpOutputAllContainerContents,
+
+ EMemSpyClientServerOpDumpKernelHeap,
+
+ /**
* [INTERNAL REQUEST]
*/
EMemSpyClientServerOpMarkerLast,
};
+enum TMemSpyEndType
+ {
+ ETerminate,
+ EKill,
+ EPanic
+ };
--- a/memspy/memspy_plat/memspy_api/include/memspy/engine/MemSpyEngine.h Mon May 03 13:58:41 2010 +0300
+++ b/memspy/memspy_plat/memspy_api/include/memspy/engine/MemSpyEngine.h Thu May 13 23:59:27 2010 +0300
@@ -60,11 +60,12 @@
{
public:
IMPORT_C static CMemSpyEngine* NewL( RFs& aFsSession );
+ IMPORT_C static CMemSpyEngine* NewL( RFs& aFsSession, TBool aStartServer );
IMPORT_C ~CMemSpyEngine();
private:
CMemSpyEngine();
- void ConstructL( RFs& aFsSession );
+ void ConstructL( RFs& aFsSession, TBool aStartServer );
public: // API
IMPORT_C RFs& FsSession();
--- a/memspy/memspy_plat/memspy_api/include/memspy/engine/MemSpyEngineImp.h Mon May 03 13:58:41 2010 +0300
+++ b/memspy/memspy_plat/memspy_api/include/memspy/engine/MemSpyEngineImp.h Thu May 13 23:59:27 2010 +0300
@@ -61,7 +61,7 @@
public:
CMemSpyEngineImp( RFs& aFsSession, CMemSpyEngine& aEngine );
~CMemSpyEngineImp();
- void ConstructL();
+ void ConstructL( TBool aStartServer );
private: // Construction support
void ConstructHelpersL();
--- a/memspy/memspy_plat/memspy_api/include/memspy/engine/ThreadAndProcess/MemSpyEngineObjectProcess.h Mon May 03 13:58:41 2010 +0300
+++ b/memspy/memspy_plat/memspy_api/include/memspy/engine/ThreadAndProcess/MemSpyEngineObjectProcess.h Thu May 13 23:59:27 2010 +0300
@@ -65,7 +65,11 @@
IMPORT_C TBool IsDead() const;
IMPORT_C TUint32 SID() const;
IMPORT_C TUint32 VID() const;
-
+ IMPORT_C TProcessPriority Priority() const;
+ IMPORT_C TExitCategoryName ExitCategory() const;
+ IMPORT_C TInt ExitReason() const;
+ IMPORT_C TExitType ExitType() const;
+
public: // API - misc
IMPORT_C void KillL();
IMPORT_C void TerminateL();
--- a/memspy/memspy_plat/memspy_api/include/memspy/engine/ThreadAndProcess/MemSpyEngineObjectThreadInfoObjects.h Mon May 03 13:58:41 2010 +0300
+++ b/memspy/memspy_plat/memspy_api/include/memspy/engine/ThreadAndProcess/MemSpyEngineObjectThreadInfoObjects.h Thu May 13 23:59:27 2010 +0300
@@ -98,6 +98,8 @@
public: // From MDesCArray
IMPORT_C TInt MdcaCount() const;
IMPORT_C TPtrC MdcaPoint(TInt aIndex) const;
+ IMPORT_C TPtrC Caption(TInt aIndex ) const;
+ IMPORT_C TPtrC Value(TInt aIndex ) const;
protected:
class CItem : public CBase
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/group/ProfilerEngine.mmp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,54 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <platform_paths.hrh>
+
+
+TARGET PIProfilerEngine.exe
+TARGETTYPE EXE
+UID 0x100039CE 0x2001E5AD
+VENDORID VID_DEFAULT
+CAPABILITY ALL -TCB
+SMPSAFE
+
+EPOCSTACKSIZE 0x10000
+EPOCHEAPSIZE 0x100000 0x2000000 // Min 1MB, Max 32MB
+
+OS_LAYER_SYSTEMINCLUDE
+USERINCLUDE ../inc
+SOURCEPATH ../src
+
+SOURCE ProfilerErrorChecker.cpp
+SOURCE ProfilerEngine.cpp
+SOURCE SamplerController.cpp
+SOURCE SamplerPluginLoader.cpp
+SOURCE WriterController.cpp
+SOURCE WriterPluginLoader.cpp
+SOURCE ProfilerTimer.cpp
+
+LIBRARY sysutil.lib
+LIBRARY EFSRV.LIB
+LIBRARY C32.LIB
+LIBRARY EUSER.LIB
+LIBRARY estor.lib
+LIBRARY fbscli.lib
+LIBRARY ws32.lib
+LIBRARY bafl.lib
+LIBRARY charconv.lib
+LIBRARY ecom.lib
+LIBRARY PlatformEnv.lib
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/group/ProfilerEshell.mmp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,41 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <platform_paths.hrh>
+
+
+TARGET PIProfiler.exe
+TARGETTYPE EXE
+UID 0x100039CE 0x2021E5AD // test UID, get an official
+VENDORID VID_DEFAULT
+CAPABILITY ALL -TCB
+SMPSAFE
+
+EPOCSTACKSIZE 0x10000
+
+OS_LAYER_SYSTEMINCLUDE
+USERINCLUDE ../inc
+SOURCEPATH ../src
+
+
+SOURCE ProfilerEshell.cpp
+
+LIBRARY C32.LIB
+LIBRARY EUSER.LIB
+LIBRARY bafl.lib
+LIBRARY efsrv.lib
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/group/bld.inf Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,22 @@
+/*
+* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+PRJ_MMPFILES
+ProfilerEngine.mmp
+ProfilerEshell.mmp
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/inc/ProfilerEngine.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,258 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef __PROFILERENGINE__
+#define __PROFILERENGINE__
+
+#include <e32base.h>
+#include <e32svr.h>
+#include <e32property.h>
+
+#include <piprofiler/SamplerPluginInterface.h>
+#include <piprofiler/WriterPluginInterface.h>
+#include <piprofiler/ProfilerSession.h>
+#include <piprofiler/ProfilerAttributes.h> // internal settings format presentations
+
+#include "SamplerController.h"
+#include "WriterController.h"
+#include "ProfilerErrorChecker.h"
+#include "ProfilerTimer.h"
+
+// CONSTANTS
+const TInt KProfilerPrefixMaxLength = 32;
+const TInt KSettingsFileSize = 4096;
+
+/*
+ * This is an internal interface to the profiling engine which allows
+ * an additional control DLL to be loaded, replacing the profiler's
+ * default console UI
+ */
+
+/**
+ * Implementation class providing access to the profiler engine
+ */
+
+class MProfilerEngine
+{
+public:
+ virtual TInt ControlL(TInt aCommand) =0;
+ virtual TInt ControlDataL(TInt aCommand, TAny* data1 = 0, TAny* data2 = 0) = 0;
+
+ virtual TInt GetSamplerAttributesL(const RMessage2& aMessage) = 0;
+ virtual TInt GetSamplerAttributeCountL(const RMessage2& aMessage) = 0;
+ virtual TInt SetSamplerAttributesL(const RMessage2& aMessage) = 0;
+ virtual TInt GetGeneralAttributesL(const RMessage2& aMessage) = 0;
+ virtual TInt SetGeneralAttributesL(const RMessage2& aMessage) = 0;
+ virtual TInt RefreshStatus(const RMessage2& aMessage) = 0;
+ virtual RProfiler::TSamplerState State() const =0;
+};
+
+/**
+ * The interface that the extra controller must implement to access
+ * the profiler.
+ */
+class MProfilerController
+{
+ public:
+ /** Release the controller from the profiler. This is invoked when the profiler is unloading. */
+ virtual void Release() = 0;
+ /** Ask the profiler to change state */
+ inline TInt ControlL(TInt aCommand) const;
+ /** Ask the profiler to change state */
+ inline TInt ControlDataL(TInt aCommand, TAny* data1 = 0, TAny* data2 = 0) const;
+
+ inline TInt GetSamplerAttributesL(const RMessage2& aMessage) const;
+ inline TInt SetSamplerAttributesL(const RMessage2& aMessage) const;
+ inline TInt GetGeneralAttributesL(const RMessage2& aMessage) const;
+ inline TInt SetGeneralAttributesL(const RMessage2& aMessage) const;
+ inline TInt GetSamplerAttributeCountL(const RMessage2& aMessage) const;
+ inline TInt RefreshStatus(const RMessage2& aMessage) const;
+ /* Query the profiler state */
+ inline RProfiler::TSamplerState GeTComand() const;
+ protected:
+ inline MProfilerController(MProfilerEngine& aEngine);
+ private:
+ MProfilerEngine& iEngine;
+};
+
+/** The signature of ordinal 1 in the controller DLL */
+typedef MProfilerController* (*TProfilerControllerFactoryL)(TInt aPriority, MProfilerEngine& aEngine);
+/** The second UID required by the controller DLL */
+const TUid KUidProfilerKeys={0x1000945c};
+
+inline MProfilerController::MProfilerController(MProfilerEngine& aEngine)
+ :iEngine(aEngine)
+{
+
+}
+
+inline TInt MProfilerController::ControlL(TInt aCommand) const
+{
+ return iEngine.ControlL(aCommand);
+}
+
+inline TInt MProfilerController::ControlDataL(TInt aCommand,TAny* data1, TAny* data2) const
+{
+ return iEngine.ControlDataL(aCommand,data1,data2);
+}
+
+inline TInt MProfilerController::GetSamplerAttributesL(const RMessage2& aMessage) const
+{
+ return iEngine.GetSamplerAttributesL(aMessage);
+}
+
+inline TInt MProfilerController::SetSamplerAttributesL(const RMessage2& aMessage) const
+{
+ return iEngine.SetSamplerAttributesL(aMessage);
+}
+
+inline TInt MProfilerController::GetGeneralAttributesL(const RMessage2& aMessage) const
+{
+ return iEngine.GetGeneralAttributesL(aMessage);
+}
+
+inline TInt MProfilerController::GetSamplerAttributeCountL(const RMessage2& aMessage) const
+{
+ return iEngine.GetSamplerAttributeCountL(aMessage);
+}
+
+inline TInt MProfilerController::SetGeneralAttributesL(const RMessage2& aMessage) const
+{
+ return iEngine.SetGeneralAttributesL(aMessage);
+}
+
+inline TInt MProfilerController::RefreshStatus(const RMessage2& aMessage) const
+{
+ return iEngine.RefreshStatus(aMessage);
+}
+
+inline RProfiler::TSamplerState MProfilerController::GeTComand() const
+{
+ return iEngine.State();
+}
+
+class CSamplerController;
+class CWriterController;
+class MSamplerControllerObserver;
+class MProfilerErrorObserver;
+
+class CProfiler : public CBase, private MProfilerEngine,
+ MSamplerControllerObserver,
+ MProfilerErrorObserver,
+ MProfilerTimerObserver
+{
+ public:
+
+ static CProfiler* NewLC(const TDesC& aSettingsFile);
+
+ /**
+ * Method for control commands, i.e. start, stop and exit
+ *
+ * @param aCommand command to be parsed and executed
+ * @return TInt KErrNone if succeed, else error code
+ */
+ TInt ControlL(TInt aCommand);
+
+ /**
+ * Method for control data, e.g. settings
+ *
+ * @param aCommand command to be parsed and executed
+ * @param value1 can contain any value, integer or string, depends on use case
+ * @param value2 can contain any value, integer or string, depends on use case
+ * @return TInt KErrNone if succeed, else error code
+ */
+ TInt ControlDataL(TInt aCommand, TAny* value1 = 0, TAny* value2 = 0);
+
+ // setting attributes manipulation
+ TInt GetGeneralAttributesL(const RMessage2& aMessage);
+ TInt GetSamplerAttributesL(const RMessage2& aMessage);
+ TInt SetGeneralAttributesL(const RMessage2& aMessage);
+ TInt SetSamplerAttributesL(const RMessage2& aMessage);
+ TInt GetSamplerAttributeCountL(const RMessage2& aMessage);
+ TInt RefreshStatus(const RMessage2& /*aMessage*/);
+
+ // from CProfilerErrorChecker
+ void HandleSamplerControllerReadyL();
+ void NotifyRequesterForSettingsUpdate();
+ void HandleProfilerErrorChangeL( TInt aError );
+
+ // from MProfilerTimerObserver
+ void HandleTimerExpiresL(TInt aError);
+
+ void Finalise();
+ CProfilerSampleStream* GetSamplerStream();
+ void HandleError(TInt aErr);
+ static TBool CheckLocationSanity(RFs& fs, const TDesC8& aLocation);
+private:
+ CProfiler(const TDesC& aSettingsFile);
+ ~CProfiler();
+ void ConstructL();
+ TInt LoadSettingsL(/*const TDesC& configFile*/);
+ void DoGetValueFromSettingsArray(CDesC8ArrayFlat* aLineArray, const TDesC8& aAttribute, TDes8& aValue);
+ void DoGetValueFromSettingsArray(CDesC8ArrayFlat* aLineArray, const TDesC8& aAttribute, TInt& aValue);
+ void UpdateSavedGeneralAttributes(CDesC8ArrayFlat* aSavedAttributes);
+ template<class T> CBufFlat* ExternalizeLC(const T& aElements);
+
+ RProfiler::TSamplerState State() const;
+
+ void DrainSampleStream();
+ void InstallStreamForActiveTraces(CSamplerPluginInterface& aSampler, CWriterPluginInterface& aWriter, TDesC& totalPrefix);
+ void SaveSettingsL();
+
+ TInt HandleGeneralSettingsChange();
+ TInt CheckOldProfilerRunning();
+public:
+ // trace file settings
+ TBuf8<KProfilerPrefixMaxLength> iFilePrefix;
+ TBuf8<KProfilerPrefixMaxLength> iDriveLetter;
+ TBuf8<KProfilerPrefixMaxLength*2> iTotalPrefix;
+
+ TBuf<256> iSettingsFileLocation;
+
+ MProfilerController* iServer;
+ RProfiler::TSamplerState iState;
+
+ CProfilerSampleStream* iUserStream;
+
+ // plug-in controllers
+ CWriterController* iWriterHandler;
+ CSamplerController* iSamplerHandler;
+
+ // setting attribute containers
+ TGeneralAttributes iGeneralAttributes;
+ CArrayFixFlat<TSamplerAttributes>* iDefaultSamplerAttributesArray;
+
+ // temporary settings file array container
+ CDesC8ArrayFlat* iSavedLineArray;
+ TInt iSavedLinesCount;
+ // saved settings, add extra 1 byte space to end buffer with a '\n'
+ TBuf8<KSettingsFileSize + 1> iSettingsBuffer;
+
+ // P&S status properties
+ RProperty iEngineStatus;
+ RProperty iUpdateStatus;
+ TBuf<128> iFileNameStream;
+private:
+ TBool iSettingsFileLoaded;
+ CProfilerErrorChecker* iErrorChecker;
+ CProfilerTimer* iTimer;
+};
+
+#include <piprofiler/ProfilerGenericClassesUsr.h>
+#endif // __PROFILERENGINE__
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/inc/ProfilerErrorChecker.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,47 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef PROFILERERRORCHECKER_H_
+#define PROFILERERRORCHECKER_H_
+
+// CLASS DECLARATIONS
+class MProfilerErrorObserver
+ {
+ public: // New
+ virtual void HandleProfilerErrorChangeL( TInt aError ) = 0;
+ };
+
+
+class CProfilerErrorChecker : public CActive
+ {
+public:
+ static CProfilerErrorChecker* CProfilerErrorChecker::NewL();
+ ~CProfilerErrorChecker();
+ void SetObserver(MProfilerErrorObserver* aObserver);
+private:
+ CProfilerErrorChecker();
+ void ConstructL();
+ void RunL();
+ TInt RunError(TInt aError);
+ void DoCancel();
+private:
+ MProfilerErrorObserver* iObserver;
+ RProperty iErrorStatus;
+ };
+
+#endif /* PROFILERERRORCHECKER_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/inc/ProfilerEshell.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,36 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+#ifndef PROFILERESHELL_H_
+#define PROFILERESHELL_H_
+
+#include <e32base.h>
+#include <e32std.h>
+#include <bacline.h> // CCommandLineArguments
+
+class CProfilerEShell : public CBase
+ {
+public:
+ static CProfilerEShell* NewL();
+ ~CProfilerEShell();
+
+ void ConstructL();
+private:
+ CProfilerEShell();
+
+ };
+
+#endif /* PROFILERESHELL_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/inc/ProfilerTimer.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,57 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#ifndef PROFILERTIMER_H_
+#define PROFILERTIMER_H_
+
+#include <e32std.h>
+#include <e32base.h>
+
+class MProfilerTimerObserver
+ {
+public:
+ virtual void HandleTimerExpiresL(TInt aError) = 0;
+ };
+
+class CProfilerTimer : public CActive
+ {
+public:
+ static CProfilerTimer* NewL(const TInt aPriority, MProfilerTimerObserver& aObserver);
+ ~CProfilerTimer();
+
+public:
+
+ void After(TUint aPeriodInSeconds);
+
+protected:
+
+ // From CActive
+ void RunL();
+ void DoCancel();
+
+private:
+
+ CProfilerTimer(const TInt aPriority, MProfilerTimerObserver& aObserver);
+ void ConstructL(void);
+
+private:
+
+ RTimer iTimer;
+ MProfilerTimerObserver& iObserver;
+ };
+
+#endif /* PROFILERTIMER_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/inc/SamplerController.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,154 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef __SAMPLERCONTROLLER_H__
+#define __SAMPLERCONTROLLER_H__
+
+// system includes
+#include <utf.h>
+#include <e32cmn.h>
+
+
+// The user-interface to the sampling device driver sued by the profiling engine
+// user includes
+#include <piprofiler/ProfilerConfig.h>
+#include <piprofiler/ProfilerVersion.h>
+#include <piprofiler/SamplerPluginInterface.h>
+
+#include "SamplerPluginLoader.h"
+
+/*
+ * Forward declarations
+ */
+class TBapBuf;
+class CProfilerSampleStream;
+class CSamplerPluginLoader;
+class CSamplerPluginInterface;
+class MSamplerControllerObserver;
+/**
+ * The sampler controller for handling the actual sampler plugins.
+ */
+
+class CSamplerController : public CBase, MSamplerPluginLoadObserver
+ {
+
+public:
+ static CSamplerController* NewL(CProfilerSampleStream& aStream);
+ void ConstructL();
+
+ CSamplerController(CProfilerSampleStream& aStream);
+ ~CSamplerController();
+
+ /**
+ *
+ * Methods for user mode sampling
+ *
+ **/
+
+ /** Initialise the user mode samplers **/
+ void InitialiseSamplerListL();
+
+ /* Overrider of MSamplerPluginLoaderObserver class **/
+ void HandlePluginLoaded( KSamplerPluginLoaderStatus aStatus );
+
+ /* returns the name matching plugin Uid */
+ TUid GetPluginUID(TDesC8& name);
+
+ /** Start enabled samplers **/
+ void StartSamplerPluginsL();
+
+ /** Stop enabled samplers **/
+ TInt StopSamplerPlugins();
+
+public:
+
+ CSamplerPluginInterface* GetPlugin(TUid aUid);
+
+ TInt GetPluginList(TDes* aList);
+
+ TInt SetSamplerSettingsL(TInt aUid, TSamplerAttributes aAttributes);
+
+ void GetSamplerAttributesL(CArrayFixFlat<TSamplerAttributes>* aAttributes);
+
+ TInt UpdateSavedSamplerAttributesL(CDesC8ArrayFlat* aSavedLineArray, CArrayFixFlat<TSamplerAttributes>* aAttributes);
+
+ /*
+ * Compose all sampler (sampler or sub-sampler) attributes as text array for saving to settings file,
+ * called by CSamplerController (and Profiler Engine)
+ *
+ * @param aFile settings file where to write the settings
+ */
+ void ComposeAttributesToSettingsFileFormat(RFile& aFile, CArrayFixFlat<TSamplerAttributes>* aAttributes);
+
+ /*
+ * Compose all sampler (sampler or sub-sampler) attributes as text array for saving to settings file,
+ * called by CSamplerController (and Profiler Engine)
+ *
+ * @param aFile settings file where to write the settings
+ * @param aAttrArray is container for saving the text to
+ */
+ void ComposeSettingsText(RFile& aFile, CArrayFixFlat<TSamplerAttributes>* aAttrArray);
+
+ void SetObserver(MSamplerControllerObserver* aObserver);
+
+ void Str2Bool(const TDesC8& aBuf, TBool& aValue);
+
+ void Str2Int(const TDesC8& aBuf, TInt& aValue);
+
+ void Str2Int(const TDesC8& aBuf, TUint32& aValue);
+
+ TBuf8<16> Bool2Str(const TBool& aValue);
+
+ TBuf8<16> Int2Str(const TInt& aValue);
+public:
+
+ CArrayPtrFlat<CSamplerPluginInterface>* iPluginArray;
+
+ // Asynchronous loader for the sampler plug-ins.
+ CSamplerPluginLoader* iPluginLoader;
+
+ // UID of the selected plugin in the container's lbx.
+ TUid iSelectedPluginUid;
+
+ // shared sample stream for all plugin samplers
+ CProfilerSampleStream& iStream;
+
+private:
+ MSamplerControllerObserver* iObserver;
+};
+
+/**
+* Interface for SamplerPluginLoader observer. MSamplerPluginLoadObserver gets
+* notifications when plugins are loaded.
+*
+* @lib ProfilerEngine.exe/.lib
+* @since Series60_30.1
+*/
+
+class MSamplerControllerObserver
+ {
+ public: // New
+
+ //CSamplerController calls this function when each plug-in is loaded or
+ //loading is finished..
+
+ virtual void HandleSamplerControllerReadyL() = 0;
+ virtual void HandleError(TInt aError) = 0;
+ };
+
+#endif // __SAMPLERCONTROLLER_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/inc/SamplerPluginLoader.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,291 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef SAMPLERPLUGINLOADER_H
+#define SAMPLERPLUGINLOADER_H
+
+// INCLUDES
+#include <e32base.h>
+#include <ecom/implementationinformation.h>
+#include <piprofiler/ProfilerConfig.h>
+#include <piprofiler/SamplerPluginInterface.h>
+
+// CONSTANTS
+// Value for a to b comparison result when logically a == b.
+const TInt KSamplerComparisonEqual = 0;
+
+// Value for a to b comparison result when logically a < b.
+const TInt KSamplerComparisonBefore = -1;
+
+// Value for a to b comparison result when logically a > b.
+const TInt KSamplerComparisonAfter = 1;
+
+// CLASS DEFINITIONS
+class CSamplerPluginInterface;
+class MSamplerPluginLoadObserver;
+class REComSession;
+
+/**
+* CSamplerPluginLoader. Mechanism used to load plugins asynchronously. Uses
+* MSamplerPluginLoadObserver as a callback.
+*
+* @lib ProfilerEngine.exe/.lib???????????
+* @since Series60_30.1
+*/
+class CSamplerPluginLoader : public CActive
+ {
+ public: // Constructor and destructor
+
+ /**
+ * Two-phased constructor.
+ *
+ * @param aAppUi Pointer to application UI. Does not take ownership.
+ */
+ static CSamplerPluginLoader* NewL();
+
+ /**
+ * Destructor
+ */
+ ~CSamplerPluginLoader();
+
+ private: // Internal construction
+
+ /**
+ * Default C++ contructor
+ */
+ CSamplerPluginLoader();
+
+ /**
+ * Symbian OS default constructor
+ * @return void
+ */
+ void ConstructL();
+
+ public: // API
+
+ /**
+ * Starts loading GS plug-ins asynchronously. Will call
+ * MSamplerPluginLoadObserver::HandlePluginLoaded() each time a plug-in is
+ * loaded and when all plugins are loaded.
+ *
+ * CSamplerPluginLoader transfers the ownership of each loaded plugin view to
+ * CAknViewAppUi. It is client's responsibility to remove the views from
+ * CAknViewAppUi and delete the plugins if necessary.
+ *
+ * @param aInterfaceUid Uid ofthe interfaces to be loaded.
+ * @param aParentUid Uid of the parent. Only children of this parent
+ * will be loaded.
+ * @param aPluginArray An array for the loaded GS plug-ins.
+ * CSamplerPluginLoader does not take the ownership of this array.
+ */
+ void LoadAsyncL( CArrayPtrFlat<CSamplerPluginInterface>* aPluginArray );
+
+ /**
+ * Load a specific plugin instance synchronously.
+ *
+ * @param aInterfaceUid Uid ofthe interfaces to be loaded.
+ * @param aImplementationUid Uid of the implementation to load
+ */
+ void LoadSyncL( CArrayPtrFlat<CSamplerPluginInterface>* aPluginArray );
+
+ /**
+ * Sets observer for this loader. Only one observer per loader in one
+ * time is possible.
+ */
+ void SetObserver(MSamplerPluginLoadObserver* aObserver);
+
+ /**
+ * Aborts asynchronous loading of the GS plug-ins.
+ */
+ void AbortAsyncLoad();
+
+
+ /**
+ * Sorts the plugin array.
+ *
+ * Sorting criterias:
+ *
+ * 1. Order number if provider category is Internal.
+ * 2. Provider category. Precedence as follows:
+ * 1. KGSPluginProviderInternal
+ * 2. EGSPluginProviderOEM
+ * 3. EGSPluginProviderOperator
+ * 4. EGSPluginProvider3rdParty
+ * 3. Alphabetical
+ *
+ * @param aPlugins The array which will be sorted.
+ */
+ void SortPluginsL( CArrayPtrFlat<CSamplerPluginInterface>* aPlugins );
+
+ private: // Internal methods
+
+ /**
+ * Starts loading next plugin.
+ */
+ void LoadNextPluginL();
+
+ /**
+ * Creates a plugin instance from given UID. Ownership is transferred.
+ */
+ CSamplerPluginInterface& CreatePluginInstanceL(
+ const CImplementationInformation& aImpInfo );
+
+ /**
+ * Notifies MPluginLoadObserver.
+ */
+ void NotifyProgress();
+
+ /**
+ * Notifies MPluginLoadObserver.
+ */
+ void NotifyFinished();
+
+ /**
+ * Wait for the next round of CActive execution.
+ */
+ void CompleteOwnRequest();
+
+ // Insertion function used by sorting:
+
+ /**
+ * Inserts plugin in the correct position in the array using sorting
+ * criterias. Assumes aPlugins is ordered.
+ *
+ * @param aPlugin The plugin to be inserted.
+ * @param aPlugins Array in which the plugin is inserted into the
+ * corresponding location.
+ */
+ void InsertPluginInOrderL(
+ CSamplerPluginInterface* aPlugin,
+ CArrayPtrFlat<CSamplerPluginInterface>* aPlugins );
+
+ // Comparison functions:
+
+ /**
+ * Compares plugins according to comparison criterias.
+ *
+ * Note: GS internal comparison constants such as KGSComparisonEqual are
+ * different from the ones outputted by this function. This is because
+ * this function is also usable by RArray sort -functionality but BC
+ * cannot be broken in GS.
+ *
+ * @return Negative value: If aFirst before aSecond.
+ * 0: If equal.
+ * Positive value: If aSecond before aFirst.
+ */
+ static TInt Compare( const CSamplerPluginInterface& aFirst,
+ const CSamplerPluginInterface& aSecond );
+
+ /**
+ *
+ * @return KGSComparisonEqual = equal indexes
+ * KGSComparisonBefore = aFirst is before aSecond
+ * KGSComparisonAfter = aFirst is after aSecond
+ */
+
+ static TInt CompareIndex(
+ const CSamplerPluginInterface& aFirst,
+ const CSamplerPluginInterface& aSecond );
+
+ private: // Utility methods
+
+ /**
+ * Parses descriptor to UID.
+ */
+ static TInt ParseToUid( const TDesC8& aSource, TUid& aTarget );
+
+ /**
+ * Parsers plugin's order number
+ */
+ static TInt ParseOrderNumber( const TDesC8& aSource, TInt& aOrderNumber );
+
+ private: // From CActive
+
+ /**
+ * See base class.
+ */
+ void RunL();
+
+ /**
+ * See base class.
+ */
+ TInt RunError( TInt aError );
+
+ /**
+ * See base class.
+ */
+ void DoCancel();
+
+ private: // Data
+ // Pluginloader goes through this array and loads the plugins into
+ // iPluginArray if they fulfill the criterias.
+ RImplInfoPtrArray iImplInfoArray;
+
+ // Used as an iterator to maintain location in iImplInfoArray.
+ TInt iImplInfoArrayIterator;
+
+ // Array of loaded plugins.Plugins are owned by iAppUi. Only the array
+ // pointers are owned by this class and therefore only reset array.
+ CArrayPtrFlat<CSamplerPluginInterface>* iPluginArray;
+
+ // Pointer to observer. Not owned.
+ MSamplerPluginLoadObserver* iObserver;
+
+ // Number of RunL calls.
+ TInt iRunLDebugCount;
+
+ };
+
+
+/**
+* Interface for SamplerPluginLoader observer. MSamplerPluginLoadObserver gets
+* notifications when plugins are loaded.
+*
+* @lib ProfilerEngine.exe/.lib???????????
+* @since Series60_30.1
+*/
+
+class MSamplerPluginLoadObserver
+ {
+ public: // Enums
+ enum KSamplerPluginLoaderStatus
+ {
+ // One plugin loaded successfully, continue to next.
+ ESamplerSuccess,
+ // Loading one plugin failed, contiue to next.
+ ESamplerFail,
+ // Client called AbortAsyncLoad(), finished loading.
+ ESamplerAborted,
+ // All plugins loaded successfully, finished loading.
+ ESamplerFinished,
+ // Severe error with loader, finished loading.
+ ESamplerError
+ };
+
+ public: // New
+
+ //CSamplerPluginLoader calls this function when each plug-in is loaded or
+ //loading is finished..
+
+ IMPORT_C virtual void HandlePluginLoaded(
+ KSamplerPluginLoaderStatus aStatus ) = 0;
+ };
+
+
+#endif // SAMPLERPLUGINLOADER_H
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/inc/WriterController.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,115 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef __WRITERCONTROLLER_H__
+#define __WRITERCONTROLLER_H__
+
+// system includes
+#include <utf.h>
+#include <e32cmn.h>
+
+
+// The user-interface to the sampling device driver sued by the profiling engine
+// user includes
+#include <piprofiler/ProfilerConfig.h>
+#include <piprofiler/ProfilerVersion.h>
+#include <piprofiler/WriterPluginInterface.h>
+
+#include "WriterPluginLoader.h"
+
+/*
+ * Forward declarations
+ */
+class TBapBuf;
+class CWriterPluginLoader;
+class CWriterPluginInterface;
+
+/**
+ * The writer controller for handling the available Data writer plugins.
+ */
+
+class CWriterController : public CBase, MWriterPluginLoadObserver
+ {
+
+public:
+ static CWriterController* NewL(CProfilerSampleStream& aStream);
+ void ConstructL();
+
+ CWriterController(CProfilerSampleStream& aStream);
+ ~CWriterController();
+
+ /**
+ *
+ * Methods for user mode sampling
+ *
+ **/
+
+ /** Initialise the user mode samplers **/
+ void InitialiseWriterListL();
+
+ /* Overrider of MSamplerPluginLoaderObserver class **/
+ void HandlePluginLoaded( KWriterPluginLoaderStatus /*aStatus*/ );
+
+ /* returns the matching plugin Uid */
+ TUid GetPluginUID(TInt traceId);
+
+ CWriterPluginInterface* GetActiveWriter();
+
+ /** Returns the sampler type (kernel/user) **/
+ TUint32 GetWriterType(TUint32 samplerId);
+
+ /** Set additional settings for a trace **/
+ TInt AdditionalUserTraceSettings(TInt traceId, TInt settings);
+
+ /** Set data stream for samplers **/
+ //void SetSampleStream(RProfilerSampleStream* iStream);
+
+ TInt StartSelectedPlugin();
+
+ void StopSelectedPlugin();
+
+ /** Set selected plugin active **/
+ void SetPluginActive(TUid uid, const TWriterPluginValueKeys aKey);
+
+ TInt SetPluginSettings(TUid aUid, TDes& aDes);
+
+ /** Get settings for a specific plugin **/
+ void GetPluginSettings(TUid uid, TDes& aVal);
+
+ /** Request stream read **/
+ //void FillThisStreamBuffer(TBapBuf* aBuffer, TRequestStatus& aStatus);
+
+ CWriterPluginInterface* GetPlugin(TUid aUid);
+
+ CArrayPtrFlat<CWriterPluginInterface>* GetPluginList();
+
+ void InitialisePluginStream();
+public:
+ CArrayPtrFlat<CWriterPluginInterface>* iPluginArray;
+
+ // Asynchronous loader for the writer plug-ins.
+ CWriterPluginLoader* iPluginLoader;
+
+ // UID of the selected plugin in the container's lbx.
+ TUid iSelectedPluginUid;
+
+ CProfilerSampleStream& iStream;
+};
+
+
+#endif // __WRITERCONTROLLER_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/inc/WriterPluginLoader.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,302 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef WRITERPLUGINLOADER_H
+#define WRITERPLUGINLOADER_H
+
+// INCLUDES
+#include <e32base.h>
+#include <ecom/implementationinformation.h>
+#include <piprofiler/ProfilerConfig.h>
+#include <piprofiler/WriterPluginInterface.h>
+#include <piprofiler/ProfilerTraces.h>
+
+// CONSTANTS
+
+// Value for a to b comparison result when logically a == b.
+const TInt KWriterComparisonEqual = 0;
+
+// Value for a to b comparison result when logically a < b.
+const TInt KWriterComparisonBefore = -1;
+
+// Value for a to b comparison result when logically a > b.
+const TInt KWriterComparisonAfter = 1;
+
+// CLASS DEFINITIONS
+class CWriterPluginInterface;
+class MWriterPluginLoadObserver;
+class REComSession;
+
+/**
+* CWriterPluginLoader. Mechanism used to load plugins asynchronously. Uses
+* MWriterPluginLoadObserver as a callback.
+*
+* @lib ProfilerEngine.exe/.lib???????????
+* @since Series60_30.1
+*/
+class CWriterPluginLoader : public CActive
+ {
+ public: // Constructor and destructor
+
+ /**
+ * Two-phased constructor.
+ *
+ * @param aAppUi Pointer to application UI. Does not take ownership.
+ */
+ static CWriterPluginLoader* NewL();
+
+ /**
+ * Destructor
+ */
+ ~CWriterPluginLoader();
+
+ private: // Internal construction
+
+ /**
+ * Default C++ contructor
+ */
+ CWriterPluginLoader();
+
+ /**
+ * Symbian OS default constructor
+ * @return void
+ */
+ void ConstructL();
+
+ public: // API
+
+ /**
+ * Starts loading GS plug-ins asynchronously. Will call
+ * MWriterPluginLoadObserver::HandlePluginLoaded() each time a plug-in is
+ * loaded and when all plugins are loaded.
+ *
+ * CWriterPluginLoader transfers the ownership of each loaded plugin view to
+ * CAknViewAppUi. It is client's responsibility to remove the views from
+ * CAknViewAppUi and delete the plugins if necessary.
+ *
+ * @param aInterfaceUid Uid ofthe interfaces to be loaded.
+ * @param aParentUid Uid of the parent. Only children of this parent
+ * will be loaded.
+ * @param aPluginArray An array for the loaded GS plug-ins.
+ * CWriterPluginLoader does not take the ownership of this array.
+ */
+ void LoadAsyncL( CArrayPtrFlat<CWriterPluginInterface>* aPluginArray );
+
+ /**
+ * Load a specific plugin instance synchronously.
+ *
+ * @param aInterfaceUid Uid ofthe interfaces to be loaded.
+ * @param aImplementationUid Uid of the implementation to load
+ */
+ CWriterPluginInterface& LoadSyncL( TUid aImplementationUid );
+
+ /**
+ * Sets observer for this loader. Only one observer per loader in one
+ * time is possible.
+ */
+ void SetObserver(MWriterPluginLoadObserver* aObserver);
+
+ /**
+ * Aborts asynchronous loading of the GS plug-ins.
+ */
+ void AbortAsyncLoad();
+
+ /**
+ * Sorts the plugin array.
+ *
+ * Sorting criterias:
+ *
+ * 1. Order number if provider category is Internal.
+ * 2. Provider category. Precedence as follows:
+ * 3. Alphabetical
+ *
+ * @param aPlugins The array which will be sorted.
+ */
+ void SortPluginsL( CArrayPtrFlat<CWriterPluginInterface>* aPlugins );
+
+ private: // Internal methods
+
+ /**
+ * Starts loading next plugin.
+ */
+ void LoadNextPluginL();
+
+ /**
+ * Creates a plugin instance from given UID. Ownership is transferred.
+ */
+ CWriterPluginInterface& CreatePluginInstanceL(
+ const CImplementationInformation& aImpInfo );
+
+ /**
+ * Notifies MGSPluginLoadObserver.
+ */
+ void NotifyProgress();
+
+ /**
+ * Notifies MGSPluginLoadObserver.
+ */
+ void NotifyFinished();
+
+ /**
+ * Wait for the next round of CActive execution.
+ */
+ void CompleteOwnRequest();
+
+ // Insertion function used by sorting:
+
+ /**
+ * Inserts plugin in the correct position in the array using sorting
+ * criterias. Assumes aPlugins is ordered.
+ *
+ * @param aPlugin The plugin to be inserted.
+ * @param aPlugins Array in which the plugin is inserted into the
+ * corresponding location.
+ */
+ void InsertPluginInOrderL(
+ CWriterPluginInterface* aPlugin,
+ CArrayPtrFlat<CWriterPluginInterface>* aPlugins );
+
+ // Comparison functions:
+
+ /**
+ * Compares plugins according to comparison criterias.
+ *
+ * Note: GS internal comparison constants such as KGSComparisonEqual are
+ * different from the ones outputted by this function. This is because
+ * this function is also usable by RArray sort -functionality but BC
+ * cannot be broken in GS.
+ *
+ * @return Negative value: If aFirst before aSecond.
+ * 0: If equal.
+ * Positive value: If aSecond before aFirst.
+ */
+ static TInt Compare( const CWriterPluginInterface& aFirst,
+ const CWriterPluginInterface& aSecond );
+
+ /**
+ *
+ * @return KGSComparisonEqual = equal indexes
+ * KGSComparisonBefore = aFirst is before aSecond
+ * KGSComparisonAfter = aFirst is after aSecond
+ */
+
+ static TInt CompareIndex(
+ const CWriterPluginInterface& aFirst,
+ const CWriterPluginInterface& aSecond );
+
+ private: // Utility methods
+
+ /**
+ * Parses descriptor to UID.
+ */
+ static TInt ParseToUid( const TDesC8& aSource, TUid& aTarget );
+
+ /**
+ * Parsers plugin's order number
+ */
+ static TInt ParseOrderNumber( const TDesC8& aSource, TInt& aOrderNumber );
+
+ /**
+ * Print debug information.
+ */
+ static void PrintInfoDebug( const CImplementationInformation& aInfo,
+ TInt aIterator,
+ TInt aPluginCount );
+
+ /**
+ * Display loading error popup message.
+ */
+ void DisplayErrorPopupL( TInt aError,
+ const CImplementationInformation* aInfo );
+
+ private: // From CActive
+
+ /**
+ * See base class.
+ */
+ void RunL();
+
+ /**
+ * See base class.
+ */
+ TInt RunError( TInt aError );
+
+ /**
+ * See base class.
+ */
+ void DoCancel();
+
+ private: // Data
+
+
+ // Pluginloader goes through this array and loads the plugins into
+ // iPluginArray if they fulfill the criterias.
+ RImplInfoPtrArray iImplInfoArray;
+
+ // Used as an iterator to maintain location in iImplInfoArray.
+ TInt iImplInfoArrayIterator;
+
+ // Array of loaded plugins.Plugins are owned by iAppUi. Only the array
+ // pointers are owned by this class and therefore only reset array.
+ CArrayPtrFlat<CWriterPluginInterface>* iPluginArray;
+
+ // Pointer to observer. Not owned.
+ MWriterPluginLoadObserver* iObserver;
+
+ // Number of RunL calls.
+ TInt iRunLDebugCount;
+ };
+
+
+/**
+* Interface for WriterPluginLoader observer. MWriterPluginLoadObserver gets
+* notifications when plugins are loaded.
+*
+* @lib ProfilerEngine.exe/.lib???????????
+* @since Series60_30.1
+*/
+
+class MWriterPluginLoadObserver
+ {
+ public: // Enums
+ enum KWriterPluginLoaderStatus
+ {
+ // One plugin loaded successfully, continue to next.
+ EWriterSuccess,
+ // Loading one plugin failed, contiue to next.
+ EWriterFail,
+ // Client called AbortAsyncLoad(), finished loading.
+ EWriterAborted,
+ // All plugins loaded successfully, finished loading.
+ EWriterFinished,
+ // Severe error with loader, finished loading.
+ EWriterError
+ };
+
+ public: // New
+
+ //CWriterPluginLoader calls this function when each plug-in is loaded or
+ //loading is finished..
+
+ IMPORT_C virtual void HandlePluginLoaded(
+ KWriterPluginLoaderStatus aStatus ) = 0;
+ };
+
+
+#endif // WRITERPLUGINLOADER_H
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/src/ProfilerEngine.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,1515 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <e32cons.h>
+#include <e32base.h>
+#include <f32file.h>
+#include <c32comm.h>
+#include <s32file.h>
+#include <pathinfo.h>
+#include <s32mem.h>
+#include <bautils.h>
+#include <sysutil.h>
+#include <piprofiler/ProfilerConfig.h>
+#include "ProfilerEngine.h"
+#include <piprofiler/ProfilerTraces.h>
+
+// properties
+const TUid KEngineStatusPropertyCat={0x2001E5AD};
+enum TEnginePropertyKeys
+ {
+ EProfilerEngineStatus = 8,
+ EProfilerErrorStatus
+ };
+
+static _LIT_SECURITY_POLICY_PASS( KAllowAllPolicy );
+
+// CONSTANTS
+const TInt KStreamBufferSize = 32768;
+const TInt KSavedLineCount = 64;
+const TInt KFileNameBufSize = 128;
+// Use this UID if plugin belongs to DebOutWriterPlugin:
+const TUid KDebOutWriterPluginUid = { 0x2001E5BA };
+// Use this UID if plugin belongs to MmcOutWriterPlugin:
+const TUid KDiskWriterPluginUid = { 0x2001E5BB };
+
+// LITERALS
+_LIT8(KGenericTraceOutput, "output_type");
+_LIT8(KGenericTraceFilePrefix, "file_prefix");
+_LIT8(KGenericTraceFileSaveDrive, "save_file_location");
+_LIT8(KGenericTimedProfilingPeriod, "profiling_period");
+_LIT8(KEquals, "=");
+_LIT8(KNewLineSeparator, "\n");
+_LIT8(KProfilerVersionTag, "version");
+_LIT8(KEndMark, "[end]");
+_LIT8(KOutputToDebugOutput, "debug_output");
+
+/**
+ *
+ * The controller class used to provide the Profiler functions.
+ * This runs as a server in the engine thread
+ *
+ */
+class CPServer : public CServer2, public MProfilerController
+ {
+public:
+ static MProfilerController* NewL(TInt aPriority, MProfilerEngine& aEngine);
+
+private:
+ CPServer(TInt aPriority, MProfilerEngine& aEngine);
+ void Release();
+ CSession2* NewSessionL(const TVersion& aVersion,const RMessage2& aMessage) const;
+
+public:
+ static TInt iClientCount;
+ };
+
+TInt CPServer::iClientCount = 0;
+
+// The session class used by the server controller
+class CPSession : public CSession2
+ {
+private:
+ inline const CPServer& Server() const;
+ void ServiceL(const RMessage2& aMessage);
+ };
+
+/*
+ *
+ * CProfiler class implementation
+ *
+ */
+// --------------------------------------------------------------------------------------------
+CProfiler* CProfiler::NewLC(const TDesC& aSettingsFile)
+ {
+ CProfiler* self = new(ELeave) CProfiler(aSettingsFile);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+ }
+
+// --------------------------------------------------------------------------------------------
+CProfiler::CProfiler(const TDesC& aSettingsFile) :
+ iSettingsFileLocation(aSettingsFile)
+ {
+ // define property for Profiler Engine status, UI may read it for control purposes
+ if ( RProperty::Define(KEngineStatusPropertyCat,
+ EProfilerEngineStatus,
+ RProperty::EInt,
+ KAllowAllPolicy,
+ KAllowAllPolicy,
+ 0) != KErrAlreadyExists )
+ {
+ LOGTEXT(_L("CProfiler::CProfiler - status property already defined"));
+ }
+
+ if ( RProperty::Define(KEngineStatusPropertyCat,
+ EProfilerErrorStatus,
+ RProperty::EInt,
+ KAllowAllPolicy,
+ KAllowAllPolicy,
+ 0) != KErrAlreadyExists )
+ {
+ LOGTEXT(_L("CProfiler::CProfiler - status property already defined"));
+ }
+
+ // attach to own property
+ iEngineStatus.Attach(KEngineStatusPropertyCat, EProfilerEngineStatus);
+ // set status idle
+ iEngineStatus.Set(KEngineStatusPropertyCat, EProfilerEngineStatus, RProfiler::EIdle);
+
+ // attach to own property
+ iUpdateStatus.Attach(KEngineStatusPropertyCat, EProfilerErrorStatus);
+ // set status idle
+ iUpdateStatus.Set(KEngineStatusPropertyCat, EProfilerErrorStatus, EFalse);
+ }
+
+// --------------------------------------------------------------------------------------------
+CProfiler::~CProfiler()
+ {
+ LOGTEXT(_L("CProfiler::~CProfiler - Enter"));
+
+ // delete error checker
+ if(iErrorChecker)
+ {
+ iErrorChecker->Cancel();
+ delete iErrorChecker;
+ iErrorChecker = NULL;
+ }
+
+ // delete settings array
+ if(iDefaultSamplerAttributesArray)
+ {
+ iDefaultSamplerAttributesArray->Reset();
+ delete iDefaultSamplerAttributesArray;
+ iDefaultSamplerAttributesArray = NULL;
+ }
+
+ // delete settings file raw line array
+ if(iSavedLineArray)
+ {
+ iSavedLineArray->Reset();
+ delete iSavedLineArray;
+ iSavedLineArray = NULL;
+ }
+
+ // delete sampler controller, cleans up the sampler plugin instances
+ if(iSamplerHandler)
+ {
+ delete iSamplerHandler;
+ iSamplerHandler = NULL;
+ }
+ // delete writer controller, cleans up the writer plugin instances
+ if(iWriterHandler)
+ {
+ delete iWriterHandler;
+ iWriterHandler = NULL;
+ }
+
+ // delete user side sampler stream
+ if(iUserStream)
+ {
+ delete iUserStream;
+ iUserStream = NULL;
+ }
+
+ // close engine status property
+ iEngineStatus.Close();
+ if (RProperty::Delete(KEngineStatusPropertyCat, EProfilerEngineStatus) != KErrNotFound)
+ {
+ LOGTEXT(_L("CProfiler::~CProfiler - cannot close status property"));
+ }
+ // close engine update property
+ iUpdateStatus.Close();
+ if (RProperty::Delete(KEngineStatusPropertyCat, EProfilerErrorStatus) != KErrNotFound)
+ {
+ LOGTEXT(_L("CProfiler::~CProfiler - cannot close update property"));
+ }
+
+ // close server process
+ if (iServer)
+ {
+ LOGTEXT(_L("CProfiler::~CProfiler - Releasing server"));
+ iServer->Release();
+ }
+
+ if( iTimer )
+ {
+ iTimer->Cancel();
+ delete iTimer;
+ iTimer = 0;
+ }
+
+ LOGTEXT(_L("CProfiler::~CProfiler - Finished"));
+ }
+
+// --------------------------------------------------------------------------------------------
+void CProfiler::ConstructL()
+ {
+ LOGTEXT(_L("CProfiler::ConstructL - Enter"));
+ TInt err(0);
+ TLex lex;
+
+ if ( iSettingsFileLocation.CompareF(KNullDesC) != 0 )
+ {
+ lex=(iSettingsFileLocation);
+ // parse the first command line argument, the command itself
+ lex.Mark();
+ lex.SkipCharacters();
+ if(lex.TokenLength() != 0)
+ {
+ // there is another item in the list
+ TPtrC filename = lex.MarkedToken();
+ LOGSTRING2("filename %S", &filename);
+ lex.SkipSpace();
+ lex.Mark();
+ lex.SkipCharacters();
+ if(lex.TokenLength() != 0)
+ {
+ TPtrC boot = lex.MarkedToken();
+ LOGTEXT(_L("boot mode"));
+ }
+ }
+ }
+
+ // create new sampler stream instance
+ iUserStream = CProfilerSampleStream::NewL(KStreamBufferSize);
+ if(!iUserStream)
+ {
+ LOGTEXT(_L("Profiler engine cannot reserve memory"));
+ User::Leave(KErrCancel); // operation cancelled
+ }
+
+ // engine status checker
+ iErrorChecker = CProfilerErrorChecker::NewL();
+ iErrorChecker->SetObserver(this);
+
+ // create and initiate plug-in controller instances
+ iSamplerHandler = CSamplerController::NewL(*iUserStream);
+ iWriterHandler = CWriterController::NewL(*iUserStream);
+
+ iWriterHandler->InitialiseWriterListL();
+
+ // set engine as an observer to sampler controller to get the notification of plugin load has ended
+ iSamplerHandler->SetObserver(this);
+
+ // default settings from sampler plugins, maximum 20 sampler plugins
+ iDefaultSamplerAttributesArray = new(ELeave) CArrayFixFlat<TSamplerAttributes>(20);
+
+ // set profiler status to initializing
+ iState = RProfiler::EInitializing;
+ iEngineStatus.Set(RProfiler::EInitializing);
+
+ // set default general settings, will be overdriven if changed in settings file
+ iGeneralAttributes.iTraceOutput.Copy(KDefaultTraceOutput);
+ iGeneralAttributes.iTraceFilePrefix.Copy(KDefaultTraceFilePrefix);
+ iGeneralAttributes.iSaveFileDrive.Copy(KDefaultTraceFileSaveDrive);
+ iGeneralAttributes.iTimedSamplingPeriod = KDefaultTimedSamplingPeriod;
+
+ RThread me;
+
+ me.SetPriority(EPriorityRealTime);
+
+ err = KErrGeneral;
+ TInt count = 0;
+
+ while(err != KErrNone && count < 30)
+ {
+ err = User::RenameThread(KProfilerName);
+ if(err != KErrNone)
+ {
+ LOGSTRING2("CProfiler: error renaming the thread, err %d", err);
+ User::Leave(err);
+ }
+ else break;
+ }
+
+ // set settings file loading preferences
+ iSettingsFileLoaded = EFalse;
+
+ // change status property to idle since initialization successfull
+ iState = RProfiler::EIdle;
+ if( iEngineStatus.Set((TInt)RProfiler::EIdle) != KErrNone )
+ {
+ LOGTEXT(_L("CProfiler::ConstructL - engine status property change failed"));
+ }
+
+ if( iUpdateStatus.Set(EFalse) != KErrNone )
+ {
+ LOGTEXT(_L("CProfiler::ConstructL - engine status property change failed"));
+ }
+
+ // create a server instance for clients to communicate with
+ iServer = CPServer::NewL(10,*this);
+
+ // close the handle
+ me.Close();
+
+ iTimer = CProfilerTimer::NewL(CActive::EPriorityStandard, *this);
+
+ LOGTEXT(_L("CProfiler::ConstructL - Exit"));
+
+ }
+
+CProfilerSampleStream* CProfiler::GetSamplerStream()
+ {
+ return iUserStream;
+ }
+
+void CProfiler::HandleSamplerControllerReadyL()
+ {
+ // load settings
+ // check if settings file already loaded
+ if(!iSettingsFileLoaded)
+ {
+ // load default settings file
+ LoadSettingsL();
+
+ iSettingsFileLoaded = ETrue;
+ }
+
+ // notify engine's launcher(UI or PIProfilerLauncher) to continue launch
+ RProcess::Rendezvous(KErrNone);
+ }
+
+void CProfiler::NotifyRequesterForSettingsUpdate()
+ {
+ // set update status P&S property true => update needed on UI side
+ iUpdateStatus.Set(ETrue);
+ }
+
+void CProfiler::HandleProfilerErrorChangeL(TInt aError)
+ {
+ LOGSTRING2("CProfiler::HandleProfilerErrorChangeL() - error received, %d", aError);
+
+ // check if profiler running
+ if(iState == RProfiler::ERunning)
+ {
+ // stop profiler if error occurred during the trace
+ iEngineStatus.Set(aError);
+
+ // stop samplers, NOTE! Writer plugins not stopped since
+ iSamplerHandler->StopSamplerPlugins();
+
+ // stop debug output plugin and write the rest of the trace data to output
+ if(iGeneralAttributes.iTraceOutput.CompareF(KOutputToDebugOutput) == 0)
+ {
+ // write the rest of trace data only if debug output selected
+ iWriterHandler->StopSelectedPlugin();
+ }
+ LOGSTRING2("CProfiler::HandleProfilerErrorChangeL - sampling stopped, going to state %d", RProfiler::EIdle);
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// Gets a value from settings file for certain attribute.
+// ----------------------------------------------------------------------------
+void CProfiler::DoGetValueFromSettingsArray(CDesC8ArrayFlat* aLineArray, const TDesC8& aAttribute, TDes8& aValue)
+ {
+ LOGTEXT(_L("CProfiler::DoGetValueFromSettingsFile()"));
+ _LIT8(KSettingItemSeparator, "=");
+
+ // read a line of given array
+ for (TInt i=0; i<aLineArray->MdcaCount(); i++)
+ {
+ // check if this line has a separator
+ TInt sepPos = aLineArray->MdcaPoint(i).Find(KSettingItemSeparator);
+ if (sepPos > 0)
+ {
+ // check that the element matches
+ if (aLineArray->MdcaPoint(i).Left(sepPos).CompareF(aAttribute) == 0)
+ {
+ // get the value
+ aValue.Copy(aLineArray->MdcaPoint(i).Right(aLineArray->MdcaPoint(i).Length()-sepPos-1));
+ break;
+ }
+ }
+ }
+ }
+
+void CProfiler::DoGetValueFromSettingsArray(CDesC8ArrayFlat* aLineArray, const TDesC8& aAttribute, TInt& aValue)
+ {
+ LOGTEXT(_L("CProfiler::DoGetValueFromSettingsFile()"));
+ _LIT8(KSettingItemSeparator, "=");
+
+ // read a line of given array
+ for (TInt i=0; i<aLineArray->MdcaCount(); i++)
+ {
+ // check if this line has a separator
+ TInt sepPos = aLineArray->MdcaPoint(i).Find(KSettingItemSeparator);
+ if (sepPos > 0)
+ {
+ // check that the element matches
+ if (aLineArray->MdcaPoint(i).Left(sepPos).CompareF(aAttribute) == 0)
+ {
+ // get the value
+ TLex8 parser(aLineArray->MdcaPoint(i).Right(aLineArray->MdcaPoint(i).Length()-sepPos-1));
+ parser.Val(aValue);
+ break;
+ }
+ }
+ }
+ }
+
+// --------------------------------------------------------------------------------------------
+TInt CProfiler::GetSamplerAttributesL(const RMessage2& aMessage)
+ {
+ TInt err(KErrNone);
+ TInt pos(0);
+
+ // get sampler count
+ TInt count(iDefaultSamplerAttributesArray->Count());
+
+ // write each of the default sampler plugin setting attributes over client-server session
+ for (TInt i(0); i<count; ++i)
+ {
+ TSamplerAttributes attr = iDefaultSamplerAttributesArray->At(i);
+ TPckgC<TSamplerAttributes> attrPckg(attr);
+
+ // write a TSamplerAttributes container at a time
+ aMessage.WriteL(0, attrPckg, pos);
+ pos += attrPckg.Length();
+ }
+
+ aMessage.Complete(err);
+ return err;
+ }
+
+// --------------------------------------------------------------------------------------------
+TInt CProfiler::SetSamplerAttributesL(const RMessage2& aMessage)
+ {
+ TSamplerAttributes attr;
+ TPckg<TSamplerAttributes> inAttr(attr);
+
+ TInt err = aMessage.Read(0, inAttr, 0);
+
+ // apply the changes directly to a plugin
+ iSamplerHandler->SetSamplerSettingsL(attr.iUid, attr);
+
+ aMessage.Complete(err);
+ return err;
+ }
+
+// --------------------------------------------------------------------------------------------
+TInt CProfiler::GetGeneralAttributesL(const RMessage2& aMessage)
+ {
+ TPckgBuf<TGeneralAttributes> generalSettings( iGeneralAttributes );
+
+ // write general attributes over client-server session
+ TInt err = aMessage.Write(0, generalSettings);
+
+ aMessage.Complete(err);
+ return err;
+ }
+
+// --------------------------------------------------------------------------------------------
+TInt CProfiler::SetGeneralAttributesL(const RMessage2& aMessage)
+ {
+ // read the general settings from message
+ TGeneralAttributes attr;
+ TPckg<TGeneralAttributes> inPckg(attr);
+ TInt err = aMessage.Read(0, inPckg, 0);
+
+ // copy to the general attributes
+ iGeneralAttributes.iSaveFileDrive.Copy(attr.iSaveFileDrive);
+ iGeneralAttributes.iTraceFilePrefix.Copy(attr.iTraceFilePrefix);
+ iGeneralAttributes.iTraceOutput.Copy(attr.iTraceOutput);
+ iGeneralAttributes.iTimedSamplingPeriod = attr.iTimedSamplingPeriod;
+
+ aMessage.Complete(err);
+ return err;
+ }
+
+TInt CProfiler::GetSamplerAttributeCountL(const RMessage2& aMessage)
+ {
+ // get the plugin array count and wrap it to TPckgBuf<>
+ TPckgBuf<TInt> attributeCount(iDefaultSamplerAttributesArray->Count());
+
+ // write general attributes over client-server session
+ TInt err = aMessage.Write(0, attributeCount);
+
+ aMessage.Complete(err);
+ return err;
+ }
+
+TInt CProfiler::RefreshStatus(const RMessage2& aMessage)
+ {
+ TInt err(KErrNone);
+
+ // update profiler status for requester
+ iEngineStatus.Set(iState);
+
+ aMessage.Complete(err);
+ return err;
+ }
+
+// --------------------------------------------------------------------------------------------
+TInt CProfiler::LoadSettingsL(/*const TDesC& configFile*/)
+ {
+ RFs fileServer;
+ RFile file;
+ TInt err(KErrNone);
+
+ // connect to file server
+ err = fileServer.Connect();
+
+ // check if file server can be connected
+ if (err != KErrNone)
+ {
+ // file server couldn't be connected
+ return KErrGeneral;
+ }
+
+ // check if settings file location length reasonable
+ if ( iSettingsFileLocation.CompareF(KNullDesC) == 0 )
+ {
+ // open the file with the default path and name
+ TBuf<256> pathAndName;
+ pathAndName.Append(PathInfo::PhoneMemoryRootPath());
+ pathAndName.Append(KProfilerSettingsFileName);
+ iSettingsFileLocation.Copy(pathAndName);
+ LOGTEXT(_L("CProfiler::LoadSettings - Opening settings file with name (with the default path)"));
+ LOGTEXT(pathAndName);
+ }
+
+ // open the file with the given path and name
+ err = file.Open(fileServer,iSettingsFileLocation,EFileRead);
+
+
+ // check if RFile::Open() returned error
+ if (err != KErrNone)
+ {
+ // file couldn't be opened
+ LOGTEXT(_L("CProfiler::LoadSettings - Failed to open settings, using default"));
+
+ // check if settings already loaded
+ if(iDefaultSamplerAttributesArray->Count() > 0)
+ {
+ // reset default settings array
+ iDefaultSamplerAttributesArray->Reset();
+ }
+
+ // load default settings, instead of settings file ones
+ iSamplerHandler->GetSamplerAttributesL(iDefaultSamplerAttributesArray);
+
+ fileServer.Close();
+ return KErrNone;
+ }
+
+ // initialize iSavedLineArray, initial settings file lines 64
+ if(iSavedLineArray)
+ {
+ iSavedLineArray->Reset();
+ }
+ else
+ {
+ iSavedLineArray = new (ELeave) CDesC8ArrayFlat(KSavedLineCount);
+ }
+
+ iSavedLinesCount = KSavedLineCount;
+
+ // get size of the file
+ TInt fileSize(0);
+ err = file.Size(fileSize);
+ // check if an error occurred reading the file size
+ if(err != KErrNone)
+ {
+ return KErrGeneral; // could not find the size
+ }
+
+ // sanity check for the file size
+ if (fileSize < 3 || fileSize > 20000)
+ {
+ fileSize = KSettingsFileSize;
+ return KErrNotSupported;
+ }
+
+ // read the contents of the file to buffer.
+ iSettingsBuffer.Zero();
+ file.Read(iSettingsBuffer, fileSize);
+ file.Close();
+ fileServer.Close();
+ LOGSTRING2("CProfiler::LoadSettings: read %d bytes",iSettingsBuffer.Length());
+
+ // append end mark "[end]"
+ iSettingsBuffer.Append(KEndMark);
+ // force an ending newline
+ iSettingsBuffer.Append('\n');
+
+ // next fill the saved settings array (CDesC8ArrayFlat) for further comparison with changes and default values
+ TBuf8<384> tmpBuf;
+ TInt lineCount(0);
+ TBool commentFound(EFalse);
+ for (TInt i(0); i<iSettingsBuffer.Length(); i++) // loop all chars
+ {
+ // if new line char found, create a new text line
+ if (iSettingsBuffer[i]=='\r' || iSettingsBuffer[i]=='\n')
+ {
+ // check if collected string has reasonable length
+ if (tmpBuf.Length() > 0)
+ {
+ // remove extra spaces
+ tmpBuf.TrimAll();
+ // check if the size of the array too small
+ if(lineCount >= iSavedLinesCount)
+ {
+ iSavedLineArray->ExpandL(20); // expand by 20 lines
+ iSavedLinesCount += 20;
+ }
+ iSavedLineArray->AppendL(tmpBuf);
+ tmpBuf.Copy(KNullDesC8);
+ lineCount++;
+ }
+ commentFound = EFalse;
+ }
+ // check if comment mark ';' is found on the line, skip the rest of the line
+ else if(iSettingsBuffer[i]==';')
+ {
+ commentFound = ETrue;
+ }
+ // otherwise append a char to the temp line buffer if it is a wanted ASCII char
+ else if (iSettingsBuffer[i]>=32 && iSettingsBuffer[i]<=127 && !commentFound)
+ {
+ tmpBuf.Append(iSettingsBuffer[i]);
+ }
+ }
+
+ // empty tmpBuf
+ tmpBuf.Copy(KNullDesC8);
+ // check settings file version
+ DoGetValueFromSettingsArray(iSavedLineArray, KProfilerVersionTag, tmpBuf);
+
+ TBuf8<32> version;
+ version.Copy(PROFILER_VERSION_SHORT);
+
+ // check if settings file version is
+ if(tmpBuf.CompareF(version) >= 0)
+ {
+ // update general attributes
+ UpdateSavedGeneralAttributes(iSavedLineArray);
+
+ // update settings to sampler plugins and save the attributes to default array
+ iSamplerHandler->UpdateSavedSamplerAttributesL(iSavedLineArray, iDefaultSamplerAttributesArray);
+ }
+ else
+ {
+ // check if settings already loaded
+ if(iDefaultSamplerAttributesArray)
+ {
+ // reset default settings array
+ iDefaultSamplerAttributesArray->Reset();
+
+ // get the default settings if settings file version too old
+ iSamplerHandler->GetSamplerAttributesL(iDefaultSamplerAttributesArray);
+ }
+ }
+
+ return err;
+ }
+
+// --------------------------------------------------------------------------------------------
+void CProfiler::UpdateSavedGeneralAttributes(CDesC8ArrayFlat* aSavedAttributes)
+ {
+ // get saved general settings
+ DoGetValueFromSettingsArray(aSavedAttributes, KGenericTraceOutput, iGeneralAttributes.iTraceOutput);
+ DoGetValueFromSettingsArray(aSavedAttributes, KGenericTraceFilePrefix, iGeneralAttributes.iTraceFilePrefix);
+ DoGetValueFromSettingsArray(aSavedAttributes, KGenericTraceFileSaveDrive, iGeneralAttributes.iSaveFileDrive);
+ DoGetValueFromSettingsArray(aSavedAttributes, KGenericTimedProfilingPeriod, iGeneralAttributes.iTimedSamplingPeriod);
+ }
+
+TBool CProfiler::CheckLocationSanity(RFs& fs, const TDesC8& aLocation)
+ {
+ TBool ret(EFalse);
+ TBool noDiskSpace(EFalse);
+ TBuf<32> drive;
+
+ CnvUtfConverter::ConvertToUnicodeFromUtf8(drive, aLocation);
+ TDriveUnit driveUnit = TDriveUnit(drive);
+
+ // check that the root folder is correct
+ if (drive.Length() > 2 && BaflUtils::CheckFolder(fs, drive.Left(3)) == KErrNone)
+ {
+ // test available disk space
+ TRAP_IGNORE((noDiskSpace = SysUtil::DiskSpaceBelowCriticalLevelL(&fs, 0, driveUnit)));
+ if(!noDiskSpace)
+ ret = ETrue;
+ }
+
+ return ret;
+ }
+
+TInt CProfiler::HandleGeneralSettingsChange()
+ {
+ // local literals
+ _LIT8(KBackSlash, "\\");
+ _LIT8(KTraceFileExtension, ".dat");
+
+ TBuf8<KFileNameBufSize> fileNameBuf;
+ TBuf8<10> number;
+ TInt result(0);
+ TInt index(1);
+ TInt hashLocation(0);
+ TParse parse;
+
+ // check if plugin writer changed
+ if(iGeneralAttributes.iTraceOutput.CompareF(KOutputToDebugOutput) == 0)
+ {
+ iWriterHandler->SetPluginActive( KDebOutWriterPluginUid, EWriterPluginEnabled );
+ }
+ else
+ {
+ RFs fileServer;
+ RFile file;
+
+ // connect to the file server
+ result = fileServer.Connect();
+ if(result == KErrNone)
+ {
+ // disk writer plugin will be activated
+ iWriterHandler->SetPluginActive( KDiskWriterPluginUid, EWriterPluginEnabled );
+
+ // fix the trace data file location as well
+ iTotalPrefix.Zero();
+ iTotalPrefix.Append(iGeneralAttributes.iSaveFileDrive);
+
+ // check that trace file location sane
+ if(!CProfiler::CheckLocationSanity(fileServer, iTotalPrefix))
+ {
+ fileServer.Close();
+ return KErrPathNotFound;
+ }
+
+ // remove extra spaces
+ iTotalPrefix.TrimAll();
+
+ // check the directory contains a trailing backlash
+ if(iTotalPrefix.Right(1) != _L8("\\") &&
+ iTotalPrefix.Right(1) != _L8("/"))
+ {
+ // append backslash to end
+ iTotalPrefix.Append(KBackSlash);
+ }
+
+ // append trace file name prefix e.g. PIProfiler_#
+ iTotalPrefix.Append(iGeneralAttributes.iTraceFilePrefix);
+
+ // locate '#' mark for finding the next free trace file name, e.g. E:\data\PIProfiler_4.dat
+ hashLocation = iTotalPrefix.Locate('#');
+ if( hashLocation == KErrNotFound )
+ {
+ // append simply at the end of the trace file prefix, no need to inform user
+ iTotalPrefix.Append('#');
+ // get new hash mark location
+ hashLocation = iTotalPrefix.Locate('#');
+ }
+
+ // add the file extension
+ iTotalPrefix.Append(KTraceFileExtension);
+
+ // search for files with different indices
+ // until a free filename is found
+ while(result != KErrNotFound)
+ {
+ fileNameBuf.Zero();
+ // start with the original prefix
+ fileNameBuf.Append(iTotalPrefix);
+ // convert the number to a descriptor
+ number.Num(index);
+ // replace the hashmark with the real number
+ fileNameBuf.Replace(hashLocation,1,number);
+
+ // make a copy to the iFileNameStream descriptor
+ iFileNameStream.Zero();
+ CnvUtfConverter::ConvertToUnicodeFromUtf8(iFileNameStream, fileNameBuf);
+
+ LOGSTRING2("CProfiler::HandleGeneralSettingsChange() - trying to open files %S ",&iFileNameStream);
+
+ if((result = parse.Set(iFileNameStream, NULL, NULL)) != KErrNone)
+ {
+ // break loop if fails, problems in file name => change to log into debug output
+ break;
+ }
+
+ // create directory for trace files if not exists
+ result = fileServer.MkDirAll(parse.FullName());
+
+ // check that file server responded with KErrNone or KErrAlreadyExists
+ if( result != KErrNone && result != KErrAlreadyExists)
+ {
+ // if some other result, e.g. memory full => break
+ break;
+ }
+
+ // attempt opening the file
+ result = file.Open(fileServer,parse.FullName(),EFileShareReadersOnly);
+ if(result != KErrNotFound)
+ {
+ if( result != KErrNotReady &&
+ result != KErrServerBusy )
+ {
+ // close the file if it could be opened
+ LOGSTRING2("Found STREAM file with index %d",index);
+ index++;
+ }
+ else
+ {
+ // in boot measurements the file system might not be ready yet.
+ LOGSTRING2("Problem in opening STREAM file %d",index);
+ }
+ file.Close();
+ }
+ } // while
+ }
+ else
+ {
+ // return error code
+ return result;
+ }
+
+ TUint32 id(iWriterHandler->GetActiveWriter()->GetWriterType());
+
+ // check if a file name is one that does not exist and selected plugin is disk writer
+ if(result == KErrNotFound && id == KDiskWriterPluginUid.iUid)
+ {
+ // write right trace data file name to disk writer plugin
+ iWriterHandler->SetPluginSettings( KDiskWriterPluginUid, iFileNameStream );
+ }
+ else
+ {
+ // return error if could not create trace log file
+ return result;
+ }
+ // close file server
+ fileServer.Close();
+ } // if output == KOutputToDebugOutput
+ return KErrNone;
+ }
+
+// --------------------------------------------------------------------------------------------
+void CProfiler::HandleTimerExpiresL(TInt aError)
+ {
+ LOGSTRING2("CProfiler::HandleTimerExpiresL - Error: %d", aError);
+ this->ControlL(RProfiler::EStopSampling);
+ if( CPServer::iClientCount <= 0 )
+ {
+ LOGSTRING("CProfiler::HandleTimerExpiresL - No clients attached, shutting down server...");
+ this->ControlL(RProfiler::EExitProfiler);
+ }
+ }
+
+// --------------------------------------------------------------------------------------------
+void CProfiler::SaveSettingsL()
+ {
+ LOGTEXT(_L("CProfiler::SaveSettings()"));
+
+ // local literal
+ _LIT(KGeneralHeader, "[general]");
+ _LIT(KVersionHeader, "version");
+ _LIT8(KPIProfilerSettingsHeader, "; PI Profiler Settings File");
+ _LIT8(KGeneralSettingsHeader, "; general settings");
+ _LIT8(KOutputFileDescription,"; \"output_type=file_system\" writes *.dat file to external memory");
+ _LIT8(KOutputDebugDescription,"; \"output_type=debug_output\" writes *.dat file to debug port");
+ _LIT8(KOutputFilePrefixDescription,"; if writing to file, prefix of the *.dat file\r\n; first '#' in the prefix is replaced with an integer");
+ _LIT8(KOutputSaveDriveDescription,"; if writing to file, the location to store the *.dat file");
+ _LIT8(KTimedProfilingPeriod,"; period (in seconds) used when using timed profiling");
+
+ RFs fs;
+ RFile settingsFile;
+ TInt err(KErrNone);
+ TBuf8<384> line;
+
+ // connect to file server
+ err = fs.Connect();
+ if( err != KErrNone )
+ {
+ // failed to write settings to settings file
+ return;
+ }
+
+ // create and set the private path
+ fs.CreatePrivatePath(EDriveC);
+ fs.SetSessionToPrivate(EDriveC);
+
+ // create the new settings file
+ err = settingsFile.Replace(fs, iSettingsFileLocation, EFileWrite);
+ if(err != KErrNone)
+ return;
+
+ CleanupClosePushL(settingsFile);
+
+ // write the header
+ line.Copy(KPIProfilerSettingsHeader);
+ line.Append(KNewLineSeparator);
+ line.Append(KNewLineSeparator);
+ settingsFile.Write(line);
+
+ // write the header
+ line.Copy(KGeneralSettingsHeader);
+ line.Append(KNewLineSeparator);
+ settingsFile.Write(line);
+
+ // write all generic settings
+ line.Copy(KGeneralHeader);
+ line.Append(KNewLineSeparator);
+ settingsFile.Write(line);
+
+ // write version info
+ line.Copy(KVersionHeader);
+ line.Append(KEquals);
+ line.Append(PROFILER_VERSION_SHORT);
+ line.Append(KNewLineSeparator);
+ settingsFile.Write(line);
+
+ // output explanation
+ line.Copy(KOutputFileDescription);
+ line.Append(KNewLineSeparator);
+ line.Append(KOutputDebugDescription);
+ line.Append(KNewLineSeparator);
+ settingsFile.Write(line);
+
+ // write trace output
+ line.Copy(KGenericTraceOutput);
+ line.Append(KEquals);
+ line.Append(iGeneralAttributes.iTraceOutput);
+ line.Append(KNewLineSeparator);
+ settingsFile.Write(line);
+
+ // file prefix explanation
+ line.Copy(KOutputFilePrefixDescription);
+ line.Append(KNewLineSeparator);
+ settingsFile.Write(line);
+
+ // write trace file prefix
+ line.Copy(KGenericTraceFilePrefix);
+ line.Append(KEquals);
+ line.Append(iGeneralAttributes.iTraceFilePrefix);
+ line.Append(KNewLineSeparator);
+ settingsFile.Write(line);
+
+ // file prefix explanation
+ line.Copy(KOutputSaveDriveDescription);
+ line.Append(KNewLineSeparator);
+ settingsFile.Write(line);
+
+ // write trace file location
+ line.Copy(KGenericTraceFileSaveDrive);
+ line.Append(KEquals);
+ line.Append(iGeneralAttributes.iSaveFileDrive);
+ line.Append(KNewLineSeparator);
+ settingsFile.Write(line);
+
+ // timed profiling period explanation
+ line.Copy(KTimedProfilingPeriod);
+ line.Append(KNewLineSeparator);
+ settingsFile.Write(line);
+
+ // Write timed profiling period value
+ line.Copy(KGenericTimedProfilingPeriod);
+ line.Append(KEquals);
+ TBuf<16> tmpNum;
+ tmpNum.AppendNum(iGeneralAttributes.iTimedSamplingPeriod);
+ line.Append(tmpNum);
+ line.Append(KNewLineSeparator);
+ settingsFile.Write(line);
+
+ // reset the default attributes array
+ iDefaultSamplerAttributesArray->Reset();
+
+ // update the latest changes from plugins
+ iSamplerHandler->GetSamplerAttributesL(iDefaultSamplerAttributesArray);
+
+ // call CSamplerController to write all sampler settings
+ iSamplerHandler->ComposeAttributesToSettingsFileFormat(settingsFile, iDefaultSamplerAttributesArray);
+
+ CleanupStack::PopAndDestroy(); //settingsFile
+ // close file
+ fs.Close();
+ }
+
+TInt CProfiler::CheckOldProfilerRunning()
+ {
+ TFindProcess procName;
+ procName.Find(_L("BappeaProf.exe*"));
+ TFullName aResult;
+ TInt err(KErrNone);
+ RProcess proc;
+
+ // now check if old Profiler is still running on
+ err = procName.Next(aResult);
+ // check if old profiler process found
+ if(err == KErrNone)
+ {
+ // other process found, i.e. right process to communicate with, in case started from eshell
+ err = proc.Open(procName);
+ if(err == KErrNone)
+ {
+ if(proc.ExitCategory().Length() > 0)
+ {
+ proc.Close();
+ // process already exited => create a new one
+ return KErrNotFound;
+ }
+ proc.Close();
+ }
+ // return error for error handling
+ return KErrAlreadyExists;
+ }
+ return err;
+ }
+
+// --------------------------------------------------------------------------------------------
+void CProfiler::HandleError(TInt aErr)
+ {
+ // write error to status property to inform requester
+ TInt err(iEngineStatus.Set(KEngineStatusPropertyCat, EProfilerEngineStatus, aErr));
+ if(err != KErrNone)
+ RDebug::Print(_L("CProfiler::HandleError() - error setting status: %d"), err);
+ }
+
+// --------------------------------------------------------------------------------------------
+TInt CProfiler::ControlDataL(TInt aCommand,TAny* value1,TAny* /*value2*/)
+ {
+ LOGSTRING3("CProfiler::ControlData %d, 0x%x",aCommand,value1);
+
+ _LIT(KDebugOutput, "debug_output");
+ _LIT(KFileOutput, "file_system");
+ _LIT8(KOutputToDebugOutput, "debug_output");
+
+ TDes* desc;
+ TPtrC ptrDesc;
+
+ switch(aCommand)
+ {
+ // new controls
+ case RProfiler::EGetFileName:
+ {
+ LOGTEXT(_L("Profiler::EGetFileName - start"));
+ LOGSTRING2("Profiler::EGetFileName - total file name is: %S",(TDes*)value1);
+ desc = (TDes*)value1;
+ desc->Zero();
+ desc->Append(iFileNameStream);
+ LOGSTRING2("Profiler::EGetFileName - now total file name is: %S",(TDes*)value1);
+ return KErrNone;
+ }
+ case RProfiler::EGetActiveWriter:
+ {
+ LOGTEXT(_L("Profiler::EGetActiveWriter - start"));
+ desc = (TDes*)value1;
+ desc->Zero();
+ if(iGeneralAttributes.iTraceOutput.CompareF(KOutputToDebugOutput) == 0)
+ {
+ desc->Append(KDebugOutput);
+ }
+ else
+ {
+ desc->Append(KFileOutput);
+ }
+ return KErrNone;
+ }
+ }
+
+ return KErrNone;
+ }
+
+// --------------------------------------------------------------------------------------------
+TInt CProfiler::ControlL(TInt aCommand)
+ {
+ LOGSTRING2("CProfiler::Control - Controlling ProfilerEngine %d",aCommand);
+ TInt err(KErrNone);
+
+ switch (aCommand)
+ {
+ case RProfiler::EStartSampling:
+ case RProfiler::EStartTimedSampling:
+ {
+ // check first if old Profiler already running
+ err = CheckOldProfilerRunning();
+ if(err == KErrAlreadyExists)
+ {
+ // if exists do not start a profiling process since corrupts the collected trace data
+ HandleError(err);
+ err = KErrNone;
+ return err;
+ }
+
+ // save settings before launching the profiler
+ // reason: the profiling may have set to the background => need for get right settings
+ SaveSettingsL();
+
+ // set the general settings to writer plugins to reflect the latest changes
+ err = HandleGeneralSettingsChange();
+ if(err == KErrNone)
+ {
+ // reset the buffers before new profiling
+ iUserStream->ResetBuffers();
+
+ // give the CProfilerSampleStream a handle to current writer
+ iUserStream->SetWriter(*iWriterHandler->GetActiveWriter());
+
+ // set initially debug output writer active
+ err = iWriterHandler->StartSelectedPlugin();
+
+ // check that writer plugin started
+ if(err != KErrNone)
+ {
+ // if not started handle error
+ HandleError(err);
+ }
+ else
+ {
+ // start activated sampler plug-in, NOTE: plugins check if errors occur in startup for some reason
+ iSamplerHandler->StartSamplerPluginsL();
+
+ // set engine state P&S property to running, e.g. for PIProfiler UI to read
+ iState = RProfiler::ERunning;
+
+ // set the engine into running mode
+ iEngineStatus.Set(iState);
+ }
+ }
+ else
+ {
+ // handle error and notify requester
+ HandleError(err);
+ }
+
+ if( aCommand == RProfiler::EStartTimedSampling )
+ {
+ iTimer->After(iGeneralAttributes.iTimedSamplingPeriod);
+ LOGTEXT(_L("CProfiler::Control - Finished processing EStartTimedSampling!"));
+ }
+ else
+ {
+ LOGTEXT(_L("CProfiler::Control - Finished processing EStartSampling!"));
+ }
+
+ return err;
+ }
+ case RProfiler::EStopSampling:
+ LOGTEXT(_L("CProfiler::Control - Starting to stop sampling..."));
+ // stop sampler plugins
+ if(iState == RProfiler::ERunning)
+ {
+ iState = RProfiler::EStopping;
+ iEngineStatus.Set(RProfiler::EStopping);
+
+ iSamplerHandler->StopSamplerPlugins();
+
+ // finalize the filled buffer writing
+ iUserStream->Finalise();
+
+ // stop output plugin and write the rest of the trace data to output
+ LOGTEXT(_L("CProfiler::Control - stopping writer"));
+ iWriterHandler->StopSelectedPlugin();
+
+ // set engine state P&S property idle
+ iState = RProfiler::EIdle;
+ iEngineStatus.Set(RProfiler::EIdle);
+
+ LOGSTRING2("CProfiler::Control - sampling stopped, going to state %d", RProfiler::EIdle);
+ }
+ return KErrNone;
+
+ case RProfiler::EExitProfiler:
+ {
+ // save settings into settings file when exiting
+ SaveSettingsL();
+
+ if(iUserStream)
+ {
+ delete iUserStream;
+ iUserStream = NULL;
+ }
+
+ // set engine state P&S property idle
+ iState = RProfiler::EIdle;
+ iEngineStatus.Set(RProfiler::EIdle);
+
+ LOGTEXT(_L("Stopping Activer Scheduler"));
+ CActiveScheduler::Stop();
+ LOGTEXT(_L("Stopped Activer Scheduler"));
+
+ return KErrNone;
+ }
+
+ case RProfiler::EAttachClient:
+ {
+ // Increase client reference count
+ ++CPServer::iClientCount;
+ LOGSTRING2("Increased client reference count to: %d", CPServer::iClientCount);
+ return KErrNone;
+ }
+ case RProfiler::ERemoveClient:
+ {
+ // Decrease client reference count
+ --CPServer::iClientCount;
+ LOGSTRING2("Decreasing client reference count to: %d", CPServer::iClientCount);
+ return KErrNone;
+ }
+ }
+
+ LOGTEXT(_L("CProfiler::Control - returning"));
+
+ return err;
+ }
+
+// --------------------------------------------------------------------------------------------
+void CProfiler::Finalise()
+ {
+ LOGTEXT(_L("CProfiler::Finalise - Finished processing EStopSampling!"));
+ }
+
+// --------------------------------------------------------------------------------------------
+RProfiler::TSamplerState CProfiler::State() const
+ {
+ return iState;
+ }
+
+/*
+ *
+ * Class CPServer definition
+ *
+ */
+// --------------------------------------------------------------------------------------------
+inline const CPServer& CPSession::Server() const
+ {
+ return *static_cast<const CPServer*>(CSession2::Server());
+ }
+
+// --------------------------------------------------------------------------------------------
+void CPSession::ServiceL(const RMessage2& aMessage)
+ {
+ LOGTEXT(_L("CPSession::ServiceL - Starting to process message"));
+ TInt err(KErrNone);
+
+ if(aMessage.Function() == RProfiler::EGetGeneralAttributes)
+ {
+ Server().GetGeneralAttributesL(aMessage);
+ }
+ else if(aMessage.Function() == RProfiler::ESetGeneralAttributes)
+ {
+ Server().SetGeneralAttributesL(aMessage);
+ }
+ else if(aMessage.Function() == RProfiler::EGetSamplerAttributes)
+ {
+ Server().GetSamplerAttributesL(aMessage);
+ }
+ else if(aMessage.Function() == RProfiler::EGetSamplerAttributeCount)
+ {
+ Server().GetSamplerAttributeCountL(aMessage);
+ }
+ else if(aMessage.Function() == RProfiler::ESetSamplerAttributes)
+ {
+ Server().SetSamplerAttributesL(aMessage);
+ }
+ else if(aMessage.Function() == RProfiler::ERefreshProfilerStatus)
+ {
+ Server().RefreshStatus(aMessage);
+ }
+ else if(aMessage.Ptr0() == 0 && aMessage.Ptr1() == 0 && aMessage.Ptr2() == 0)
+ {
+ LOGTEXT(_L("Ptr0 && Ptr1 == 0 && Ptr2 == 0"));
+ aMessage.Complete(Server().ControlL(RProfiler::TCommand(aMessage.Function())));
+ LOGTEXT(_L("CPSession::ServiceL - Message completed"));
+ }
+ else if(aMessage.Ptr0() != 0 && aMessage.Ptr1() != 0 && aMessage.Ptr2() != 0)
+ {
+ LOGTEXT(_L("Error with message, all pointers contain data!"));
+ }
+
+ else if (aMessage.Ptr0() != 0)
+ {
+ if(aMessage.Ptr1() == 0)
+ {
+ LOGTEXT(_L("ServiceL: Ptr0 != 0 && Ptr1 == 0"));
+ // provided value is a descriptor
+ TBuf<64>* dst = new TBuf<64>;
+ aMessage.ReadL(0,*dst,0);
+
+ err = Server().ControlDataL(aMessage.Function(),(TAny*)dst);
+ delete dst;
+ aMessage.Complete(err);
+ LOGTEXT(_L("CPSession::ServiceL - Message completed"));
+ }
+ else
+ {
+ LOGTEXT(_L("ServiceL: Ptr0 != 0 && Ptr1 != 0"));
+ // provided value is a descriptor
+ TBuf<64>* dst = new TBuf<64>;
+ aMessage.ReadL(0,*dst,0);
+
+ TUint32 num1 = (TUint32)aMessage.Ptr1();
+
+ err = Server().ControlDataL(aMessage.Function(),(TAny*)dst, (TAny*)num1);
+ delete dst;
+ aMessage.Complete(err);
+ LOGTEXT(_L("CPSession::ServiceL - Message completed"));
+ }
+ }
+ else if (aMessage.Ptr1() != 0)
+ {
+ LOGTEXT(_L("ServiceL: Ptr1 != 0"));
+ // provided value is a TUint32
+ if( ((TUint32)aMessage.Ptr3()) == 0xffffffff)
+ {
+ TUint32 num = (TUint32)aMessage.Ptr1();
+ err = Server().ControlDataL(aMessage.Function(),(TAny*)num);
+ aMessage.Complete(err);
+ LOGTEXT(_L("CPSession::ServiceL - Message completed"));
+ }
+ else
+ {
+ LOGTEXT(_L("ServiceL: Ptr3 != 0xffffffff"));
+ TUint32 num1 = (TUint32)aMessage.Ptr1();
+ TUint32 num2 = (TUint32)aMessage.Ptr3();
+ err = Server().ControlDataL(aMessage.Function(),(TAny*)num1,(TAny*)num2);
+ aMessage.Complete(err);
+ LOGTEXT(_L("CPSession::ServiceL - Message completed"));
+ }
+ }
+ else if (aMessage.Ptr2() != 0)
+ {
+ // command requests for data, provided
+ // value should be a descriptor
+ if( ((TUint32)aMessage.Ptr3()) == 0xffffffff)
+ {
+ LOGTEXT(_L("ServiceL: Ptr2 != 0 && Ptr3 == 0xffffffff"));
+
+ TBuf<256>* src = new TBuf<256>;
+ src->Zero();
+ err = Server().ControlDataL(aMessage.Function(),(TAny*)src);
+
+ LOGSTRING2("Got sampler data %S",src);
+
+ aMessage.WriteL(2, *src, 0);
+
+ delete src;
+ aMessage.Complete(err);
+ LOGTEXT(_L("CPSession::ServiceL - Message completed"));
+ }
+ else
+ {
+ LOGTEXT(_L("ServiceL: Ptr2 != 0 && Ptr3 != 0xffffffff"));
+
+ TUint32 num1 = (TUint32)aMessage.Ptr2(); // containing id
+ TBuf<256>* buffer = new TBuf<256>; // Text data, e.g. plug-in name or description
+
+ LOGSTRING3("Getting data for sampler: 0x%X, buffer max len %d",num1, aMessage.GetDesMaxLength(3));
+
+ err = Server().ControlDataL(aMessage.Function(), (TAny*)num1, (TAny*)buffer);
+
+ LOGSTRING2("Got sampler data %S",&buffer);
+
+ // write back to same parameter
+ aMessage.WriteL(3, *buffer, 0);
+
+ delete buffer;
+ aMessage.Complete(err);
+ LOGTEXT(_L("CPSession::ServiceL - Message completed"));
+ }
+ }
+ LOGTEXT(_L("CPSession::ServiceL - Message processed"));
+ }
+
+// --------------------------------------------------------------------------------------------
+MProfilerController* CPServer::NewL(TInt aPriority, MProfilerEngine& aEngine)
+ {
+ LOGTEXT(_L("CPServer::NewL - Enter"));
+ CPServer* self = new(ELeave) CPServer(aPriority, aEngine);
+ CleanupStack::PushL(self);
+ self->StartL(KProfilerName);
+ CleanupStack::Pop();
+ LOGTEXT(_L("CPSession::NewL - Exit"));
+ return self;
+ }
+
+// --------------------------------------------------------------------------------------------
+CPServer::CPServer(TInt aPriority, MProfilerEngine& aEngine)
+ : CServer2(aPriority), MProfilerController(aEngine)
+ {
+
+ }
+
+// --------------------------------------------------------------------------------------------
+void CPServer::Release()
+ {
+ delete this;
+ }
+
+// --------------------------------------------------------------------------------------------
+CSession2* CPServer::NewSessionL(const TVersion&,const RMessage2&) const
+ {
+ return new(ELeave) CPSession();
+ }
+
+/*
+ *
+ * Static methods for controlling the profiler
+ * through command line
+ *
+ */
+// --------------------------------------------------------------------------------------------
+static void RunEngineServerL(const TDesC& aSettingsFile)
+ {
+ RDebug::Print(_L("Profiler: RunEngineServerL() - Install active scheduler"));
+ CActiveScheduler* pS = new CActiveScheduler;
+ CActiveScheduler::Install(pS);
+ CProfiler* p = CProfiler::NewLC(aSettingsFile);
+ CActiveScheduler::Start();
+ p->Finalise();
+ CleanupStack::PopAndDestroy(p);
+ delete pS;
+ }
+
+// --------------------------------------------------------------------------------------------
+static TInt TestSettingsFile(const TDesC& configFile)
+ {
+ RFs fs;
+ LOGSTRING2("TestSettingsFile: entry %S", &configFile);
+ // check if file server can be connected
+ if (fs.Connect() != KErrNone)
+ {
+ LOGTEXT(_L("TestSettingsFile: could not connect file server"));
+ // file server couldn't be connected, return false
+ return KErrNotFound;
+ }
+
+ // check if config file name length is > 0
+ if (configFile.Length() > 0)
+ {
+ LOGTEXT(_L("TestSettingsFile: checking location sanity"));
+ // check sanity of settings file location
+ if(BaflUtils::CheckFolder(fs, configFile) != KErrNone)
+ {
+ LOGTEXT(_L("TestSettingsFile: location sanity check failed"));
+ fs.Close();
+ return KErrGeneral;
+ }
+ }
+ else
+ {
+ // configFile length 0, return false
+ LOGTEXT(_L("TestSettingsFile: config file string null length"));
+ fs.Close();
+ return KErrNotFound;
+ }
+ // return true if tests passed
+ LOGTEXT(_L("TestSettingsFile: exiting..."));
+ fs.Close();
+ return KErrNone;
+ }
+
+// --------------------------------------------------------------------------------------------
+GLDEF_C TInt E32Main()
+ {
+ // parse command line arguments
+ TBuf<256> c;
+ TInt err(KErrNone);
+
+ // copy the full command line with arguments into a buffer
+ User::CommandLine(c);
+
+ TBuf<256> fileName;
+ fileName.Append(c); // only one settings param should be
+ LOGSTRING3("Filename is %S, response %d 1", &fileName, err);
+ err = TestSettingsFile(fileName);
+ if(err != KErrNone)
+ {
+ LOGSTRING3("Filename is %S, response %d 2", &fileName, err);
+ // settings file does not exist, copy null desc to file name
+ fileName.Copy(KNullDesC);
+ }
+
+ LOGSTRING3("Filename is %S, response %d 3", &fileName, err);
+
+ // if no command line arguments found just start the profiler process
+ __UHEAP_MARK;
+ CTrapCleanup* cleanup = CTrapCleanup::New();
+ TInt ret(KErrNoMemory);
+ if( cleanup )
+ {
+ TRAPD( ret, RunEngineServerL(fileName) );
+ RDebug::Print(_L("Profiler: E32Main() - ret %d"), ret);
+ delete cleanup;
+ }
+ __UHEAP_MARKEND;
+
+ return ret;
+ }
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/src/ProfilerErrorChecker.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,115 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <e32std.h>
+#include <e32base.h>
+#include <e32property.h>
+
+#include <piprofiler/ProfilerTraces.h>
+
+#include "ProfilerErrorChecker.h"
+
+// properties
+const TUid KEngineStatusPropertyCat={0x2001E5AD};
+enum TEnginePropertyKeys
+ {
+ EProfilerEngineStatus = 8,
+ EProfilerErrorStatus
+ };
+
+/*
+ *
+ * CProfilerErrorChecker class implementation
+ *
+ */
+CProfilerErrorChecker* CProfilerErrorChecker::NewL()
+ {
+ CProfilerErrorChecker* self = new(ELeave) CProfilerErrorChecker;
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+ }
+
+// --------------------------------------------------------------------------------------------
+CProfilerErrorChecker::CProfilerErrorChecker() :
+ CActive(EPriorityStandard)
+ {
+ }
+
+CProfilerErrorChecker::~CProfilerErrorChecker()
+ {
+ Cancel();
+ iErrorStatus.Close();
+ }
+
+// --------------------------------------------------------------------------------------------
+void CProfilerErrorChecker::ConstructL()
+ {
+
+ LOGTEXT(_L("Trying to attach to profiler engine error status property"));
+ User::LeaveIfError(iErrorStatus.Attach(KEngineStatusPropertyCat, EProfilerErrorStatus));
+ CActiveScheduler::Add(this);
+
+ // subscribe to P&S status property
+ iErrorStatus.Subscribe(iStatus);
+ SetActive();
+ }
+
+// --------------------------------------------------------------------------------------------
+void CProfilerErrorChecker::SetObserver(MProfilerErrorObserver* aObserver)
+ {
+ iObserver = aObserver;
+ }
+
+// --------------------------------------------------------------------------------------------
+TInt CProfilerErrorChecker::RunError(TInt aError)
+ {
+ iErrorStatus.Close();
+ return aError;
+ }
+// --------------------------------------------------------------------------------------------
+void CProfilerErrorChecker::RunL()
+ {
+ // resubscribe before processing new value to prevent missing updates
+ iErrorStatus.Subscribe(iStatus);
+ SetActive();
+
+ TInt stat(0);
+ if(iErrorStatus.Get(stat) != KErrNone)
+ {
+ // check if error status != KErrNone
+ if(stat != 0)
+ {
+ iObserver->HandleProfilerErrorChangeL(stat);
+ }
+
+ // reset error code
+ iErrorStatus.Set(KErrNone);
+ }
+ }
+
+// --------------------------------------------------------------------------------------------
+
+void CProfilerErrorChecker::DoCancel()
+ {
+ iErrorStatus.Cancel();
+ }
+
+// end of file
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/src/ProfilerEshell.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,440 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include <f32file.h>
+#include <e32cons.h>
+
+#include "ProfilerEshell.h"
+#include <piprofiler/ProfilerSession.h>
+
+
+
+_LIT(KProfilerEngineExe, "PIProfilerEngine.exe");
+
+/*
+ *
+ * Static methods for controlling the profiler
+ * through command line
+ *
+ */
+// --------------------------------------------------------------------------------------------
+static void PrintUsageInfo(const TDesC& aAdditionalInfo)
+ {
+ _LIT(KConsoleName, "Console");
+ _LIT(KLegalNote, "PIProfiler Version 2.2.0.2 Copyright @ 2009 Nokia\n");
+ _LIT(KUsageNote, "Usage: PIProfiler [start/end/timed] settingsfile [time to run]\n");
+ _LIT(KExample, "Example: PIProfiler timed C:\\data\\piprofilersettings.txt 60\n");
+
+ TRAP_IGNORE(CConsoleBase* console = Console::NewL(KConsoleName,TSize(KConsFullScreen,KConsFullScreen));
+ console->Printf(KLegalNote);
+ console->Printf(KUsageNote);
+ console->Printf(KExample);
+ console->Write(aAdditionalInfo);
+
+ console->Printf(_L("\n[Press any key]"));
+ console->Getch();
+ delete console;);
+ }
+
+// --------------------------------------------------------------------------------------------
+static TInt FindProcess()
+ {
+ TFindProcess procName;
+ procName.Find(_L("PIProfilerEngine.exe*"));
+ TFullName aResult;
+
+ // find the first appearance, i.e. "myself"...
+ TInt err(procName.Next(aResult)); // the first appearance
+ if(err == KErrNotFound)
+ {
+ // now check if old Profiler is still running on
+ procName.Find(_L("BappeaProf.exe*"));
+ err = procName.Next(aResult);
+ // check if old profiler process found
+ if(err == KErrNone)
+ {
+ // return error for error handling
+ return KErrAlreadyExists;
+ }
+ // return KErrNotFound and a new profiler engine process can be started
+ return KErrNotFound;
+ }
+ return err;
+ }
+
+/**
+ * Function for starting profiler engine in the background,
+ * call profiler to load settings
+ * and start sampling process
+ *
+ * @param configFile name and location of settings file
+ * @param aRunTimeInSeconds run time in seconds
+ * @param aBootTime run boot time sampling or not.
+ */
+// --------------------------------------------------------------------------------------------
+static TInt StartProfilerProcess(const TDesC& configFile, TInt aRunTimeInSeconds, TBool aBootTime)
+ {
+ TInt err(KErrNone);
+ RProcess proc;
+ TRequestStatus status = KRequestPending;
+ TBuf<256> conf;
+ conf.Zero();
+ conf.Append(configFile);
+ if(aBootTime)
+ {
+ RDebug::Printf("boot time measurement");
+ conf.Append(_L(" "));
+ conf.Append(_L("boot"));
+ }
+ RDebug::RawPrint(conf);
+ // check if process exists
+ err = FindProcess();
+ LOGSTRING2("PIProfiler: tried to find process, response %d", err);
+
+ // check if already exists and don't start a new eshell profiling
+ if( err == KErrNotFound )
+ {
+ // try create new process
+ err = proc.Create(KProfilerEngineExe, conf);
+
+ LOGSTRING2("PIProfiler: created process, response %d", err);
+
+ // check if RProcess::Create() succeeded
+ if( err == KErrNone )
+ {
+ // Trigger rendezvous on the supplied TRequestStatus object
+ proc.Rendezvous(status);
+
+ // kick off the engine process
+ proc.Resume();
+
+ // wait for the constructor to complete
+ User::WaitForRequest(status);
+
+ // just lose the handle
+ proc.Close();
+
+ // start sampling, using settings found in settings file or if not found the default settings
+ err = RProfiler::StartSampling();
+ // check if command succesful
+ if( err != KErrNone )
+ {
+ LOGSTRING2("PI Profiler start: err %d", err);
+ _LIT(KNoteProfilerCannotStart, "PI Profiler: cannot start PI Profiler, check settings!");
+ PrintUsageInfo(KNoteProfilerCannotStart);
+
+ // check if process still alive
+ if(err != KErrNotFound)
+ {
+ // exit the profiler process since process was started
+ RProfiler::ExitProfiler();
+ }
+ return err;
+ }
+
+ if(aRunTimeInSeconds > 0)
+ {
+ RDebug::Print(_L("Profiler running for %d s... "), aRunTimeInSeconds);
+ User::After(aRunTimeInSeconds*1000000);
+ RDebug::Print(_L("************* Profiler process closing *********"));
+
+ // stop sampling process
+ err = RProfiler::StopSampling();
+ // check if command succesfull
+ if( err != KErrNone )
+ {
+ LOGTEXT(_L("Profiler: could not connect engine, stop failed"));
+ return err;
+ }
+
+ // exit the profiler process
+ err = RProfiler::ExitProfiler();
+ // check if command succesfull
+ if( err != KErrNone )
+ {
+ LOGTEXT(_L("Profiler: could not connect engine, exit failed"));
+ return err;
+ }
+ }
+ }
+ else
+ {
+ _LIT(KNoteCannotFindProfiler, "PI Profiler: could not find PIProfilerEngine.exe");
+ PrintUsageInfo(KNoteCannotFindProfiler);
+ }
+ }
+ // check if old Profiler is already running
+ else if( err == KErrAlreadyExists )
+ {
+ _LIT(KNoteAlreadyRunning, "PI Profiler: old Profiler process already running, close it down before launching the new!");
+ PrintUsageInfo(KNoteAlreadyRunning);
+ }
+ // otherwise show error note
+ else
+ {
+ _LIT(KNoteAlreadyRunning, "PI Profiler: already running, not able to launch new one. NOTE: check if UI running!");
+ PrintUsageInfo(KNoteAlreadyRunning);
+ }
+ return KErrNone;
+ }
+
+// --------------------------------------------------------------------------------------------
+static TInt EndProfilerProcess()
+ {
+ LOGTEXT(_L("EndProfilerProcess() ..."));
+
+ // call profiler to stop sampling
+ TInt err = RProfiler::StopSampling();
+
+ // check if command succesfull
+ if( err != KErrNone )
+ {
+ LOGTEXT(_L("Profiler: could not connect engine, stop failed"));
+ return err;
+ }
+
+ // exit the profiler process
+ err = RProfiler::ExitProfiler();
+ // check if command succesfull
+ if( err != KErrNone )
+ {
+ LOGTEXT(_L("Profiler: could not connect engine, exit failed"));
+ return err;
+ }
+
+ return KErrNone;
+ }
+
+// --------------------------------------------------------------------------------------------
+static TInt TestSettingsFile(const TDesC& configFile)
+ {
+ RFs fs;
+ RFile file;
+ TInt err(KErrNone);
+
+ // check if file server can be connected
+ if (fs.Connect() != KErrNone)
+ {
+ // file server couldn't be connected, return false
+ return KErrNotFound;
+ }
+
+ // check if config file name length is > 0
+ if (configFile.Length() > 0)
+ {
+ // open the file with the given path and name
+ err = file.Open(fs,configFile,EFileRead);
+ // check if file open was succesfull
+ if(err != KErrNone)
+ {
+ // return false if failed
+ fs.Close();
+ return err;
+ }
+
+ }
+ else
+ {
+ // configFile length 0, return false
+ fs.Close();
+ return KErrNotFound;
+ }
+ // return true if tests passed
+ file.Close();
+ fs.Close();
+ return KErrNone;
+ }
+
+// --------------------------------------------------------------------------------------------
+static TInt ParseCommandAndExecute()
+ {
+ // commands literals for finding the right keyword
+ _LIT(KAutomatedTestStart,"start*");
+ _LIT(KAutomatedTestEnd,"end*");
+ _LIT(KAutomatedTestTimed,"timed*");
+ _LIT(KBootMeasurement,"boot*");
+ TBuf<256> c;
+ TInt match(KErrNotFound);
+ TInt bootmatch(KErrNotFound);
+ TBool myBoot=false;
+ // copy the full command line with arguments into a buffer
+ User::CommandLine(c);
+ LOGSTRING2("command: %S", &c);
+
+ // try to match with each of the literals defined above
+ // (commands in atf format)
+
+ // check if command is "start"
+ match = c.Match(KAutomatedTestStart);
+ if (match != KErrNotFound)
+ {
+ LOGTEXT(_L("Found keyword start"));
+
+ TBuf<256> fileName;
+ fileName.Append(c.Right(c.Length()-6));
+ LOGSTRING2("Filename is %S", &fileName);
+ if(TestSettingsFile(fileName) != KErrNone)
+ {
+ _LIT(KSettingsFileFailed, "False settings file");
+ PrintUsageInfo(KSettingsFileFailed);
+ return -2;
+ }
+ // execute Profile process
+ if( StartProfilerProcess(fileName, 0, myBoot) == KErrNone )
+ {
+ return -10;
+ }
+ return -2;
+ }
+
+ // check if command is "end"
+ match = c.Match(KAutomatedTestEnd);
+ if (match != KErrNotFound)
+ {
+ LOGTEXT(_L("Found keyword end"));
+
+ // stop the profiling process
+ EndProfilerProcess();
+ return -10;
+ }
+
+ // check if command is "timed"
+ match = c.Match(KAutomatedTestTimed);
+ // check if command is "boot"
+ bootmatch = c.Match(KBootMeasurement);
+ if ((match!= KErrNotFound) || (bootmatch != KErrNotFound))
+ {
+ // command "timed" or " boot" found, need for finding settings file and run time next
+ if(bootmatch != KErrNotFound)
+ {
+ LOGTEXT(_L("Found keyword boot"));
+ myBoot = TRUE;
+ }
+ if(match != KErrNotFound)
+ {
+ LOGTEXT(_L("Found keyword timed"));
+ }
+
+ TBuf<256> temp;
+ temp.Append(c);
+ TLex lex(temp);
+
+ TBuf<256> fileName;
+ TInt seconds;
+
+ // parse the first command line argument, the command itself
+ lex.Mark();
+ lex.SkipCharacters();
+ if(lex.TokenLength() != 0)
+ {
+ #ifdef PIPROFILER_PRINTS
+ TPtrC token = lex.MarkedToken();
+ LOGSTRING2("Token 1 %S",&token);
+ #endif
+ }
+ else
+ {
+ LOGTEXT(_L("Problem 1 in parsing command line"));
+ _LIT(KSettingsFileFailed, "Failure: False argument");
+ PrintUsageInfo(KSettingsFileFailed);
+ return -2;
+ }
+
+ // parse the second command line argument, the settings file name
+ lex.SkipSpace();
+ lex.Mark();
+ lex.SkipCharacters();
+ if(lex.TokenLength() != 0)
+ {
+ TPtrC token2 = lex.MarkedToken();
+ LOGSTRING2("Token 2 %S",&token2);
+ fileName.Append(token2);
+ LOGSTRING2("Value of fileName is %S",&fileName);
+// if(TestSettingsFile(fileName) != KErrNone)
+// {
+// _LIT(KSettingsFileFailed, "Failure: False settings file");
+// PrintUsageInfo(KSettingsFileFailed);
+// return -2;
+// }
+ }
+ else
+ {
+ LOGTEXT(_L("Problem 2 in parsing command line"));
+ _LIT(KSettingsFileFailed, "Failure: No settings file specified");
+ PrintUsageInfo(KSettingsFileFailed);
+ return -2;
+ }
+
+ // parse the third command line argument, the run time in seconds
+ lex.SkipSpace();
+ lex.Mark();
+ lex.SkipCharacters();
+ if(lex.TokenLength() != 0)
+ {
+ // third token ok, try to convert into TInt value
+ TPtrC token3 = lex.MarkedToken();
+ LOGSTRING2("Token 3 %S",&token3);
+ TLex num(token3);
+ TInt err = num.Val(seconds);
+ // check if given time value acceptable
+ if (err != KErrNone)
+ {
+ // value parsing failed, show info note to user
+ _LIT(KSecondsFailed, "Failure: False time value");
+ PrintUsageInfo(KSecondsFailed);
+ return -2;
+ }
+ }
+ else
+ {
+ LOGTEXT(_L("Problem 3 in parsing command line"));
+ _LIT(KSecondsFailed, "Failure: False time value");
+ PrintUsageInfo(KSecondsFailed);
+ return -2;
+ }
+
+ LOGSTRING3("Filename is %S, seconds is %d", &fileName, seconds);
+ // execute Profile process
+ if( StartProfilerProcess(fileName, seconds, myBoot) == KErrNone )
+ {
+ return -10;
+ }
+ return -2;
+ }
+
+ // check if space character in the middle of command line string
+ if( c.LocateReverse(' ') != KErrNotFound)
+ {
+ _LIT(KWrongParameters, "Failure: Check command line parameters");
+ PrintUsageInfo(KWrongParameters);
+ return -2;
+ }
+
+ // return -1 if no command found
+ LOGTEXT(_L("No keyword found"));
+ return -1;
+ }
+
+// --------------------------------------------------------------------------------------------
+GLDEF_C TInt E32Main()
+ {
+ // parse command line arguments
+ ParseCommandAndExecute();
+
+ return KErrNone;
+
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/src/ProfilerTimer.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,76 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include "ProfilerTimer.h"
+
+/*
+ *
+ * CProfilerTimer class implementation
+ *
+ */
+// --------------------------------------------------------------------------------------------
+CProfilerTimer::CProfilerTimer(const TInt aPriority, MProfilerTimerObserver& aObserver)
+:
+CActive(aPriority),
+iObserver(aObserver)
+ {
+ }
+
+// --------------------------------------------------------------------------------------------
+CProfilerTimer::~CProfilerTimer()
+ {
+ Cancel();
+ iTimer.Close();
+ }
+
+// --------------------------------------------------------------------------------------------
+CProfilerTimer* CProfilerTimer::NewL(const TInt aPriority, MProfilerTimerObserver& aObserver)
+ {
+ CProfilerTimer* self = new (ELeave) CProfilerTimer(aPriority, aObserver);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+ }
+
+// --------------------------------------------------------------------------------------------
+void CProfilerTimer::ConstructL(void)
+ {
+ CActiveScheduler::Add(this);
+ iTimer.CreateLocal();
+ }
+
+// --------------------------------------------------------------------------------------------
+void CProfilerTimer::After(TUint aPeriodInSeconds)
+ {
+ Cancel();
+ TTimeIntervalMicroSeconds32 period = aPeriodInSeconds * 1000000;
+ iTimer.After(iStatus, period);
+ SetActive();
+ }
+
+// --------------------------------------------------------------------------------------------
+void CProfilerTimer::DoCancel()
+ {
+ iTimer.Cancel();
+ }
+
+// --------------------------------------------------------------------------------------------
+void CProfilerTimer::RunL()
+ {
+ iObserver.HandleTimerExpiresL(iStatus.Int());
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/src/SamplerController.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,500 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include "SamplerController.h"
+//#include <piprofiler/EngineUIDs.h>
+
+// CONSTANTS
+const TInt KMaxSamplerPluginCount = 20;
+const TInt KMaxExtraSettingsItemCount = 6;
+
+// LITERALS
+_LIT8(KSamplingPeriod, "sampling_period_ms");
+_LIT8(KNewLine8, "\n");
+_LIT8(KEquals8, "=");
+_LIT8(KSettingsText, " settings");
+_LIT(KNewLine, "\n");
+_LIT(KEquals, "=");
+_LIT(KCommentSeparator, " ; ");
+
+CSamplerController* CSamplerController::NewL(CProfilerSampleStream& aStream)
+ {
+ CSamplerController* self = new( ELeave ) CSamplerController(aStream);
+ CleanupStack::PushL( self );
+ self->ConstructL( );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+void CSamplerController::ConstructL()
+ {
+ // initiate sampler plugin list
+ InitialiseSamplerListL();
+ }
+
+
+CSamplerController::CSamplerController(CProfilerSampleStream& aStream) :
+ iStream(aStream)
+ {
+ }
+
+void CSamplerController::InitialiseSamplerListL()
+ {
+ // create new sampler plugin array
+ iPluginArray = new (ELeave) CArrayPtrFlat<CSamplerPluginInterface>( KMaxSamplerPluginCount );
+
+ // create plugin loader instance
+ iPluginLoader = CSamplerPluginLoader::NewL();
+
+ // register sampler controller to get notifications of succesfull plugin load
+ iPluginLoader->SetObserver( this );
+
+ // load sampler plugins asynchronously
+ iPluginLoader->LoadAsyncL( iPluginArray );
+
+ LOGTEXT(_L(" RSamplerController::InitialiseUserSideSamplerList - exit"));
+ }
+
+CSamplerController::~CSamplerController()
+ {
+ LOGTEXT(_L("CSamplerController::~CSamplerController - entry" ));
+
+ if ( iPluginArray )
+ {
+ // destroy the plugin instances
+ // empty loaded plugins from array
+ for(TInt i(0);i<iPluginArray->Count();i++)
+ {
+ if(iPluginArray->At(i))
+ {
+ delete iPluginArray->At(i);
+ iPluginArray->At(i) = NULL;
+ }
+ }
+ iPluginArray->Reset();
+ delete iPluginArray;
+ iPluginArray = NULL;
+ }
+
+ if ( iPluginLoader )
+ {
+ iPluginLoader->AbortAsyncLoad();
+ delete iPluginLoader;
+ iPluginLoader = NULL;
+ }
+
+ LOGTEXT(_L("CSamplerController::~CSamplerController - exit" ));
+ }
+
+void CSamplerController::SetObserver(MSamplerControllerObserver* aObserver)
+ {
+ iObserver = aObserver;
+ }
+
+TInt CSamplerController::UpdateSavedSamplerAttributesL(CDesC8ArrayFlat* aSavedLineArray, CArrayFixFlat<TSamplerAttributes>* aAttributes)
+ {
+ TInt err(KErrNone);
+ TInt count(iPluginArray->Count());
+ // all plugins get their own settings among whole lump of setting strings
+ CSamplerPluginInterface* plugin = NULL;
+
+ // loop through the plugin array
+ for(TInt i(0);i<count;i++)
+ {
+ // get each plugin at a time
+ plugin = iPluginArray->At(i);
+
+ // call each plugin to sort out its own settings
+ err = plugin->ConvertRawSettingsToAttributes(aSavedLineArray);
+
+ // get plugin specific attributes, array may contain attributes of several sub samplers
+ plugin->GetAttributesL(aAttributes);
+ }
+
+ return err;
+ }
+
+TInt CSamplerController::SetSamplerSettingsL(TInt aUid, TSamplerAttributes aAttributes)
+ {
+ // parse right plugin based on UID
+ CSamplerPluginInterface* plugin = GetPlugin(TUid::Uid(aUid));
+
+ // set the sampler attributes of a sampler plugin
+ plugin->SetAttributesL(aAttributes);
+
+ return KErrNone;
+ }
+
+void CSamplerController::GetSamplerAttributesL(CArrayFixFlat<TSamplerAttributes>* aAttributes)
+ {
+ CSamplerPluginInterface* plugin = NULL;
+
+ TInt count(iPluginArray->Count());
+
+ // get first all the attributes from all the sampler plugins listed in iPluginArray
+ for(TInt i(0);i<count;i++)
+ {
+ // get the plugin first
+ plugin = iPluginArray->At(i);
+
+ // get plugin specific attributes, array may contain attributes of several sub samplers
+ plugin->GetAttributesL(aAttributes);
+ }
+ }
+
+void CSamplerController::ComposeAttributesToSettingsFileFormat(RFile& aFile, CArrayFixFlat<TSamplerAttributes>* aAttributes)
+ {
+ // write immediately to settings file
+ ComposeSettingsText(aFile, aAttributes);
+ }
+
+void CSamplerController::ComposeSettingsText(RFile& aFile, CArrayFixFlat<TSamplerAttributes>* aAttrArray)
+ {
+ // temporary buffer for a setting line
+ TBuf<384> settingLine;
+ TBuf8<384> settingLine8;
+ TInt itemCount(0);
+ TBuf<266> tBuf;
+
+ TSamplerAttributes attr;
+
+ for(TInt i(0);i<aAttrArray->Count();i++)
+ {
+ // get the attribute container
+ attr = aAttrArray->At(i);
+
+ // add the name and description of the sampler in brackets first
+ settingLine8.Copy(KBracketOpen);
+ settingLine8.Append(attr.iShortName);
+ settingLine8.Append(KBracketClose);
+ settingLine8.Append(KCommentSeparator());
+ settingLine8.Append(attr.iName);
+ settingLine8.Append(KSettingsText);
+ settingLine8.Append(KNewLine8);
+ aFile.Write(settingLine8);
+
+ // enabled
+ settingLine8.Copy(KEnabled);
+ settingLine8.Append(KEquals8);
+ settingLine8.Append(Bool2Str(attr.iEnabled));
+ settingLine8.Append(KNewLine8);
+ aFile.Write(settingLine8);
+
+ // sampling rate (if set)
+ if( attr.iSampleRate != -1 )
+ {
+ settingLine8.Copy(KSamplingPeriod);
+ settingLine8.Append(KEquals8);
+ settingLine8.Append(Int2Str(attr.iSampleRate));
+ settingLine8.Append(KNewLine8);
+ aFile.Write(settingLine8);
+ }
+
+ itemCount = attr.iItemCount;
+
+ // check if item count set is sane, max extra settings item count 6
+ if(itemCount > KMaxExtraSettingsItemCount)
+ {
+ // probably forgot to set the item count value in plugin => safe to set it 0
+ itemCount = 0;
+ }
+
+ // setting items
+ for (TInt j(0);j<itemCount;j++)
+ {
+ switch(j)
+ {
+ case 0: // settingItem1
+ {
+ settingLine.Copy(attr.iSettingItem1.iSettingText);
+ settingLine.Append(KEquals());
+ settingLine.Append(attr.iSettingItem1.iValue);
+ settingLine.Append(KCommentSeparator());
+ settingLine.Append(attr.iSettingItem1.iUIText);
+ settingLine.Append(KNewLine());
+ CnvUtfConverter::ConvertFromUnicodeToUtf8(settingLine8, settingLine);
+ aFile.Write(settingLine8);
+ break;
+ }
+ case 1: // settingItem2
+ {
+ settingLine.Copy(attr.iSettingItem2.iSettingText);
+ settingLine.Append(KEquals());
+ settingLine.Append(attr.iSettingItem2.iValue);
+ settingLine.Append(KCommentSeparator());
+ settingLine.Append(attr.iSettingItem2.iUIText);
+ settingLine.Append(KNewLine());
+ CnvUtfConverter::ConvertFromUnicodeToUtf8(settingLine8, settingLine);
+ aFile.Write(settingLine8);
+ break;
+ }
+ case 2: // settingItem3
+ {
+ settingLine.Copy(attr.iSettingItem3.iSettingText);
+ settingLine.Append(KEquals());
+ settingLine.Append(attr.iSettingItem3.iValue);
+ settingLine.Append(KCommentSeparator());
+ settingLine.Append(attr.iSettingItem3.iUIText);
+ settingLine.Append(KNewLine());
+ CnvUtfConverter::ConvertFromUnicodeToUtf8(settingLine8, settingLine);
+ aFile.Write(settingLine8);
+ break;
+ }
+ case 3: // settingItem4
+ {
+ settingLine.Copy(attr.iSettingItem4.iSettingText);
+ settingLine.Append(KEquals());
+ settingLine.Append(attr.iSettingItem4.iValue);
+ settingLine.Append(KCommentSeparator());
+ settingLine.Append(attr.iSettingItem4.iUIText);
+ settingLine.Append(KNewLine());
+ CnvUtfConverter::ConvertFromUnicodeToUtf8(settingLine8, settingLine);
+ aFile.Write(settingLine8);
+ break;
+ }
+ case 4: // settingItem5
+ {
+ settingLine.Copy(attr.iSettingItem5.iSettingText);
+ settingLine.Append(KEquals());
+ settingLine.Append(attr.iSettingItem5.iValue);
+ settingLine.Append(KCommentSeparator());
+ settingLine.Append(attr.iSettingItem5.iUIText);
+ settingLine.Append(KNewLine());
+ CnvUtfConverter::ConvertFromUnicodeToUtf8(settingLine8, settingLine);
+ aFile.Write(settingLine8);
+ break;
+ }
+ case 5: // settingItem6
+ {
+ settingLine.Copy(attr.iSettingItem6.iSettingText);
+ settingLine.Append(KEquals());
+ settingLine.Append(attr.iSettingItem6.iValue);
+ settingLine.Append(KCommentSeparator());
+ settingLine.Append(attr.iSettingItem6.iUIText);
+ settingLine.Append(KNewLine());
+ CnvUtfConverter::ConvertFromUnicodeToUtf8(settingLine8, settingLine);
+ aFile.Write(settingLine8);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// Converts given descriptor into TBool value.
+// ----------------------------------------------------------------------------
+//
+inline void CSamplerController::Str2Bool(const TDesC8& aBuf, TBool& aValue)
+ {
+ if (aBuf.CompareF(KFalse) == 0)
+ aValue = EFalse;
+ else
+ aValue = ETrue;
+ }
+
+// ----------------------------------------------------------------------------
+// Converts given descriptor into TInt value.
+// ----------------------------------------------------------------------------
+//
+inline void CSamplerController::Str2Int(const TDesC8& aBuf, TInt& aValue)
+ {
+ TLex8 conv;
+ conv.Assign(aBuf);
+
+ if (conv.Val(aValue) != KErrNone)
+ aValue = 0;
+ }
+
+// ----------------------------------------------------------------------------
+// Converts given descriptor into TInt value.
+// ----------------------------------------------------------------------------
+//
+inline void CSamplerController::Str2Int(const TDesC8& aBuf, TUint32& aValue)
+ {
+ TInt temp(0);
+
+ TLex8 conv;
+ conv.Assign(aBuf);
+
+ if (conv.Val(temp) != KErrNone)
+ aValue = 0;
+ else
+ aValue = (TUint32)temp;
+ }
+
+// ----------------------------------------------------------------------------
+// Converts given boolean into a descriptor.
+// ----------------------------------------------------------------------------
+//
+inline TBuf8<16> CSamplerController::Bool2Str(const TBool& aValue)
+ {
+ TBuf8<16> buf;
+
+ if (aValue)
+ buf.Copy(KTrue);
+ else
+ buf.Copy(KFalse);
+
+ return buf;
+ }
+
+// ----------------------------------------------------------------------------
+// Converts given integer into a descriptor.
+// ----------------------------------------------------------------------------
+//
+inline TBuf8<16> CSamplerController::Int2Str(const TInt& aValue)
+ {
+ TBuf8<16> buf;
+ buf.AppendNum(aValue);
+
+ return buf;
+ }
+
+
+void CSamplerController::HandlePluginLoaded( KSamplerPluginLoaderStatus aStatus )
+ {
+
+ // process status value
+ switch(aStatus)
+ {
+ case 0:
+ LOGSTRING2("RSamplerController - one plugin loaded, status: %d", aStatus);
+ break;
+ case 1:
+ LOGSTRING2("RSamplerController - a plugin load failed: %d", aStatus);
+ break;
+ case 2:
+ LOGSTRING2("RSamplerController - plugin loading aborted: %d", aStatus);
+ break;
+ case 3:
+ LOGSTRING2("RSamplerController - all plugins loaded: %d", aStatus);
+ TRAPD(err, iPluginLoader->SortPluginsL(iPluginArray));
+ if(err != KErrNone)
+ {
+ LOGTEXT(_L("Sampler controller unable to sort plugins"));
+ }
+
+ // call engine to finalize the startup
+ TRAPD(result, iObserver->HandleSamplerControllerReadyL(););
+ if(result != KErrNone)
+ {
+ LOGTEXT(_L("Failed to notify engine"));
+ }
+ break;
+ case 4:
+ LOGSTRING2("RSamplerController - error in loading plugins: %d", aStatus);
+ break;
+ default:
+ break;
+ }
+ }
+
+
+CSamplerPluginInterface* CSamplerController::GetPlugin(TUid aUid)
+ {
+ LOGTEXT(_L("RSamplerController::GetPlugin - entry"));
+ // check that plugin array contains samplers
+ if( iPluginArray && iPluginArray->Count() > 0 )
+ {
+ for(TInt i=0;i<iPluginArray->Count();i++)
+ {
+ CSamplerPluginInterface* plugin = iPluginArray->At(i);
+ TUid uid = plugin->Id(-1); // get parent uid first
+ if(uid == aUid)
+ {
+ LOGTEXT(_L("CSamplerController::GetPlugin() - main plug-in found!"));
+ return plugin;
+ }
+
+ if(plugin->SubId(aUid) != KErrNotFound)
+ {
+ LOGTEXT(_L("CSamplerController::GetPlugin() - subsampler found!"));
+ return plugin;
+ }
+ }
+ }
+ LOGTEXT(_L("CSamplerController::GetPlugin() - No plug-in found for UID"));
+
+ return (CSamplerPluginInterface*)0;
+ }
+
+// start user mode samplers
+void CSamplerController::StartSamplerPluginsL()
+ {
+ CSamplerPluginInterface* plugin = NULL;
+
+ if( iPluginArray )
+ {
+ TInt count(iPluginArray->Count());
+
+ for(TInt i(0);i<count;i++)
+ {
+ plugin = iPluginArray->At(i);
+ // check if some error received when starting profiling
+ TRAPD(err, plugin->ResetAndActivateL(iStream));
+ LOGSTRING2(" RSamplerController::StartSamplerPlugin - plugin activated (0x%X)", plugin->Id(-1));
+ if( err != KErrNone)
+ {
+ LOGSTRING2(" RSamplerController::StartSamplerPlugin - error %d", i);
+ // handle received error, need to update UI!
+ iObserver->HandleError(err);
+ }
+ }
+ }
+ }
+
+// stop user mode samplers
+TInt CSamplerController::StopSamplerPlugins()
+ {
+ TInt count(0);
+
+ if( iPluginArray && iPluginArray->Count() > 0 )
+ {
+ TInt i(0);
+ CSamplerPluginInterface* plugin = NULL;
+ // stop kernel mode samplers
+ for(;i<iPluginArray->Count();i++)
+ {
+ plugin = iPluginArray->At(i);
+ TUint32 id = plugin->Id(-1).iUid;
+ LOGSTRING2(" CSamplerController::StopSamplerPlugins - traceId = %d",
+ id);
+ // stop only started samplers
+ if(plugin->Enabled())
+ {
+ // stop selected plugin
+ plugin->StopSampling();
+ // check if user mode sampler, special flush needed to direct data to stream
+ if(plugin->GetSamplerType() == PROFILER_USER_MODE_SAMPLER)
+ {
+ LOGTEXT(_L(" CSamplerController::StopSamplerPlugins - flushing user mode sampler stream"));
+ plugin->Flush();
+ }
+ }
+ count++;
+ }
+ }
+ return count;
+ }
+
+// end of file
+
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/src/SamplerPluginLoader.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,539 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+// INCLUDE FILES
+#include "SamplerPluginLoader.h"
+//#include <piprofiler/EngineUIDs.h>
+#include <utf.h> // CnvUtfConverter
+#include <basched.h>
+
+// CONSTANTS
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::NewL
+//
+// EPOC two-phased constructor
+// ----------------------------------------------------------------------------
+//
+CSamplerPluginLoader* CSamplerPluginLoader::NewL()
+ {
+ CSamplerPluginLoader* self = new( ELeave ) CSamplerPluginLoader;
+ CleanupStack::PushL( self );
+ self->ConstructL( );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::CSamplerPluginLoader
+//
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// ----------------------------------------------------------------------------
+//
+CSamplerPluginLoader::CSamplerPluginLoader() : CActive( EPriorityStandard )
+ {
+ LOGSTRING( "CSamplerPluginLoader()::CSamplerPluginLoader()" );
+ }
+
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::ConstructL
+//
+// EPOC default constructor can leave.
+// ----------------------------------------------------------------------------
+//
+void CSamplerPluginLoader::ConstructL( )
+ {
+ LOGSTRING( "CSamplerPluginLoader()::ConstructL()" );
+
+ // get list of implementations
+ CSamplerPluginInterface::ListAllImplementationsL( iImplInfoArray );
+
+ CActiveScheduler::Add( this );
+ }
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::~CSamplerPluginLoader
+//
+// Destructor
+// ----------------------------------------------------------------------------
+//
+CSamplerPluginLoader::~CSamplerPluginLoader()
+ {
+ LOGSTRING( "CSamplerPluginLoader()::~CSamplerPluginLoader()" );
+
+ AbortAsyncLoad();
+
+ Cancel();
+
+ // reset ECOM implementation info array
+ iImplInfoArray.ResetAndDestroy(); // This is needed
+ iImplInfoArray.Close();
+ }
+
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::LoadAsync
+// ----------------------------------------------------------------------------
+//
+void CSamplerPluginLoader::LoadAsyncL(CArrayPtrFlat<CSamplerPluginInterface>* aPluginArray )
+ {
+ iPluginArray = aPluginArray;
+
+ // Reset iterator
+ iImplInfoArrayIterator = 0;
+
+ LOGSTRING2( "CSamplerPluginLoader()::Implementation info count: %d",
+ iImplInfoArray.Count() );
+
+ NotifyProgress();
+
+ //Begin CActive asynchronous loop.
+ CompleteOwnRequest();
+ }
+
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::LoadSyncL
+// ----------------------------------------------------------------------------
+//
+void CSamplerPluginLoader::LoadSyncL(CArrayPtrFlat<CSamplerPluginInterface>* aPluginArray)
+ {
+ // cancel first active object from loading samplers dynamically
+ Cancel();
+ CSamplerPluginInterface* plugin = NULL;
+
+ iPluginArray = aPluginArray;
+
+ // Get a list of all implementations, even though we only want one specific
+ // one. There appears to be no way to otherwise extract a specific implementation
+ // info object :(
+ // Search for the implementation that matches aImplementationUid
+ const TInt impCount = iImplInfoArray.Count();
+ for( TInt i=0; i<impCount; i++ )
+ {
+ const CImplementationInformation* info = iImplInfoArray[ i ];
+ {
+ TRAPD(ret, plugin = &CreatePluginInstanceL( *info ); );
+ if( ret == KErrNone )
+ {
+ // Plugin ownership is transfered to iPluginArray
+ InsertPluginInOrderL( plugin, iPluginArray );
+ }
+ else
+ {
+ // Error note is displayed even if plugin is not loaded
+ LOGSTRING2("CSamplerPluginLoader::LoadSyncL() - plugin load failed, error %d", ret);
+ }
+ break;
+ }
+ }
+
+ if ( plugin == NULL )
+ {
+ User::Leave( KErrNotFound );
+ }
+ }
+
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::AbortAsyncLoad
+// ----------------------------------------------------------------------------
+//
+void CSamplerPluginLoader::AbortAsyncLoad()
+ {
+ LOGSTRING( "CSamplerPluginLoader()::AbortAsyncLoad()" );
+ Cancel();
+ }
+
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::RunL
+// ----------------------------------------------------------------------------
+//
+void CSamplerPluginLoader::RunL()
+ {
+ iRunLDebugCount++;
+ LoadNextPluginL();
+
+ // Check if there are still more plugins to be loaded:
+ if ( iImplInfoArrayIterator < iImplInfoArray.Count() )
+ {
+ NotifyProgress();
+ // Continue CActive asynchronous loop.
+ CompleteOwnRequest();
+ }
+ else
+ {
+ // All plugins loaded:
+ LOGSTRING( "CSamplerPluginLoader()::Loading plugins finished." );
+ NotifyFinished();
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CScGenreItemConstructionConductor::CompleteOwnRequest
+//
+// Issue request complete notification.
+// ---------------------------------------------------------------------------
+void CSamplerPluginLoader::CompleteOwnRequest()
+ {
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete( status, KErrNone );
+ SetActive();
+ }
+
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::RunError
+// ----------------------------------------------------------------------------
+//
+TInt CSamplerPluginLoader::RunError( TInt aError )
+ {
+ // This method is called when a plugin loading fails.
+ // Always "fake" the return value so that ActiveSchedule
+ // keeps running and later plugins are continued to be loaded.
+ // Check if still plugins to be loaded:
+ LOGTEXT(_L("CSamplerPluginLoader::RunError() - error in loading plugin"));
+ if( iImplInfoArrayIterator < iImplInfoArray.Count() )
+ {
+ NotifyProgress();
+
+ //Continue CActive asynchronous loop.
+ CompleteOwnRequest();
+ }
+ else // All plugins loaded:
+ {
+ NotifyFinished();
+ }
+
+ if ( aError == KLeaveExit )
+ {
+ return KLeaveExit;
+ }
+
+ return KErrNone;
+ }
+
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::DoCancel
+// ----------------------------------------------------------------------------
+//
+void CSamplerPluginLoader::DoCancel()
+ {
+
+ }
+
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::NotifyProgress
+// ----------------------------------------------------------------------------
+//
+void CSamplerPluginLoader::NotifyProgress()
+ {
+ if( iObserver )
+ {
+ iObserver->HandlePluginLoaded( MSamplerPluginLoadObserver::ESamplerSuccess);
+ }
+ }
+
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::NotifyFinished
+// ----------------------------------------------------------------------------
+//
+void CSamplerPluginLoader::NotifyFinished()
+ {
+ if( iObserver )
+ {
+ iObserver->HandlePluginLoaded( MSamplerPluginLoadObserver::ESamplerFinished );
+ }
+ }
+
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::SetObserver
+// ----------------------------------------------------------------------------
+//
+void CSamplerPluginLoader::SetObserver(MSamplerPluginLoadObserver* aObserver)
+ {
+ LOGSTRING2("CSamplerPluginLoader()::Observer set:0x%X", aObserver);
+ iObserver = aObserver;
+ }
+
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::ParseToUid
+// Parses a UID from descriptor of form '0xNNNNNNNN' where N is hexadecimal.
+//
+// ----------------------------------------------------------------------------
+//
+TInt CSamplerPluginLoader::ParseToUid( const TDesC8& aSource, TUid& aTarget )
+ {
+ // Remove "0x" from the descriptor if it exists
+ _LIT8(KHexPrefix, "0x");
+
+ TPtrC8 pSource( aSource );
+ const TInt prefixPosition = pSource.Find( KHexPrefix );
+ if ( prefixPosition != KErrNotFound )
+ {
+ pSource.Set( aSource.Mid( prefixPosition + KHexPrefix().Length() ) );
+ }
+
+ // Parse to integer
+ TLex8 lex( pSource );
+ TUint integer = 0;
+
+ // Parse using TRadix::EHex as radix:
+ const TInt err = lex.Val( integer, EHex );
+ aTarget.iUid = integer;
+
+ if( err != KErrNone )
+ {
+ // If parsing parent UID failed, do not load plugin:
+ LOGSTRING2(
+ "CSamplerPluginLoader()::Parsing parent UID failed. Error code:%d",
+ err );
+ }
+ return err;
+ }
+
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::ParseOrderNumber
+//
+//
+// ----------------------------------------------------------------------------
+//
+TInt CSamplerPluginLoader::ParseOrderNumber( const TDesC8& aSource, TInt& aOrderNumber )
+ {
+ // Parse plugin's order number from opaque_data:
+ TLex8 lex( aSource );
+ const TInt orderErr = lex.Val( aOrderNumber );
+ return orderErr;
+ }
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::LoadNextPluginL
+// Iterate through iImplInfoArray. Load the plugin if it is eligible for
+// loading. Loaded plugin is added to iPluginArray. Each time a plugin is
+// loaded, iObserver is notified.
+//
+// ----------------------------------------------------------------------------
+//
+void CSamplerPluginLoader::LoadNextPluginL()
+ {
+ // Iterate through iImplInfoArray. This loop continues between function
+ // calls. Therefore member variable iImplInfoArrayIterator is used as a
+ // counter. Loop will break when match is found and continues on next RunL.
+ for( ; iImplInfoArrayIterator < iImplInfoArray.Count(); )
+ {
+ const CImplementationInformation* info =
+ iImplInfoArray[ iImplInfoArrayIterator ];
+
+ iImplInfoArrayIterator++;
+
+// PrintInfoDebug( *info, iImplInfoArrayIterator, iImplInfoArray.Count() );
+ LOGSTRING3("CSamplerPluginLoader() - iImplInfoArrayIterator %d, iImplInfoArray.Count() %d",
+ iImplInfoArrayIterator,
+ iImplInfoArray.Count() );
+
+ // If this plugin is OK -> load it:
+ LOGSTRING2( "CSamplerPluginLoader() %S eligible for parent",
+ &info->DisplayName());
+ CSamplerPluginInterface* plugin = NULL;
+ TInt error(KErrNone);
+ // Create plugin. Trap leave for debugging purposes.
+ TRAP( error, plugin = &CreatePluginInstanceL( *info ); );
+
+ if( error == KErrNone )
+ {
+ // Plugin ownership is transfered to iPluginArray
+ InsertPluginInOrderL( plugin, iPluginArray );
+ }
+ else
+ {
+ // Error note is displayed even if plugin is not loaded
+ LOGSTRING2("CSamplerPluginLoader::LoadNextPluginL() - plugin load failed, error %d", error);
+ }
+ // Wait for next round
+ break;
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::CreatePluginInstanceL
+//
+//
+// ----------------------------------------------------------------------------
+//
+
+CSamplerPluginInterface& CSamplerPluginLoader::CreatePluginInstanceL(
+ const CImplementationInformation& aImpInfo )
+ {
+ // Now we can load the plugin
+ const TUid implUid = aImpInfo.ImplementationUid();
+
+ CSamplerPluginInterface* plugin = CSamplerPluginInterface::NewL( implUid , (TAny*)&aImpInfo.DisplayName() );
+ CleanupStack::PushL ( plugin );
+
+ // Parse plugin's order number from opaque_data:
+ TInt orderNumber(0);
+ const TInt orderErr = ParseOrderNumber( aImpInfo.OpaqueData(), orderNumber );
+
+ if ( orderErr == KErrNone && orderNumber >= 0 )
+ {
+ plugin->iOrder = orderNumber;
+ }
+ CleanupStack::Pop( plugin ); // CSamplerController is now responsible for this memory.
+
+ return *plugin;
+ }
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::SortPluginsL
+//
+// ----------------------------------------------------------------------------
+//
+void CSamplerPluginLoader::SortPluginsL(
+ CArrayPtrFlat<CSamplerPluginInterface>* aPlugins )
+ {
+ RPointerArray<CSamplerPluginInterface> plugins;
+ TLinearOrder<CSamplerPluginInterface> order( CSamplerPluginLoader::Compare );
+
+ // Insertion will also order
+ for( TInt i = 0; i < aPlugins->Count(); i++ )
+ {
+ plugins.InsertInOrderL( (*aPlugins)[i], order );
+ }
+
+ // Replace original array content with sorted items
+ aPlugins->Reset();
+ for( TInt i = 0; i < plugins.Count(); i++ )
+ {
+ aPlugins->AppendL( plugins[i] );
+ }
+ }
+
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::Compare
+//
+// Compare two plugins.
+// Precedence:
+// [1. plugin provider category]
+// 2. plugin order number
+// 3. plugin caption
+// Plugin provider gategory is currently disabled (not supported yet).
+// ----------------------------------------------------------------------------
+//
+TInt CSamplerPluginLoader::Compare( const CSamplerPluginInterface& aFirst,
+ const CSamplerPluginInterface& aSecond )
+ {
+ // compare indexes and sort
+ return CompareIndex( aFirst, aSecond );
+ }
+
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::InsertPluginInOrderL
+//
+// ----------------------------------------------------------------------------
+//
+void CSamplerPluginLoader::InsertPluginInOrderL(
+ CSamplerPluginInterface* aPlugin,
+ CArrayPtrFlat<CSamplerPluginInterface>* aPlugins )
+ {
+ CSamplerPluginInterface* comparedPlugin;
+ TInt comparison = 0;
+ TBool inserted = EFalse;
+
+ for( TInt i = 0; i < aPlugins->Count(); i++ )
+ {
+ comparedPlugin = (*aPlugins)[i];
+ // Optimization: do not call time consuming Compare() multiple times!
+ comparison = Compare( *aPlugin, *comparedPlugin );
+ if( comparison < 0 )
+ {
+ aPlugins->InsertL( i, aPlugin );
+ inserted = ETrue;
+ break;
+ }
+ else if( comparison == 0 )
+ {
+ aPlugins->InsertL( i+1, aPlugin );
+ inserted = ETrue;
+ break;
+ }
+ }
+ // Plugin was not before any other plugin - make sure it's appended
+ if( !inserted )
+ {
+ aPlugins->AppendL( aPlugin );
+ }
+
+ #ifdef _GS_PLUGINLOADER_SORTING_TRACES
+ PrintOrderTraces( aPlugins );
+ #endif // _GS_PLUGINLOADER_SORTING_TRACES
+
+ }
+
+// ----------------------------------------------------------------------------
+// CSamplerPluginLoader::CompareIndex
+// ----------------------------------------------------------------------------
+//
+TInt CSamplerPluginLoader::CompareIndex( const CSamplerPluginInterface& aFirst,
+ const CSamplerPluginInterface& aSecond )
+ {
+ TInt comparison = KSamplerComparisonEqual;
+ // The plugin having index is before the one not having one
+
+ if( aFirst.iOrder == KSamplerPluginNotIndexed &&
+ aSecond.iOrder == KSamplerPluginNotIndexed )
+ {
+ // Neither have index -> equal
+ comparison = KSamplerComparisonEqual;
+ }
+ else if( aFirst.iOrder == KSamplerPluginNotIndexed )
+ {
+ // The plugin having index is before the one not having one
+ comparison = KSamplerComparisonAfter;
+ }
+ else if( aSecond.iOrder == KSamplerPluginNotIndexed )
+ {
+ // The plugin having index is before the one not having one
+ comparison = KSamplerComparisonBefore;
+ }
+ else if( aFirst.iOrder < aSecond.iOrder )
+ {
+ // Compare actual index values
+ comparison = KSamplerComparisonBefore;
+ }
+ else if( aFirst.iOrder > aSecond.iOrder )
+ {
+ // Compare actual index values
+ comparison = KSamplerComparisonAfter;
+ }
+ return comparison;
+ }
+
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/src/WriterController.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,283 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <piprofiler/EngineUIDs.h>
+#include <piprofiler/ProfilerTraces.h>
+
+#include "WriterController.h"
+
+const TInt KMaxWriterPluginCount = 10;
+
+
+CWriterController* CWriterController::NewL(CProfilerSampleStream& aStream)
+ {
+ CWriterController* self = new( ELeave ) CWriterController(aStream);
+ CleanupStack::PushL( self );
+ self->ConstructL( );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+CWriterController::CWriterController(CProfilerSampleStream& aStream) :
+ iStream(aStream)
+ {
+ }
+
+void CWriterController::ConstructL()
+ {
+ // initiate writer plugin list
+
+ }
+
+
+void CWriterController::InitialiseWriterListL()
+ {
+ // create new writer plugin array
+ iPluginArray = new(ELeave) CArrayPtrFlat<CWriterPluginInterface>( KMaxWriterPluginCount );
+
+ // create new writer plugin loader
+ iPluginLoader = CWriterPluginLoader::NewL();
+ iPluginLoader->SetObserver( this );
+ iPluginLoader->LoadAsyncL( iPluginArray );
+
+ LOGTEXT(_L(" RWriterController::InitialiseWriterList - exit"));
+ }
+
+CWriterController::~CWriterController()
+ {
+ LOGTEXT(_L("RWriterController::~RWriterController" ));
+ if ( iPluginArray )
+ {
+ // destroy the plugin instances
+ // empty loaded plugins from array
+ for(TInt i(0);i<iPluginArray->Count();i++)
+ {
+ if(iPluginArray->At(i))
+ {
+ delete iPluginArray->At(i);
+ iPluginArray->At(i) = NULL;
+ }
+ }
+ iPluginArray->Reset();
+ delete iPluginArray;
+ iPluginArray = NULL;
+ }
+
+ if ( iPluginLoader )
+ {
+ iPluginLoader->AbortAsyncLoad();
+ delete iPluginLoader;
+ iPluginLoader = NULL;
+ }
+
+ }
+
+
+void CWriterController::InitialisePluginStream()
+ {
+ LOGTEXT(_L("RWriterController::InitialisePluginStream - entry"));
+ if( iPluginArray )
+ {
+ TInt pluginCount(iPluginArray->Count());
+
+ LOGSTRING2("RWriterController::InitialisePluginStream - plugin count %d, searching through", pluginCount);
+ for(TInt i=0;i<pluginCount;i++)
+ {
+ LOGSTRING2("RWriterController::InitialisePluginStream - getting plugin n:o: %d...", i);
+ CWriterPluginInterface* plugin = iPluginArray->At(i);
+ LOGSTRING2("RWriterController::InitialisePluginStream - writer found, 0x%x, initializing stream...", plugin->Id());
+ plugin->SetStream(iStream);
+ LOGTEXT(_L("RSamplerController::InitialisePluginStream - succeeded!"));
+ }
+ }
+ LOGTEXT(_L("RSamplerController::InitialisePluginStream - exit"));
+
+ }
+
+CArrayPtrFlat<CWriterPluginInterface>* CWriterController::GetPluginList()
+ {
+ return iPluginArray;
+ }
+
+void CWriterController::HandlePluginLoaded( KWriterPluginLoaderStatus aStatus )
+ {
+
+ switch(aStatus)
+ {
+ case 0:
+ LOGSTRING2("RWriterController - one plugin loaded, status: %d", aStatus);
+ break;
+ case 1:
+ LOGSTRING2("RWriterController - a plugin load failed: %d", aStatus);
+ break;
+ case 2:
+ LOGSTRING2("RWriterController - plugin loading aborted: %d", aStatus);
+ break;
+ case 3:
+ LOGSTRING2("RWriterController - all plugins loaded: %d", aStatus);
+ // set stream after all loaded writer plugins
+ InitialisePluginStream();
+ break;
+ case 4:
+ LOGSTRING2("RWriterController - error in loading plugins: %d", aStatus);
+ break;
+ default:
+ break;
+ }
+ }
+
+
+
+TUid CWriterController::GetPluginUID(TInt traceId)
+ {
+ LOGSTRING2(" RWriterController::GetPluginUID - checking UID for traceId = %d",traceId);
+ // this part has to be changed for each new writer
+
+ if( iPluginArray && iPluginArray->Count() > 0 )
+ {
+ for(TInt i=0;i<iPluginArray->Count();i++)
+ {
+ CWriterPluginInterface* plugin = iPluginArray->At(i);
+ if(plugin->Id().iUid == traceId)
+ {
+ LOGSTRING2(" RWriterController::GetPluginUID - got: 0x%X",plugin->Id());
+ return plugin->Id();
+ }
+ }
+ }
+ return KWriterNoneSelected;
+
+ }
+
+CWriterPluginInterface* CWriterController::GetActiveWriter()
+ {
+ CWriterPluginInterface* plugin = NULL;
+
+ if( iPluginArray )
+ {
+ TInt count(iPluginArray->Count());
+
+ for(TInt i=0;i<count;i++)
+ {
+ plugin = iPluginArray->At(i);
+ if(plugin->GetEnabled())
+ {
+ return plugin;
+ }
+ }
+ }
+
+ return (CWriterPluginInterface*)0;
+ }
+
+TUint32 CWriterController::GetWriterType(TUint32 writerId)
+ {
+ TUid id;
+
+ id = this->GetPluginUID(writerId);
+
+ if(id != KWriterNoneSelected)
+ return GetPlugin(id)->GetWriterType();
+ else
+ return 0;
+ }
+
+CWriterPluginInterface* CWriterController::GetPlugin(TUid aUid)
+ {
+ if( iPluginArray && iPluginArray->Count() > 0 )
+ {
+ for(TInt i=0;i<iPluginArray->Count();i++)
+ {
+ CWriterPluginInterface* plugin = iPluginArray->At(i);
+ // check if searched uid found
+ if(plugin->Id().iUid == aUid.iUid)
+ {
+ // return pointer to found plugin
+ return plugin;
+ }
+ }
+ }
+ // return null plugin
+ return (CWriterPluginInterface*)0;
+ }
+
+TInt CWriterController::StartSelectedPlugin()
+ {
+ LOGTEXT(_L("RWriterController::StartSelectedPlugin - entry"));
+
+ CWriterPluginInterface* plugin = GetActiveWriter();
+
+ if(plugin)
+ {
+ return plugin->Start();
+ }
+
+ LOGTEXT(_L("RWriterController::StartSelectedPlugin - exit"));
+ return KErrNotFound;
+ }
+
+void CWriterController::StopSelectedPlugin()
+ {
+ LOGTEXT(_L("RWriterController::StopSelectedPlugin - entry"));
+
+ CWriterPluginInterface* plugin = GetActiveWriter();
+
+ if(plugin)
+ {
+ plugin->Stop();
+ }
+ LOGTEXT(_L("RWriterController::StopSelectedPlugin - exit"));
+ }
+
+/** Set selected plugin active **/
+void CWriterController::SetPluginActive(TUid uid, const TWriterPluginValueKeys aKey)
+ {
+ CWriterPluginInterface* plugin = NULL;
+ _LIT(KDummy, "");
+ TBuf<1> buf;
+ buf.Append(KDummy);
+
+ for(TInt i(0);i<iPluginArray->Count();i++)
+ {
+ plugin = iPluginArray->At(i);
+ if(plugin->Id().iUid == uid.iUid)
+ {
+ plugin->SetValue(aKey, buf);
+ }
+ else
+ {
+ plugin->SetValue(EWriterPluginDisabled, buf);
+ }
+ }
+ }
+
+TInt CWriterController::SetPluginSettings(TUid aUid, TDes& aDes)
+ {
+ LOGSTRING2(" CWriterController::SetPluginSettings, traceId = 0x%X", aUid.iUid);
+ GetPlugin(aUid)->SetValue(EWriterPluginSettings, aDes);
+ return KErrNone;
+ }
+
+/** Get settings for a specific plugin **/
+void CWriterController::GetPluginSettings(TUid uid, TDes& aVal)
+ {
+ GetPlugin(uid)->GetValue(EWriterPluginSettings, aVal);
+ }
+
+
+// end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/engine/src/WriterPluginLoader.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,565 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+// INCLUDE FILES
+#include "WriterPluginLoader.h"
+//#include <piprofiler/EngineUIDs.h>
+#include <utf.h> // CnvUtfConverter
+#include <basched.h>
+
+// constants
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::NewL
+//
+// EPOC two-phased constructor
+// ----------------------------------------------------------------------------
+//
+CWriterPluginLoader* CWriterPluginLoader::NewL()
+ {
+ CWriterPluginLoader* self = new( ELeave ) CWriterPluginLoader;
+ CleanupStack::PushL( self );
+ self->ConstructL( );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::CWriterPluginLoader
+//
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// ----------------------------------------------------------------------------
+//
+CWriterPluginLoader::CWriterPluginLoader() : CActive( EPriorityStandard )
+ {
+ LOGTEXT(_L("CWriterPluginLoader()::CWriterPluginLoader()" ));
+ }
+
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::ConstructL
+//
+// EPOC default constructor can leave.
+// ----------------------------------------------------------------------------
+//
+void CWriterPluginLoader::ConstructL( )
+ {
+ LOGTEXT(_L("CWriterPluginLoader()::ConstructL()" ));
+
+ // get list of implementations
+ CWriterPluginInterface::ListAllImplementationsL( iImplInfoArray );
+
+ CActiveScheduler::Add( this );
+ }
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::~CWriterPluginLoader
+//
+// Destructor
+// ----------------------------------------------------------------------------
+//
+CWriterPluginLoader::~CWriterPluginLoader()
+ {
+ LOGTEXT(_L("CWriterPluginLoader()::~CWriterPluginLoader()") );
+
+ AbortAsyncLoad();
+
+ Cancel();
+
+ // reset ECOM implementation info array
+ iImplInfoArray.ResetAndDestroy(); // This is needed
+ iImplInfoArray.Close();
+ }
+
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::LoadAsync
+//
+//
+// ----------------------------------------------------------------------------
+//
+void CWriterPluginLoader::LoadAsyncL( CArrayPtrFlat<CWriterPluginInterface>* aPluginArray )
+ {
+ iPluginArray = aPluginArray;
+
+ // Reset iterator:
+ iImplInfoArrayIterator = 0;
+
+ LOGSTRING2( "CWriterPluginLoader()::Implementation info count: %d",
+ iImplInfoArray.Count() );
+
+ NotifyProgress();
+
+ //Begin CActive asynchronous loop.
+ CompleteOwnRequest();
+ }
+
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::LoadSyncL
+//
+//
+// ----------------------------------------------------------------------------
+//
+CWriterPluginInterface& CWriterPluginLoader::LoadSyncL( TUid aImplementationUid )
+ {
+ Cancel();
+ CWriterPluginInterface* plugin = NULL;
+
+ // Get a list of all implementations, even though we only want one specific
+ // one. There appears to be no way to otherwise extract a specific implementation
+ // info object :(
+ // Search for the implementation that matches aImplementationUid
+ const TInt impCount = iImplInfoArray.Count();
+ for( TInt i=0; i<impCount; i++ )
+ {
+ const CImplementationInformation* info = iImplInfoArray[ i ];
+ if ( info->ImplementationUid() == aImplementationUid )
+ {
+ TRAPD(ret, plugin = &CreatePluginInstanceL( *info ); );
+ if( ret == KErrNone )
+ {
+ // Plugin ownership is transfered to iPluginArray
+ InsertPluginInOrderL( plugin, iPluginArray );
+ }
+ else
+ {
+ // Error note is displayed even if plugin is not loaded
+ LOGSTRING2("CWriterPluginLoader::LoadSyncL() - plugin load failed, error %d", ret);
+ }
+ break;
+ }
+ }
+
+ if ( plugin == NULL )
+ {
+ User::Leave( KErrNotFound );
+ }
+ return *plugin;
+ }
+
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::AbortAsyncLoad
+//
+//
+// ----------------------------------------------------------------------------
+//
+void CWriterPluginLoader::AbortAsyncLoad()
+ {
+ LOGTEXT(_L("CWriterPluginLoader()::AbortAsyncLoad()" ));
+ Cancel();
+ }
+
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::RunL
+//
+//
+// ----------------------------------------------------------------------------
+//
+void CWriterPluginLoader::RunL()
+ {
+ iRunLDebugCount++;
+ LoadNextPluginL();
+
+ // Check if there are still more plugins to be loaded:
+ if ( iImplInfoArrayIterator < iImplInfoArray.Count() )
+ {
+ NotifyProgress();
+ // Continue CActive asynchronous loop.
+ CompleteOwnRequest();
+ }
+ else
+ {
+ // All plugins loaded:
+ LOGTEXT(_L("CWriterPluginLoader()::Loading plugins finished." ));
+ NotifyFinished();
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CScGenreItemConstructionConductor::CompleteOwnRequest
+//
+// Issue request complete notification.
+// ---------------------------------------------------------------------------
+void CWriterPluginLoader::CompleteOwnRequest()
+ {
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete( status, KErrNone );
+ SetActive();
+ }
+
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::RunError
+//
+//
+// ----------------------------------------------------------------------------
+//
+TInt CWriterPluginLoader::RunError( TInt aError )
+ {
+ // This method is called when a plugin loading fails.
+ // Always "fake" the return value so that ActiveSchedule
+ // keeps running and later plugins are continued to be loaded.
+ // Check if still plugins to be loaded:
+ if( iImplInfoArrayIterator < iImplInfoArray.Count() )
+ {
+ NotifyProgress();
+
+ //Continue CActive asynchronous loop.
+ CompleteOwnRequest();
+ }
+ else // All plugins loaded:
+ {
+ NotifyFinished();
+ }
+
+ if ( aError == KLeaveExit )
+ {
+ return KLeaveExit;
+ }
+
+ return KErrNone;
+ }
+
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::DoCancel
+//
+//
+// ----------------------------------------------------------------------------
+//
+void CWriterPluginLoader::DoCancel()
+ {
+
+ }
+
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::NotifyProgress
+//
+//
+// ----------------------------------------------------------------------------
+//
+void CWriterPluginLoader::NotifyProgress()
+ {
+ if( iObserver )
+ {
+ iObserver->HandlePluginLoaded( MWriterPluginLoadObserver::EWriterSuccess);
+ }
+ }
+
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::NotifyFinished
+//
+//
+// ----------------------------------------------------------------------------
+//
+void CWriterPluginLoader::NotifyFinished()
+ {
+ if( iObserver )
+ {
+ iObserver->HandlePluginLoaded( MWriterPluginLoadObserver::EWriterFinished );
+ }
+ }
+
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::SetObserver
+//
+//
+// ----------------------------------------------------------------------------
+//
+void CWriterPluginLoader::SetObserver(MWriterPluginLoadObserver* aObserver)
+ {
+ LOGSTRING2("CWriterPluginLoader()::Observer set:0x%X", aObserver);
+ iObserver = aObserver;
+ }
+
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::ParseToUid
+// Parses a UID from descriptor of form '0xNNNNNNNN' where N is hexadecimal.
+//
+// ----------------------------------------------------------------------------
+//
+TInt CWriterPluginLoader::ParseToUid( const TDesC8& aSource, TUid& aTarget )
+ {
+ // Remove "0x" from the descriptor if it exists
+ _LIT8(KHexPrefix, "0x");
+
+ TPtrC8 pSource( aSource );
+ const TInt prefixPosition = pSource.Find( KHexPrefix );
+ if ( prefixPosition != KErrNotFound )
+ {
+ pSource.Set( aSource.Mid( prefixPosition + KHexPrefix().Length() ) );
+ }
+
+ // Parse to integer
+ TLex8 lex( pSource );
+ TUint integer = 0;
+
+ // Parse using TRadix::EHex as radix:
+ const TInt err = lex.Val( integer, EHex );
+ aTarget.iUid = integer;
+
+ if( err != KErrNone )
+ {
+ // If parsing parent UID failed, do not load plugin:
+ LOGSTRING2(
+ "CWriterPluginLoader()::Parsing parent UID failed. Error code:%d",
+ err );
+ }
+ return err;
+ }
+
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::ParseOrderNumber
+//
+//
+// ----------------------------------------------------------------------------
+//
+TInt CWriterPluginLoader::ParseOrderNumber( const TDesC8& aSource, TInt& aOrderNumber )
+ {
+ // Parse plugin's order number from opaque_data:
+ TLex8 lex( aSource );
+ const TInt orderErr = lex.Val( aOrderNumber );
+ return orderErr;
+ }
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::LoadNextPluginL
+// Iterate through iImplInfoArray. Load the plugin if it is eligible for
+// loading. Loaded plugin is added to iPluginArray. Each time a plugin is
+// loaded, iObserver is notified.
+//
+// ----------------------------------------------------------------------------
+//
+void CWriterPluginLoader::LoadNextPluginL()
+ {
+ // Iterate through iImplInfoArray. This loop continues between function
+ // calls. Therefore member variable iImplInfoArrayIterator is used as a
+ // counter. Loop will break when match is found and continues on next RunL.
+ for( ; iImplInfoArrayIterator < iImplInfoArray.Count(); )
+ {
+ const CImplementationInformation* info =
+ iImplInfoArray[ iImplInfoArrayIterator ];
+
+ iImplInfoArrayIterator++;
+
+ // If this plugin is OK -> load it:
+ LOGSTRING2( "CWriterPluginLoader() %S eligible for parent",
+ &info->DisplayName() );
+ CWriterPluginInterface* plugin = NULL;
+ TInt error(KErrNone);
+ // Create plugin. Trap leave for debugging purposes.
+ TRAP( error, plugin = &CreatePluginInstanceL( *info ); );
+ if( error == KErrNone )
+ {
+ // Plugin ownership is transfered to iPluginArray
+ InsertPluginInOrderL( plugin, iPluginArray );
+ }
+ else
+ {
+ LOGSTRING2("CWriterPluginLoader::LoadNextPluginL() - plugin load failed, error %d", error);
+ }
+ // Wait for next round
+ break;
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::CreatePluginInstanceL
+//
+//
+// ----------------------------------------------------------------------------
+//
+
+CWriterPluginInterface& CWriterPluginLoader::CreatePluginInstanceL(
+ const CImplementationInformation& aImpInfo )
+ {
+ // Now we can load the plugin
+ const TUid implUid = aImpInfo.ImplementationUid();
+
+ CWriterPluginInterface* plugin = CWriterPluginInterface::NewL( implUid , (TAny*)&aImpInfo.DisplayName() );
+ CleanupStack::PushL ( plugin );
+
+ TInt orderNumber(0);
+ const TInt orderErr = ParseOrderNumber( aImpInfo.OpaqueData(), orderNumber );
+
+ if ( orderErr == KErrNone && orderNumber >= 0 )
+ {
+ plugin->iOrder = orderNumber;
+ }
+
+ CleanupStack::Pop( plugin ); // CWriterController is now responsible for this memory.
+
+ return *plugin;
+ }
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::SortPluginsL
+//
+// ----------------------------------------------------------------------------
+//
+void CWriterPluginLoader::SortPluginsL(
+ CArrayPtrFlat<CWriterPluginInterface>* aPlugins )
+ {
+ RPointerArray<CWriterPluginInterface> plugins;
+ TLinearOrder<CWriterPluginInterface> order( CWriterPluginLoader::Compare );
+
+ // Insertion will also order
+ for( TInt i = 0; i < aPlugins->Count(); i++ )
+ {
+ plugins.InsertInOrderL( (*aPlugins)[i], order );
+ }
+
+ // Replace original array content with sorted items
+ aPlugins->Reset();
+ for( TInt i = 0; i < plugins.Count(); i++ )
+ {
+ aPlugins->AppendL( plugins[i] );
+ }
+ }
+
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::Compare
+//
+// Compare two plugins.
+// Precedence:
+// [1. plugin provider category]
+// 2. plugin order number
+// 3. plugin caption
+// Plugin provider gategory is currently disabled (not supported yet).
+// ----------------------------------------------------------------------------
+//
+TInt CWriterPluginLoader::Compare( const CWriterPluginInterface& aFirst,
+ const CWriterPluginInterface& aSecond )
+ {
+ return CompareIndex( aFirst, aSecond );
+ }
+
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::InsertPluginInOrderL
+//
+// ----------------------------------------------------------------------------
+//
+void CWriterPluginLoader::InsertPluginInOrderL(
+ CWriterPluginInterface* aPlugin,
+ CArrayPtrFlat<CWriterPluginInterface>* aPlugins )
+ {
+ CWriterPluginInterface* comparedPlugin;
+ TInt comparison = 0;
+ TBool inserted = EFalse;
+
+ for( TInt i = 0; i < aPlugins->Count(); i++ )
+ {
+ comparedPlugin = (*aPlugins)[i];
+ // Optimization: do not call time consuming Compare() multiple times!
+ comparison = Compare( *aPlugin, *comparedPlugin );
+ if( comparison < 0 )
+ {
+ aPlugins->InsertL( i, aPlugin );
+ inserted = ETrue;
+ break;
+ }
+ else if( comparison == 0 )
+ {
+ aPlugins->InsertL( i+1, aPlugin );
+ inserted = ETrue;
+ break;
+ }
+ }
+ // Plugin was not before any other plugin - make sure it's appended
+ if( !inserted )
+ {
+ aPlugins->AppendL( aPlugin );
+ }
+
+ #ifdef _GS_PLUGINLOADER_SORTING_TRACES
+ PrintOrderTraces( aPlugins );
+ #endif // _GS_PLUGINLOADER_SORTING_TRACES
+
+ }
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::CompareIndex
+//
+//
+// ----------------------------------------------------------------------------
+//
+
+TInt CWriterPluginLoader::CompareIndex( const CWriterPluginInterface& aFirst,
+ const CWriterPluginInterface& aSecond )
+ {
+ TInt comparison = KWriterComparisonEqual;
+ // The plugin having index is before the one not having one
+
+ if( aFirst.iOrder == KWriterPluginNotIndexed &&
+ aSecond.iOrder == KWriterPluginNotIndexed )
+ {
+ // Neither have index -> equal
+ comparison = KWriterComparisonEqual;
+ }
+ else if( aFirst.iOrder == KWriterPluginNotIndexed )
+ {
+ // The plugin having index is before the one not having one
+ comparison = KWriterComparisonAfter;
+ }
+ else if( aSecond.iOrder == KWriterPluginNotIndexed )
+ {
+ // The plugin having index is before the one not having one
+ comparison = KWriterComparisonBefore;
+ }
+ else if( aFirst.iOrder < aSecond.iOrder )
+ {
+ // Compare actual index values
+ comparison = KWriterComparisonBefore;
+ }
+ else if( aFirst.iOrder > aSecond.iOrder )
+ {
+ // Compare actual index values
+ comparison = KWriterComparisonAfter;
+ }
+ return comparison;
+ }
+
+
+// ----------------------------------------------------------------------------
+// CWriterPluginLoader::GetDocument
+//
+//
+// ----------------------------------------------------------------------------
+//
+/*
+CWriterBaseDocument* CWriterPluginLoader::GetDocument()
+ {
+ CWriterBaseDocument* document = static_cast<CWriterBaseDocument*>( iAppUi->Document() );
+ return document;
+ }
+*/
+
+// End of File
Binary file piprofiler/group/ReleaseNotes_PIProfiler.txt has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/group/bld.inf Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,33 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+//PRJ_PLATFORMS
+//DEFAULT ARMV5SMP
+
+#include <platform_paths.hrh>
+
+#include "../piprofiler_plat/group/bld.inf"
+#include "../engine/group/bld.inf"
+#include "../plugins/GeneralsPlugin/group/bld.inf"
+#include "../plugins/BUPplugin/group/bld.inf"
+#include "../plugins/DebugOutputWriterPlugin/group/bld.inf"
+#include "../plugins/DiskWriterPlugin/group/bld.inf"
+
+
+PRJ_EXPORTS
+../rom/piprofiler.iby CORE_IBY_EXPORT_PATH(tools,piprofiler.iby)
+../rom/piprofiler_ldd.iby CORE_IBY_EXPORT_PATH(tools/rom,piprofiler_ldd.iby)
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/group/bld.inf Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,44 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: File that exports the files belonging to
+: PIProfilerAPI
+*
+*/
+
+
+#include <platform_paths.hrh>
+
+
+PRJ_EXPORTS
+../inc/ProfilerTraces.h OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/ProfilerTraces.h)
+../inc/ProfilerVersion.h OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/ProfilerVersion.h)
+../inc/ProfilerConfig.h OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/ProfilerConfig.h)
+../inc/ProfilerAttributes.h OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/ProfilerAttributes.h)
+../inc/ProfilerGenericClassesUsr.h OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/ProfilerGenericClassesUsr.h)
+../inc/ProfilerGenericClassesUsr.inl OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/ProfilerGenericClassesUsr.inl)
+../inc/ProfilerGenericClassesKrn.h OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/ProfilerGenericClassesKrn.h)
+../inc/ProfilerGenericClassesKrn.inl OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/ProfilerGenericClassesKrn.inl)
+../inc/ProfilerGenericClassesCommon.h OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/ProfilerGenericClassesCommon.h)
+../inc/ProfilerEngineAPI.h OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/ProfilerEngineAPI.h)
+../inc/EngineUIDs.h OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/EngineUIDs.h)
+../inc/PluginDriver.h OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/PluginDriver.h)
+../inc/PluginDriver.inl OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/PluginDriver.inl)
+../inc/PluginSampler.h OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/PluginSampler.h)
+../inc/ProfilerSession.h OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/ProfilerSession.h)
+../inc/SamplerPluginInterface.h OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/SamplerPluginInterface.h)
+../inc/SamplerPluginInterface.inl OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/SamplerPluginInterface.inl)
+../inc/WriterPluginInterface.h OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/WriterPluginInterface.h)
+../inc/WriterPluginInterface.inl OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/WriterPluginInterface.inl)
+../inc/ProfilerEngineStatusChecker.h OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/ProfilerEngineStatusChecker.h)
+../inc/ProfilerEngineStatusChecker.inl OS_LAYER_PLATFORM_EXPORT_PATH(piprofiler/ProfilerEngineStatusChecker.inl)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/EngineUIDs.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,29 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef ENGINEUIDS_H
+#define ENGINEUIDS_H
+
+#include <e32cmn.h>
+
+// No item is selected in the container's listbox
+const TUid KSamplerNoneSelected = { 0x00000001 };
+const TUid KWriterNoneSelected = { 0x00000002 };
+
+#endif // ENGINEUIDS_H
+// End of File
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/PluginDriver.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,85 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <piprofiler/ProfilerGenericClassesKrn.h>
+
+const TInt KMinRate = 10;
+const TInt KMaxRate = 1000;
+
+enum TState{ERunning, EStopping, EStopped};
+
+const TUid KGppPropertyCat={0x20201F70};
+enum TGppPropertyKeys
+ {
+ EGppPropertySyncSampleNumber
+ };
+
+
+/*
+ *
+ *
+ * Class DPluginDriver definition, inherited by sampler implementations except GPP
+ *
+ *
+ */
+
+class DPluginDriver : public DLogicalChannel
+{
+
+public:
+ DPluginDriver();
+ ~DPluginDriver();
+
+public:
+ TInt ProcessStreamReadCancel();
+
+ TInt StopSampling();
+
+private:
+ TInt ProcessPrintStreamRequest(TDesC8* aDes/*,TRequestStatus* aStatus*/);
+
+ void FastPrintf(TDesC8* aDes);
+
+public:
+ DThread* iClient;
+
+ // property and value;
+ // GPP sampler start time, needed to set other samplers in sync
+ RPropertyRef iSampleStartTimeProp;
+ TInt iSampleStartTime;
+ TUint32 iSyncOffset; // offset from the start
+
+
+ TUint32 sampleRunning;
+ const TUint* iInterruptStack;
+ TState iState;
+ TInt doingDfc;
+
+ // request status objects for requests
+ TRequestStatus* iEndRequestStatus;
+ TRequestStatus* iStreamReadCancelStatus;
+
+ // sample stream object used in stream mode
+ DProfilerSampleStream iSampleStream;
+
+ // just for testing
+ TUint32* stackTop;
+
+};
+
+#include <piprofiler/PluginDriver.inl>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/PluginDriver.inl Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,77 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+//
+// LDD for thread time profiling
+//
+
+#include <piprofiler/ProfilerConfig.h>
+#include <piprofiler/ProfilerVersion.h>
+
+
+#include <kern_priv.h>
+#include <sproperty.h>
+
+#include <piprofiler/PluginSampler.h>
+
+
+/*
+ *
+ *
+ * Class DPluginDriver implementation
+ *
+ *
+ */
+inline DPluginDriver::DPluginDriver() //: iSubsRequest(&HandleSubsComplete, this)
+ {
+ //iClientProcess = &Kern::CurrentProcess();
+ }
+inline DPluginDriver::~DPluginDriver()
+ {
+
+ }
+
+/*
+ * Methods for controlling stream read option
+ */
+
+inline TInt DPluginDriver::ProcessStreamReadCancel()
+{
+ return KErrNone;
+}
+
+/*
+ * Mark traces active or inactive, this can be done
+ * only if sampling is not running
+ */
+
+inline TInt DPluginDriver::StopSampling()
+{
+ if(this->iState == ERunning)
+ {
+ this->iState = EStopping;
+ return KErrNone;
+ }
+ else
+ {
+ return KErrGeneral;
+ }
+}
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/PluginSampler.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,247 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef __PLUGINSAMPLER_H__
+#define __PLUGINSAMPLER_H__
+
+/*
+ * The user-interface to the sampling device driver sued by the profiling engine
+ */
+// #include <piprofiler/ProfilerConfig.h>
+// #include <piprofiler/ProfilerVersion.h> // versions removed from ProfilerConfig.h
+
+#ifndef __KERNEL_MODE__
+#include <utf.h>
+#endif
+
+/*
+ * Forward declarations
+ */
+class TBapBuf;
+
+/**
+ * A minimal capabilities class for the Sampling device.
+ * It just returns the version number.
+ */
+class TCapsSamplerV01
+ {
+public:
+ TVersion iVersion;
+ };
+
+
+const TInt KMinDelay = 1;
+const TInt KMaxDelay = 10000;
+
+/**
+ * The user device driver class for controlling the plugin sampler.
+ */
+
+class RPluginSampler : public RBusLogicalChannel
+{
+ friend class DPluginDriver;
+ public:
+ enum TControl
+ {
+ EOutputSettingsForTrace,
+ EMarkTraceActive,
+ EMarkTraceInactive,
+ ESample,
+ EStartSampling,
+ EGetSampleTime,
+ EGetSamplerVersion,
+ EStopAndWaitForEnd,
+ ESetSamplingPeriod,
+ EAdditionalTraceSettings,
+ EAdditionalTraceSettings2,
+ EAdditionalTraceSettings3,
+ EAdditionalTraceSettings4,
+ //EPrintTraces,
+ ECancelStreamRead,
+ ERequestFillThisStreamBuffer,
+ ERequestPrintStreamBuffer,
+ ETest
+ };
+
+ public:
+ #ifndef __KERNEL_MODE__
+
+ inline ~RPluginSampler();
+
+ /**
+ *
+ * Methods for controlling the sampler device
+ *
+ **/
+ /** Open a channel to the sampling device **/
+ virtual TInt Open() = 0;
+
+ /** Set sampling period for sampler */
+ inline void SetSamplingPeriod(TInt samplerId, TInt settings);
+
+ /** Set additional trace settings **/
+ inline void AdditionalSettingsForTrace(TInt samplerId,TInt settings);
+ inline void AdditionalSettingsForTrace2(TInt samplerId,TInt settings);
+ inline void AdditionalSettingsForTrace3(TInt samplerId,TInt settings);
+ inline void AdditionalSettingsForTrace4(TInt samplerId,TInt settings);
+
+ /** Mark trace active **/
+ inline void MarkTraceActive(TUint32 id);
+
+ /** Mark trace inactive **/
+ inline void MarkTraceInactive(TUint32 id);
+
+ /** Sample command to kernel LDD**/
+ inline void Sample();
+
+ /** Start tracing **/
+ inline void StartSampling();
+
+ /** Stop tracing **/
+ inline void StopSampling();
+
+ /** Get current sampling time **/
+ inline TUint32 GetSampleTime();
+
+ /** Get sampler version as descriptor **/
+ virtual void GetSamplerVersion(TDes*);
+
+ /** Get next filled buffer in stream mode **/
+ void GetNextbuffer( );
+
+ /** Request stream read **/
+ void FillThisStreamBuffer(TBapBuf* aBuffer, TRequestStatus& aStatus);
+
+ /** Request print buffer**/
+ void PrintStreamBuffer(TDesC16* aBuffer);
+
+ /** Run test case **/
+ inline void Test(TUint32 testCase);
+
+ #endif // !__KERNEL_MODE__
+};
+
+
+#ifndef __KERNEL_MODE__
+inline RPluginSampler::~RPluginSampler()
+{
+}
+
+inline void RPluginSampler::AdditionalSettingsForTrace(TInt samplerId,TInt settings)
+ {
+ DoControl(EAdditionalTraceSettings,
+ reinterpret_cast<TAny*>(samplerId),
+ reinterpret_cast<TAny*>(settings));
+ }
+
+inline void RPluginSampler::AdditionalSettingsForTrace2(TInt samplerId,TInt settings)
+ {
+ DoControl(EAdditionalTraceSettings2,
+ reinterpret_cast<TAny*>(samplerId),
+ reinterpret_cast<TAny*>(settings));
+ }
+
+inline void RPluginSampler::AdditionalSettingsForTrace3(TInt samplerId,TInt settings)
+ {
+ DoControl(EAdditionalTraceSettings3,
+ reinterpret_cast<TAny*>(samplerId),
+ reinterpret_cast<TAny*>(settings));
+ }
+
+inline void RPluginSampler::AdditionalSettingsForTrace4(TInt samplerId,TInt settings)
+ {
+ DoControl(EAdditionalTraceSettings4,
+ reinterpret_cast<TAny*>(samplerId),
+ reinterpret_cast<TAny*>(settings));
+ }
+
+inline void RPluginSampler::SetSamplingPeriod(TInt samplerId, TInt settings)
+ {
+ DoControl(ESetSamplingPeriod,
+ reinterpret_cast<TAny*>(samplerId),
+ reinterpret_cast<TAny*>(settings));
+ }
+
+
+inline void RPluginSampler::MarkTraceActive(TUint32 id)
+{
+ DoControl(EMarkTraceActive, reinterpret_cast<TAny*>(id));
+}
+
+inline void RPluginSampler::MarkTraceInactive(TUint32 id)
+{
+ DoControl(EMarkTraceInactive, reinterpret_cast<TAny*>(id));
+}
+
+inline void RPluginSampler::Sample()
+ {
+ DoControl(ESample);
+ }
+
+inline void RPluginSampler::StartSampling()
+{
+ // at first, start the kernel side samplers
+ DoControl(EStartSampling);
+}
+
+inline void RPluginSampler::StopSampling()
+{
+ // stop the device driver and the kernel mode samplers
+ TRequestStatus status;
+ status = KRequestPending;
+ DoRequest(EStopAndWaitForEnd,status);
+ User::WaitForRequest(status);
+}
+
+inline TUint32 RPluginSampler::GetSampleTime()
+{
+ TUint32* sampleTime = new TUint32;
+
+ DoControl(EGetSampleTime,reinterpret_cast<TAny*>(sampleTime));
+ TUint32 value = *sampleTime;
+ delete sampleTime;
+
+ return value;
+}
+
+inline void RPluginSampler::GetSamplerVersion(TDes* aDes)
+{
+ TBuf8<16> buf;
+ DoControl(EGetSamplerVersion,(TAny*)&buf);
+ CnvUtfConverter::ConvertToUnicodeFromUtf8(*aDes,buf);
+}
+
+inline void RPluginSampler::PrintStreamBuffer(TDesC16* aDes)
+{
+ DoControl(ERequestPrintStreamBuffer,reinterpret_cast<TAny*>(aDes));
+}
+
+inline void RPluginSampler::FillThisStreamBuffer(TBapBuf* aBuffer, TRequestStatus& aStatus)
+{
+ aStatus = KRequestPending;
+ DoRequest(ERequestFillThisStreamBuffer,aStatus,(TAny*)aBuffer);
+
+}
+
+inline void RPluginSampler::Test(TUint32 testCase)
+{
+ DoControl(ETest,reinterpret_cast<TAny*>(testCase));
+}
+
+#endif
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/ProfilerAttributes.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,151 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef PROFILER_ATTRIBUTES_H
+#define PROFILER_ATTRIBUTES_H
+
+// INCLUDES
+#include <e32std.h>
+#include <e32base.h>
+#include <s32mem.h>
+
+// LITERALS
+_LIT8(KDefaultTraceFilePrefix, "PIProfiler_#");
+_LIT8(KDefaultTraceOutput, "file_system");
+_LIT8(KDefaultTraceFileSaveDrive, "C:\\data\\");
+
+_LIT8(KEnabled, "enabled");
+_LIT8(KBracketOpen, "[");
+_LIT8(KBracketClose, "]");
+_LIT8(KSettingItemSeparator, "=");
+
+// CONSTANTS
+const TUint KPrefixMaxLength = 64;
+const TUint KShortNameMaxLength = 3;
+const TUint KNameMaxLength = 63;
+const TUint KDescriptionMaxLength = 255;
+const TInt KDefaultTimedSamplingPeriod = 60; // Sampling time in seconds
+/*
+ *
+ * TGeneralAttributes class definition, internal settings format
+ *
+ */
+class TGeneralAttributes
+ {
+public:
+ TBuf8<KPrefixMaxLength> iTraceOutput;
+ TBuf8<KPrefixMaxLength> iTraceFilePrefix;
+ TBuf8<KPrefixMaxLength> iSaveFileDrive;
+ TInt iTimedSamplingPeriod;
+ };
+
+
+
+/*
+ *
+ * TSettingItem class definition, internal settings format
+ *
+ */
+class TSettingItem
+ {
+public:
+ enum
+ {
+ ESettingItemTypeInt = 0,
+ ESettingItemTypeBool,
+ ESettingItemTypeHex,
+ ESettingItemTypeText
+ };
+
+public:
+ TBuf<64> iSettingText;
+ TUint32 iType;
+ TBuf<128> iValue;
+ TBuf<256> iSettingDescription;
+ TBuf<64> iUIText;
+ };
+/*
+ *
+ * TSamplerAttributes class definition, internal settings format
+ *
+ */
+class TSamplerAttributes
+ {
+public:
+ // default constructor
+ TSamplerAttributes();
+ // constructor
+ TSamplerAttributes(TInt32 aUid,
+ const TDesC8& aShortName,
+ const TDesC8& aName,
+ const TDesC8& aDescription,
+ TInt aSampleRate,
+ TBool aEnabled,
+ TBool aHidden,
+ TInt aItemCount);
+public:
+ TInt32 iUid;
+ TBuf8<8> iShortName; // name of the plugin, short name
+ TBuf8<64> iName; // name of the plugin, long name
+ TBuf8<256> iDescription; // sampler description, info about HW/SW dependencies etc.
+ TInt iSampleRate; // sample rate of the plugin
+ TBool iEnabled; // enabled for profiling
+ TBool iIsHidden; // hidden, i.e. no start/stop controls
+ TInt iItemCount; // plugin specific setting item count
+
+ // plugin specific settings, plugin implementation dependent
+ TSettingItem iSettingItem1;
+ TSettingItem iSettingItem2;
+ TSettingItem iSettingItem3;
+ TSettingItem iSettingItem4;
+ TSettingItem iSettingItem5;
+ TSettingItem iSettingItem6;
+ };
+
+inline TSamplerAttributes::TSamplerAttributes()
+ {}
+
+inline TSamplerAttributes::TSamplerAttributes(TInt32 aUid,
+ const TDesC8& aShortName,
+ const TDesC8& aName,
+ const TDesC8& aDescription,
+ TInt aSampleRate,
+ TBool aEnabled,
+ TBool aHidden,
+ TInt aItemCount)
+ {
+ iUid = aUid;
+ // check if given short name too long
+ aShortName.Length() > KShortNameMaxLength ?
+ iShortName.Copy(aShortName.Left(KShortNameMaxLength)) :
+ iShortName.Copy(aShortName);
+ // check if given name too long
+ aName.Length() > KNameMaxLength ?
+ iName.Copy(aName.Left(KNameMaxLength)) :
+ iName.Copy(aName);
+ // check if description too long
+ aDescription.Length() > KDescriptionMaxLength ?
+ iDescription.Copy(aDescription.Left(KDescriptionMaxLength)) :
+ iDescription.Copy(aDescription);
+ iSampleRate = aSampleRate;
+ iEnabled = aEnabled;
+ iIsHidden = aHidden;
+ iItemCount = aItemCount;
+ }
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/ProfilerConfig.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,108 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef PI_PROFILER_CONFIG_H
+#define PI_PROFILER_CONFIG_H
+
+// NCP release process will move the PIProfiler flags as Carbon feature flags
+// where the product responsibles can choose the right settings for PI Profiler
+// compilation.
+
+ /*** NOTE!!!
+ * Uncomment the following definition if compiling the Profiler by your own
+ ***/
+ #define PROFILER_SISX
+
+ /*
+ *
+ * Filename and path for the settings file
+ * this file is written on application exit and
+ * it contains the settings of the profiler application
+ *
+ */
+
+// #define PROFILER_SETTINGS_DRIVE _L("C:\\")
+// #define PROFILER_SETTINGS_MAXLENGTH 32
+// #define PROFILER_SETTINGS_FILENAME _L("ProfilerSettings.txt")
+ const TInt KProfilerSettingsMaxLength = 32;
+ _LIT(KProfilerSettingsFileName, "PIProfilerSettings.txt");
+
+ // a fix for going through the different drives for settings file
+ #define PROFILER_SETTINGS_DRIVE_COUNT 3
+ #define PROFILER_SETTINGS_DRIVE_ARRAY TBuf<4> settingsDrives[PROFILER_SETTINGS_DRIVE_COUNT];
+ #define PROFILER_DEFINE_SETTINGS_DRIVE(name,number) settingsDrives[number].Append(_L(name));
+
+ // change these to reflect the drive names and numbers
+ // the last number must be PROFILER_SETTINGS_DRIVE_COUNT-1
+ #define PROFILER_SETTINGS_DRIVES PROFILER_DEFINE_SETTINGS_DRIVE("C:\\",0) \
+ PROFILER_DEFINE_SETTINGS_DRIVE("E:\\",1) \
+ PROFILER_DEFINE_SETTINGS_DRIVE("Z:\\",2)
+
+ /*
+ *
+ * Locations of PI Profiler binaries
+ *
+ */
+
+ #define PROFILERENGINE_EXE_PATH_PRIMARY _L("C:\\sys\\bin\\PIProfilerEngine.exe")
+ #define PROFILERENGINE_EXE_PATH_SECONDARY _L("Z:\\sys\\bin\\PIProfilerEngine.exe")
+
+ /*
+ *
+ * PI Profiler tool composition definitions
+ *
+ */
+
+ // sampler codes and names
+ #define PROFILER_USER_MODE_SAMPLER 123
+ #define PROFILER_KERNEL_MODE_SAMPLER 321
+ #define PROFILER_DUMMY_SAMPLER 213
+
+ // old definitions
+ #define PROFILER_GENERALS_SAMPLER_ID 100
+ #define PROFILER_INTERNALS_SAMPLER_ID 101
+ #define PROFILER_GPP_SAMPLER_ID 1
+ #define PROFILER_GFC_SAMPLER_ID 2
+ #define PROFILER_ITT_SAMPLER_ID 3
+ #define PROFILER_MEM_SAMPLER_ID 4
+ #define PROFILER_PRI_SAMPLER_ID 5
+ #define PROFILER_IRQ_SAMPLER_ID 6
+ #define PROFILER_BUP_SAMPLER_ID 7
+ #define PROFILER_SWI_SAMPLER_ID 8
+ #define PROFILER_TIP_SAMPLER_ID 9
+ #define PROFILER_PEC_SAMPLER_ID 10
+ #define PROFILER_PWR_SAMPLER_ID 11
+ #define PROFILER_IPC_SAMPLER_ID 12
+ #define PROFILER_ISA_SAMPLER_ID 13
+ #define PROFILER_GPU_SAMPLER_ID 14
+
+ // sampler IDs for external, e.g. 3rd party sampler plug-ins
+ #define PROFILER_EXT1_SAMPLER_ID 15
+ #define PROFILER_EXT2_SAMPLER_ID 16
+ #define PROFILER_EXT3_SAMPLER_ID 17
+ #define PROFILER_EXT4_SAMPLER_ID 18
+ #define PROFILER_EXT5_SAMPLER_ID 19
+
+ #define PROFILER_GPP_SAMPLER_NAME _L("GPP")
+ #define PROFILER_GFC_SAMPLER_NAME _L("GFC")
+ #define PROFILER_ITT_SAMPLER_NAME _L("ITT")
+ #define PROFILER_MEM_SAMPLER_NAME _L("MEM")
+ #define PROFILER_PRI_SAMPLER_NAME _L("PRI")
+ #define PROFILER_GPU_SAMPLER_NAME _L("GPU")
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/ProfilerEngineAPI.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,88 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef PROFILERCONTROLLER_H
+#define PROFILERCONTROLLER_H
+
+#include <e32std.h>
+#include <s32stor.h>
+
+class CProfilerSettings;
+
+class CProfilerEngineAPI : public CBase
+{
+public:
+ enum TProfilerEngineTraceMode
+ {
+ EProfilerEngineDebugOutputMode,
+ EProfilerEngineFileSystemMode
+ };
+
+ ~CProfilerEngineAPI();
+
+ IMPORT_C static CProfilerEngineAPI* NewL();
+ void ConstructL();
+
+ IMPORT_C void SaveSettings();
+ IMPORT_C void LoadSettings();
+
+ // controlling all sampler plugins
+ IMPORT_C TInt StartProfiling();
+ IMPORT_C TBool StopProfiling();
+ IMPORT_C TInt LaunchProfiler();
+
+ // controlling separate plugins
+ IMPORT_C TInt StartSampler(TUint32 aUid);
+ IMPORT_C TInt StopSampler(TUint32 aUid);
+ IMPORT_C TInt EnableSampler(TUint32 aUid);
+ IMPORT_C TInt DisableSampler(TUint32 aUid);
+ IMPORT_C TInt EnableWriter(TUint32 aUid);
+ IMPORT_C TInt DisableWriter(TUint32 aUid);
+
+ // for meeting the HTI requirements
+ IMPORT_C TInt SetSettings(TUint aSamplerId, TDes& aSettings);
+ IMPORT_C TInt SetTraceMode(TProfilerEngineTraceMode aMode, TDes& aTraceDataStruct);
+ IMPORT_C TInt GetSamplerInfo(TUint aSamplerId, TDes& aCompleteSamplerInfo);
+
+ // old implementations
+ IMPORT_C TBool GetSamplerVersion(TDes& version);
+
+ IMPORT_C void LeaveProfilerBG(TBool aVal);
+
+
+public:
+ TBool DriveIsValidL(const TDesC& drive);
+ IMPORT_C CProfilerSettings* Settings() const;
+
+private:
+
+ CProfilerEngineAPI();
+
+ TInt FindProcessL();
+private:
+ CProfilerSettings* iSettings;
+
+ RProcess* iProfilerProcess;
+
+ TBool iProfilerLaunched;
+
+ TBool iLeaveProfilerBG;
+
+ };
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/ProfilerEngineStatusChecker.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,74 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#ifndef PROFILER_STATUS_CHECKER_H
+#define PROFILER_STATUS_CHECKER_H
+
+#include <e32std.h>
+#include <e32base.h>
+#include <e32property.h> // RProperty
+
+// CONSTANTS
+const TUid KEngineStatusPropertyCat = { 0x2001E5AD };
+enum TEnginePropertyKeys
+ {
+ EProfilerEngineStatus = 8
+ };
+
+// CLASS DECLARATIONS
+class MProfilerStatusObserver
+ {
+ public: // Enums
+ enum KProfilerStatus
+ {
+ EIdle = 0,
+ EInitializing,
+ ERunning,
+ EStopping,
+ ERestarting
+ };
+
+ public: // New
+ virtual void HandleProfilerStatusChange(
+ KProfilerStatus aStatus ) = 0;
+ virtual void HandleProfilerErrorL(
+ TInt aError ) = 0;
+ };
+
+
+class CProfilerEngineStatusChecker : public CActive
+ {
+public:
+ inline static CProfilerEngineStatusChecker* CProfilerEngineStatusChecker::NewL();
+ inline ~CProfilerEngineStatusChecker();
+ inline void SetObserver(MProfilerStatusObserver* aObserver);
+ inline TInt GetInitialState();
+private:
+ inline CProfilerEngineStatusChecker();
+ inline void ConstructL();
+ inline void RunL();
+ inline void DoCancel();
+private:
+ TInt iPrevStat;
+ MProfilerStatusObserver* iObserver;
+ RProperty iEngineStatus;
+ };
+
+#include <piprofiler/ProfilerEngineStatusChecker.inl>
+
+
+#endif // PROFILER_STATUS_CHECKER_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/ProfilerEngineStatusChecker.inl Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,128 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+// ------------------------------------------------------------------------------
+//
+// class CProfilerEngineStatusChecker
+//
+// ------------------------------------------------------------------------------
+//
+inline CProfilerEngineStatusChecker* CProfilerEngineStatusChecker::NewL()
+ {
+ CProfilerEngineStatusChecker* self = new(ELeave) CProfilerEngineStatusChecker();
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+ }
+
+// --------------------------------------------------------------------------------------------
+inline CProfilerEngineStatusChecker::CProfilerEngineStatusChecker() :
+ CActive(EPriorityStandard)
+ {
+ }
+
+inline CProfilerEngineStatusChecker::~CProfilerEngineStatusChecker()
+ {
+ Cancel();
+ iEngineStatus.Close();
+ }
+
+// --------------------------------------------------------------------------------------------
+inline void CProfilerEngineStatusChecker::ConstructL()
+ {
+ User::LeaveIfError(iEngineStatus.Attach(KEngineStatusPropertyCat, EProfilerEngineStatus));
+ CActiveScheduler::Add(this);
+
+ // check engine status, if not available set to idle
+ if(iEngineStatus.Get(iPrevStat) != KErrNone)
+ {
+ iPrevStat = MProfilerStatusObserver::EIdle;
+ }
+
+ // subscribe to P&S status property
+ iEngineStatus.Subscribe(iStatus);
+ SetActive();
+ }
+
+inline TInt CProfilerEngineStatusChecker::GetInitialState()
+ {
+ // check engine status, if not available set to idle
+ TInt err(iEngineStatus.Get(KEngineStatusPropertyCat, EProfilerEngineStatus, iPrevStat));
+ if(err != KErrNone)
+ {
+ iPrevStat = MProfilerStatusObserver::EIdle;
+ }
+ return iPrevStat;
+ }
+
+// --------------------------------------------------------------------------------------------
+inline void CProfilerEngineStatusChecker::RunL()
+ {
+ // resubscribe before processing new value to prevent missing updates
+ iEngineStatus.Subscribe(iStatus);
+ SetActive();
+
+ TInt stat(0);
+ if(iEngineStatus.Get(KEngineStatusPropertyCat, EProfilerEngineStatus, stat) == KErrNone)
+ {
+ // check if status one of error codes (< 0)
+ if(stat < KErrNone)
+ {
+ // some error occurred on engine side => set UI idle and show an error note
+ iObserver->HandleProfilerErrorL(stat);
+ }
+ else
+ {
+ if(iPrevStat != stat)
+ {
+ switch(stat)
+ {
+ case 0:
+ iObserver->HandleProfilerStatusChange(MProfilerStatusObserver::EIdle);
+ break;
+ case 1:
+ iObserver->HandleProfilerStatusChange(MProfilerStatusObserver::EInitializing);
+ break;
+ case 2:
+ iObserver->HandleProfilerStatusChange(MProfilerStatusObserver::ERunning);
+ break;
+ case 3:
+ iObserver->HandleProfilerStatusChange(MProfilerStatusObserver::EStopping);
+ break;
+ default:
+ iObserver->HandleProfilerErrorL(stat);
+ break;
+ }
+ iPrevStat = stat;
+ }
+ }
+ }
+ }
+
+// --------------------------------------------------------------------------------------------
+
+inline void CProfilerEngineStatusChecker::DoCancel()
+ {
+ iEngineStatus.Cancel();
+ }
+
+// --------------------------------------------------------------------------------------------
+inline void CProfilerEngineStatusChecker::SetObserver(MProfilerStatusObserver* aObserver)
+ {
+ iObserver = aObserver;
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/ProfilerGenericClassesCommon.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,55 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef PROFILERGENERICCLASSESCOMMON_H
+#define PROFILERGENERICCLASSESCOMMON_H
+
+ #include <e32cmn.h>
+
+/*
+ *
+ * Class TProfilerSampleBufStruct definition
+ *
+ */
+
+
+class TProfilerSampleBufStruct
+{
+public:
+ TUint32 iSampleRemainder;
+ TUint8 iDataStart;
+};
+
+/*
+ *
+ * Class TBapBuf definition
+ *
+ */
+
+class TBapBuf
+{
+public:
+ TPtr8* iDes;
+ TPtr8* iBufDes;
+ TInt iBufferSize;
+ TInt iDataSize;
+ TUint8* iBuffer;
+ TBapBuf* iNext;
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/ProfilerGenericClassesKrn.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,422 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef PROFILERGENERICCLASSESKRN_H
+#define PROFILERGENERICCLASSESKRN_H
+
+ #include <piprofiler/ProfilerGenericClassesCommon.h>
+ #include <piprofiler/ProfilerTraces.h>
+
+ #include <e32cmn.h>
+
+ #define PROFILER_KERNEL_MODE
+
+#ifdef PROFILER_KERNEL_MODE
+class DProfilerSampleBuffer;
+
+class DProfilerSampleStream
+ {
+public:
+ DProfilerSampleStream();
+ ~DProfilerSampleStream();
+
+ void InsertCurrentClient(DThread* aClient);
+ void AddSampleBuffer(TBapBuf* aBuffer,TRequestStatus* aStatus);
+ void ReleaseIfPending();
+
+ void AddSamples(DProfilerSampleBuffer& aBuffer, TInt aSamplerId);
+ TInt EndSampling(DProfilerSampleBuffer& aBuffer,TInt aSamplerId);
+
+ void PerformCopy(TUint8 aSamplerId,TUint8* aSrc,TPtr8* dst,TInt aOffset,TInt aAmount);
+
+private:
+ TBapBuf* iCurrentBuffer;
+ TRequestStatus* iPendingRequest;
+ DThread* iClient;
+ TInt iAddingSamples;
+ };
+
+class DProfilerSampleBuffer : public DBase
+ {
+ friend class DProfilerSampleStream;
+public:
+
+ enum ProfilerBufferStatus
+ {
+ BufferOk,
+ BufferCopyAsap,
+ BufferBeingCopied,
+ BufferFull,
+ BufferDataEnd
+ };
+
+ DProfilerSampleBuffer(TUint8* aBuffer, TUint8* aDblBuffer, TUint32 aSize);
+ ~DProfilerSampleBuffer();
+ TInt AddSample(TUint8* aSample, TUint32 aLength);
+ TUint32 GetBufferStatus();
+ void ClearBuffer();
+ void EndSampling();
+ void DataCopied();
+
+ TUint32 iBufferStatus;
+private:
+ TUint32 iBytesWritten;
+ TUint32 iDblBytesWritten;
+ TUint32 iDblBytesRead;
+
+ TUint32 iBufferDataSize;
+ TUint32 iBufferRealSize;
+
+ TProfilerSampleBufStruct* iDblBufStruct;
+ TProfilerSampleBufStruct* iBufStruct;
+ };
+
+#endif
+
+
+
+/*
+ *
+ * Abstract class CProfilerSamplerBase definition
+ *
+ */
+
+#ifdef PROFILER_KERNEL_MODE
+class DProfilerSamplerBase : public DBase
+ {
+public:
+ DProfilerSamplerBase();
+ virtual ~DProfilerSamplerBase();
+
+ virtual TInt Initialise() = 0;
+ virtual void Sample() = 0;
+ virtual TBool PostSampleNeeded() = 0;
+ virtual TInt PostSample() = 0;
+ virtual TInt EndSampling() = 0;
+
+ virtual TInt Reset(DProfilerSampleStream* aStream = 0, TUint32 aSyncOffset = 0) = 0;
+
+ virtual void SetEnabledFlag(TBool aFlag) = 0;
+ virtual TBool GetEnabledFlag() = 0;
+ virtual void SetOutputCombination(TInt aSettings) = 0;
+ virtual void SetSamplingPeriod(TInt aSettings) = 0;
+ virtual void SetAdditionalSettings(TInt aSettings) = 0;
+ virtual void SetAdditionalSettings2(TInt aSettings) = 0;
+ virtual void SetAdditionalSettings3(TInt aSettings) = 0;
+ virtual void SetAdditionalSettings4(TInt aSettings) = 0;
+
+ TInt iSamplerId;
+ TInt iOutputCombination;
+ TBool iEnabled;
+ };
+
+/*
+ *
+ * Template abstract class CProfilerGenericSampler definition
+ *
+ */
+
+// size parameter given defines the explicit buffer size in bytes for this sampler
+template <int BufferSize>
+class DProfilerGenericSampler : public DProfilerSamplerBase
+ {
+public:
+ DProfilerGenericSampler(TInt aSamplerId);
+ virtual ~DProfilerGenericSampler();
+
+ TInt Initialise();
+ virtual void Sample() = 0;
+ TBool PostSampleNeeded();
+ TInt PostSample();
+ TInt EndSampling();
+ virtual TInt Reset(DProfilerSampleStream* aStream = 0, TUint32 aSyncOffset = 0);
+
+
+ void SetEnabledFlag(TBool aFlag);
+ TBool GetEnabledFlag();
+ void SetOutputCombination(TInt aComb);
+ void SetSamplingPeriod(TInt aSettings);
+ void SetAdditionalSettings(TInt aSettings);
+ void SetAdditionalSettings2(TInt aSettings);
+ void SetAdditionalSettings3(TInt aSettings);
+ void SetAdditionalSettings4(TInt aSettings);
+
+ DProfilerSampleBuffer* iSampleBuffer;
+ DProfilerSampleStream* iStream;
+
+ // for right alignment
+ TUint8 iBuffer[BufferSize+4];
+ TUint8 iDblBuffer[BufferSize+4];
+
+ TInt iSamplingPeriod;
+ TInt iAdditionalSettings;
+ TInt iAdditionalSettings2;
+ TInt iAdditionalSettings3;
+ TInt iAdditionalSettings4;
+ };
+
+/*
+ *
+ * Template abstract class CProfilerGenericSampler implementation
+ *
+ */
+
+template <int BufferSize>
+DProfilerGenericSampler<BufferSize>::DProfilerGenericSampler(TInt aSamplerId)
+ {
+ iSamplerId = aSamplerId;
+ iEnabled = false;
+ iSampleBuffer = 0;
+ iAdditionalSettings = 0;
+ iAdditionalSettings2 = 0;
+ iAdditionalSettings3 = 0;
+ iAdditionalSettings4 = 0;
+ iStream = 0;
+ Initialise();
+ }
+
+template <int BufferSize>
+DProfilerGenericSampler<BufferSize>::~DProfilerGenericSampler()
+ {
+ LOGSTRING2("CProfilerGenericSampler<%d>::CProfilerGenericSampler",BufferSize);
+
+ if(iSampleBuffer != 0)
+ delete iSampleBuffer;
+
+ }
+
+template <int BufferSize>
+TInt DProfilerGenericSampler<BufferSize>::Initialise()
+ {
+ LOGSTRING2("CProfilerGenericSampler<%d>::Initialise - chunk option",BufferSize);
+
+ // stream is not used in chunk mode
+ iStream = 0;
+
+ // create the sample buffer object with the buffers
+ if(iSampleBuffer == 0)
+ {
+ iSampleBuffer = new DProfilerSampleBuffer(iBuffer,iDblBuffer,BufferSize);
+ }
+ else
+ {
+ LOGSTRING2("CProfilerGenericSampler<%d>::Initialise - ERROR 1",BufferSize);
+ }
+
+ return KErrNone;
+ }
+
+
+
+template <int BufferSize>
+TInt DProfilerGenericSampler<BufferSize>::Reset(DProfilerSampleStream* aStream, TUint32 aSyncOffset)
+ {
+ LOGSTRING4("CProfilerGenericSampler<%d>::Reset %d, sync offset %d",BufferSize,aStream,aSyncOffset);
+ // reset the sample buffer and resolve the chunk again
+
+ // CURRENT VERSION SUPPORTS ONLY STREAM MODE!
+ LOGSTRING2("CProfilerGenericSampler<%d>::Reset - stream option",BufferSize);
+
+ // initialise the sampler with the stream option
+ iStream = aStream;
+
+ // clear the sample buffer
+ if(iSampleBuffer != 0)
+ {
+ iSampleBuffer->ClearBuffer();
+ }
+ else
+ {
+ LOGSTRING2("CProfilerGenericSampler<%d>::Initialise - ERROR no buffer",BufferSize);
+ }
+
+ return KErrNone;
+
+ }
+
+template <int BufferSize>
+TBool DProfilerGenericSampler<BufferSize>::PostSampleNeeded()
+ {
+ LOGSTRING4("CProfilerGenericSampler<%d>::PostSampleNeeded - ID %d, state %d",iSamplerId,BufferSize,iSampleBuffer->GetBufferStatus());
+
+ TUint32 status = iSampleBuffer->iBufferStatus;
+
+ if(status == DProfilerSampleBuffer::BufferCopyAsap || status == DProfilerSampleBuffer::BufferFull)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+
+template <int BufferSize>
+TInt DProfilerGenericSampler<BufferSize>::PostSample()
+ {
+ LOGSTRING4("CProfilerGenericSampler<%d>::PostSample - ID %d, state %d",iSamplerId,BufferSize,iSampleBuffer->GetBufferStatus());
+
+ TUint32 status = iSampleBuffer->iBufferStatus;
+
+ if(status == DProfilerSampleBuffer::BufferCopyAsap || status == DProfilerSampleBuffer::BufferFull)
+ {
+ // write data to the stream
+ iStream->AddSamples(*iSampleBuffer,iSamplerId);
+ }
+
+ return KErrNone;
+ }
+
+template <int BufferSize>
+TInt DProfilerGenericSampler<BufferSize>::EndSampling()
+ {
+ LOGSTRING3("CProfilerGenericSampler<%d>::EndSampling, ID %d",BufferSize,iSamplerId);
+
+ // only if write to stream option is selected
+ if(iStream->EndSampling(*iSampleBuffer,iSamplerId) == 0)
+ {
+ return KErrNone;
+ }
+ else
+ {
+ // there is still data to copy
+ return KErrNotReady;
+ }
+ }
+
+template <int BufferSize>
+void DProfilerGenericSampler<BufferSize>::SetEnabledFlag(TBool aFlag)
+ {
+ LOGSTRING2("CProfilerGenericSampler<%d>::SetEnabledFlag",BufferSize);
+ iEnabled = aFlag;
+ }
+
+template <int BufferSize>
+TBool DProfilerGenericSampler<BufferSize>::GetEnabledFlag()
+ {
+ LOGSTRING2("CProfilerGenericSampler<%d>::GetEnabledFlag",BufferSize);
+ return iEnabled;
+ }
+
+template <int BufferSize>
+void DProfilerGenericSampler<BufferSize>::SetOutputCombination(TInt aComb)
+ {
+ LOGSTRING2("CProfilerGenericSampler<%d>::SetOutputCombination",BufferSize);
+ iOutputCombination = aComb;
+ }
+
+template <int BufferSize>
+void DProfilerGenericSampler<BufferSize>::SetAdditionalSettings(TInt aSettings)
+ {
+ LOGSTRING3("CProfilerGenericSampler<%d>::SetAdditionalSettings to 0x%x",BufferSize,aSettings);
+ iAdditionalSettings = aSettings;
+ }
+
+template <int BufferSize>
+void DProfilerGenericSampler<BufferSize>::SetAdditionalSettings2(TInt aSettings)
+ {
+ LOGSTRING3("CProfilerGenericSampler<%d>::SetAdditionalSettings2 to 0x%x",BufferSize,aSettings);
+ iAdditionalSettings2 = aSettings;
+ }
+
+template <int BufferSize>
+void DProfilerGenericSampler<BufferSize>::SetAdditionalSettings3(TInt aSettings)
+ {
+ LOGSTRING3("CProfilerGenericSampler<%d>::SetAdditionalSettings3 to 0x%x",BufferSize,aSettings);
+ iAdditionalSettings3 = aSettings;
+ }
+
+template <int BufferSize>
+void DProfilerGenericSampler<BufferSize>::SetAdditionalSettings4(TInt aSettings)
+ {
+ LOGSTRING3("CProfilerGenericSampler<%d>::SetAdditionalSettings4 to 0x%x",BufferSize,aSettings);
+ iAdditionalSettings4 = aSettings;
+ }
+
+template <int BufferSize>
+void DProfilerGenericSampler<BufferSize>::SetSamplingPeriod(TInt aSettings)
+ {
+ LOGSTRING3("CProfilerGenericSampler<%d>::SetSamplingPeriod to 0x%x",BufferSize,aSettings);
+ iSamplingPeriod = aSettings;
+ }
+
+/*
+ *
+ * Just a test class that is derived from CProfilerGenericSampler
+ *
+ */
+
+template <int BufferSize>
+class DProfilerExampleSampler : public DProfilerGenericSampler<BufferSize>
+ {
+public:
+ TUint32 iSampleNumber;
+
+ DProfilerExampleSampler(TInt aSamplerId);
+ ~DProfilerExampleSampler();
+
+ void Sample();
+ void Sample(TInt aCount, TInt aLastPc);
+ };
+
+
+/*
+ *
+ * Just a test class that is derived from CProfilerGenericSampler
+ *
+ */
+
+template <int BufferSize>
+DProfilerExampleSampler<BufferSize>::DProfilerExampleSampler(TInt aSamplerId) :
+ DProfilerGenericSampler<BufferSize>(aSamplerId)
+ {
+ iSampleNumber = 0;
+ LOGSTRING2("CProfilerExampleSampler<%d>::CProfilerExampleSampler",BufferSize);
+ }
+
+template <int BufferSize>
+void DProfilerExampleSampler<BufferSize>::Sample()
+ {
+ LOGSTRING2("CProfilerExampleSampler<%d>::Sample",BufferSize);
+ TBuf8<20>* testiBuf = new TBuf8<20>;
+
+ testiBuf->AppendNum((TInt)iSampleNumber);
+ iSampleNumber++;
+
+ this->iSampleBuffer->AddSample((TUint8*)testiBuf->Ptr(),testiBuf->Length());
+ delete testiBuf;
+ return;
+ }
+
+template <int BufferSize>
+void DProfilerExampleSampler<BufferSize>::Sample(TInt aCount, TInt aLastPc)
+ {
+ return;
+ }
+
+template <int BufferSize>
+DProfilerExampleSampler<BufferSize>::~DProfilerExampleSampler()
+ {
+ LOGSTRING2("CProfilerExampleSampler<%d>::~CProfilerExampleSampler",BufferSize);
+ }
+
+#include <piprofiler/ProfilerGenericClassesKrn.inl>
+
+#endif
+
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/ProfilerGenericClassesKrn.inl Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,530 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <kern_priv.h>
+
+#include <piprofiler/ProfilerGenericClassesKrn.h>
+
+
+/*
+ *
+ * Class CProfilerSamplerBase implementation
+ *
+ */
+
+inline DProfilerSamplerBase::DProfilerSamplerBase()
+ {
+
+ }
+
+inline DProfilerSamplerBase::~DProfilerSamplerBase()
+ {
+
+ }
+
+/*
+ *
+ * Class CProfilerSampleBuffer implementation
+ *
+ */
+
+inline DProfilerSampleBuffer::DProfilerSampleBuffer(TUint8* aBuffer,
+ TUint8* aDblBuffer,
+ TUint32 aBufferSize )
+ {
+ LOGSTRING3("CProfilerSampleBuffer::CProfilerSampleBuffer AtFirst: b:0x%x db:0x%x",aBuffer,aDblBuffer);
+
+ // make sure the alignment is right
+ if((((TUint32)aBuffer) %4) != 0)
+ aBuffer += (4-(((TUint32)aBuffer)%4));
+ if((((TUint32)aDblBuffer) %4) != 0)
+ aDblBuffer += (4-(((TUint32)aDblBuffer)%4));
+
+ LOGSTRING3("CProfilerSampleBuffer::CProfilerSampleBuffer b:0x%x db:0x%x",aBuffer,aDblBuffer);
+
+ iBufStruct = (TProfilerSampleBufStruct*)aBuffer;
+ iDblBufStruct = (TProfilerSampleBufStruct*)aDblBuffer;
+
+ LOGSTRING3("CProfilerSampleBuffer::CProfilerSampleBuffer bufStruct rem:0x%x dbuStruct rem:0x%x",
+ &iBufStruct->iSampleRemainder,&iDblBufStruct->iSampleRemainder);
+
+ iBufferDataSize = aBufferSize-4;
+ iBufferRealSize = aBufferSize;
+
+ ClearBuffer();
+ }
+
+inline DProfilerSampleBuffer::~DProfilerSampleBuffer()
+ {
+
+ }
+
+inline TInt DProfilerSampleBuffer::AddSample(TUint8* aSample, TUint32 aLength)
+ {
+ TUint32 bytesTotal;
+
+ // check whether the buffer status is
+ switch (iBufferStatus)
+ {
+ case DProfilerSampleBuffer::BufferOk:
+ // add the data normally to the buffer
+ bytesTotal = iBytesWritten+aLength;
+
+ if(bytesTotal < iBufferDataSize)
+ {
+ memcpy((&(iBufStruct->iDataStart))+iBytesWritten,aSample,aLength);
+ iBytesWritten+=aLength;
+ return 0;
+ }
+ else
+ {
+
+ // the sample does not fit to the buffer
+ // first copy as much data as we can fit to the first buffer
+ TUint32 fitsToBuffer = iBufferDataSize-iBytesWritten;
+ TUint32 remaining = aLength-fitsToBuffer;
+
+ memcpy((&(iBufStruct->iDataStart))+iBytesWritten,aSample,fitsToBuffer);
+ iBytesWritten = iBufferDataSize;
+
+ // ->switch to the double buffer
+ iBufferStatus = DProfilerSampleBuffer::BufferCopyAsap;
+
+ TProfilerSampleBufStruct* tmpPtr = iBufStruct;
+ iBufStruct = iDblBufStruct;
+ iDblBufStruct = tmpPtr;
+
+ iDblBytesWritten = iBytesWritten;
+
+ // and this is the remainder of a sample
+ // that will be copied to the new buffer
+ // just in a while
+ iBufStruct->iSampleRemainder = remaining;
+
+ // now that the buffers have been switched
+ // add the rest of the sample to the buffer
+ aSample+=fitsToBuffer;
+
+ // there should be room - in case the single sample
+ // is smaller than the whole buffer! so we don't
+ // bother to check
+
+ memcpy((&(iBufStruct->iDataStart)),aSample,remaining);
+ iBytesWritten = remaining;
+ return 0;
+ }
+
+ case DProfilerSampleBuffer::BufferCopyAsap:
+
+ // no difference to the BufferOk case
+ // unless the double buffer gets filled
+ // before the data has been copied
+ // add the data normally to the buffer
+ bytesTotal = iBytesWritten+aLength;
+
+ if(bytesTotal < iBufferDataSize)
+ {
+ memcpy((&(iBufStruct->iDataStart))+iBytesWritten,aSample,aLength);
+ iBytesWritten+=aLength;
+ return 0;
+ }
+ else
+ {
+ // the double buffer is now also full - there is no
+ // place to put the data -> we have to waste it!
+ // this is an indication of a too small buffer size
+ iBufferStatus = DProfilerSampleBuffer::BufferFull;
+ LOGSTRING("DProfilerSampleBuffer::AddSample - double buffer full1!!");
+ return -1;
+ }
+
+ case DProfilerSampleBuffer::BufferBeingCopied:
+
+ // no difference to the BufferCopyAsap case
+ bytesTotal = iBytesWritten+aLength;
+
+ if(bytesTotal < iBufferDataSize)
+ {
+ memcpy((&(iBufStruct->iDataStart))+iBytesWritten,aSample,aLength);
+ iBytesWritten+=aLength;
+ return 0;
+ }
+ else
+ {
+ // the double buffer is now also full - there is no
+ // place to put the data -> we have to waste it!
+ // this is an indication of a too small buffer size
+ LOGSTRING("DProfilerSampleBuffer::AddSample - double buffer full2!!");
+
+ // don't change the state to CProfilerSampleBuffer::BufferFull, since it is
+ // already being copied
+ return -1;
+ }
+
+ case DProfilerSampleBuffer::BufferFull:
+ // the buffer is still full, there is noting we can do
+ // about it -> return
+ LOGSTRING("DProfilerSampleBuffer::AddSample - double buffer full3!!");
+ return -1;
+
+ default:
+ LOGSTRING("DProfilerSampleBuffer::AddSample - wrong switch!!");
+ return -1;
+ }
+ }
+
+inline void DProfilerSampleBuffer::EndSampling()
+ {
+ LOGSTRING("DProfilerSampleBuffer::EndSampling");
+ // this will switch to the dbl buffer even though
+ // the buffer is not full, so that data can be copied
+
+ // during this operation, no other buffer
+ // operations are allowed
+
+ // ensure that the normal buffer is in use and that the
+ // buffer is in normal state ( this procedure is performed only once )
+ if(iBufferStatus == DProfilerSampleBuffer::BufferOk)
+ {
+ // ->switch to the double buffer
+ LOGSTRING("DProfilerSampleBuffer::EndSampling - switching to double buffer");
+ iBufferStatus = DProfilerSampleBuffer::BufferCopyAsap;
+
+ TProfilerSampleBufStruct* tmpPtr = iBufStruct;
+ iBufStruct = iDblBufStruct;
+ iDblBufStruct = tmpPtr;
+
+ iDblBytesWritten = iBytesWritten;
+
+ // there is no new sample so the remainder is
+ // zero, (this shouldn't be used anyway)
+ iBufStruct->iSampleRemainder = 0;
+ }
+ }
+
+inline TUint32 DProfilerSampleBuffer::GetBufferStatus()
+ {
+ return iBufferStatus;
+ }
+
+inline void DProfilerSampleBuffer::ClearBuffer()
+ {
+ LOGSTRING2("CProfilerSampleBuffer::ClearBuffer - %d",iBufferDataSize);
+
+ // the buffers are of same size
+ TUint8* ptr1 = (TUint8*)&(iBufStruct->iDataStart);
+ TUint8* ptr2 = (TUint8*)&(iDblBufStruct->iDataStart);
+
+ for(TUint32 i=0;i<iBufferDataSize;i++)
+ {
+ ptr1[i] = 0;
+ ptr2[i] = 0;
+ }
+
+
+ iBufStruct->iSampleRemainder = 0;
+ iDblBufStruct->iSampleRemainder = 0;
+
+ // written the dblBufStruct
+ iBytesWritten = 0;
+ iDblBytesWritten = 0;
+ iDblBytesRead = 0;
+
+ iBufferStatus = DProfilerSampleBuffer::BufferOk;
+ }
+
+inline void DProfilerSampleBuffer::DataCopied()
+ {
+ iDblBytesRead = 0;
+ iDblBytesWritten = 0;
+ iBufferStatus = DProfilerSampleBuffer::BufferOk;
+ }
+
+/*
+ *
+ * Class DProfilerSampleStream implementation
+ *
+ */
+
+inline DProfilerSampleStream::DProfilerSampleStream()
+ {
+ LOGSTRING("DProfilerSampleStream::DProfilerSampleStream");
+
+ iCurrentBuffer = 0;
+ iPendingRequest = 0;
+ iAddingSamples = 0;
+ iClient = 0;
+ }
+
+inline DProfilerSampleStream::~DProfilerSampleStream()
+ {
+ LOGSTRING("DProfilerSampleStream::~DProfilerSampleStream");
+ }
+
+inline void DProfilerSampleStream::InsertCurrentClient(DThread* aClient)
+ {
+ iClient = aClient;
+ LOGSTRING2("DProfilerSampleStream::InsertCurrentClient - iClient is 0x%x",iClient);
+ }
+
+
+inline void DProfilerSampleStream::AddSampleBuffer(TBapBuf* aBuffer,TRequestStatus* aStatus)
+ {
+ if(iCurrentBuffer != 0 || iPendingRequest != 0)
+ {
+ LOGSTRING("DProfilerSampleStream::AddSampleBuffer - ERROR 1");
+ return;
+ }
+
+ LOGSTRING3("DProfilerSampleStream::AddSampleBuffer - OK 0x%x,0x%x",aBuffer,aStatus);
+ iCurrentBuffer = aBuffer;
+ iPendingRequest = aStatus;
+
+ LOGSTRING2("DProfilerSampleStream::AddSampleBuffer - Current Client is 0x%x",iClient);
+ }
+
+
+inline void DProfilerSampleStream::ReleaseIfPending()
+ {
+ LOGSTRING("DProfilerSampleStream::ReleaseIfPending - entry");
+
+ if(iCurrentBuffer != 0 && iPendingRequest != 0 && iClient != 0)
+ {
+ LOGSTRING("DProfilerSampleStream::ReleaseIfPending - release buffer");
+
+ LOGSTRING2("DProfilerSampleStream::AddSamples - completing request 0x%x",iPendingRequest);
+ Kern::RequestComplete(iClient,iPendingRequest,KErrNone);
+
+ iPendingRequest = 0;
+ iCurrentBuffer = 0;
+ }
+
+ LOGSTRING("DProfilerSampleStream::ReleaseIfPending - exit");
+ }
+
+inline void DProfilerSampleStream::AddSamples(DProfilerSampleBuffer& aBuffer, TInt aSamplerId)
+ {
+ LOGSTRING3("DProfilerSampleStream::AddSamples - entry ID: %d, currentbuffer: 0x%x", aSamplerId,iCurrentBuffer);
+ if(iCurrentBuffer != 0)
+ {
+ // the following will perform simple mutual exclusion
+ iAddingSamples++;
+ if(iAddingSamples > 1)
+ {
+ // there is someone else adding samples to the buffer
+ LOGSTRING("DProfilerSampleStream::AddSamples - mutex in use");
+ iAddingSamples--;
+ return;
+ }
+
+ LOGSTRING("DProfilerSampleStream::AddSamples - reading TBapBuf");
+
+ // use a copy of the client TBapBuf structure during processing
+ TBapBuf realBuf;
+ TPtr8 ptr((TUint8*)&realBuf,(TInt)sizeof(TBapBuf));
+
+ Kern::ThreadRawRead(iClient,(TAny*)(iCurrentBuffer),(TAny*)&realBuf,sizeof(TBapBuf));
+
+ ptr.SetLength(sizeof(TBapBuf));
+
+ LOGSTRING4("DProfilerSampleStream::AddSamples - read %d bytes from 0x%x of thread 0x%x",ptr.Size(),iCurrentBuffer,iClient);
+
+ LOGSTRING5("DProfilerSampleStream::AddSamples - current buffer 0x%x -> b:0x%x s:%d d:%d",
+ &realBuf,
+ realBuf.iBuffer,
+ realBuf.iBufferSize,
+ realBuf.iDataSize);
+
+ // get the address of the source buffer data
+ TUint8* src = (TUint8*)&(aBuffer.iDblBufStruct->iDataStart);
+ src += aBuffer.iDblBytesRead;
+
+ // the amount of data to copy is the 4 header bytes +
+ // the remaining data in the buffer
+ TInt amount = aBuffer.iDblBytesWritten-aBuffer.iDblBytesRead;
+
+ TUint8* dst = realBuf.iBuffer;
+
+ LOGSTRING4("DProfilerSampleStream::AddSamples - s:0x%x d:0x%x a:%d",src,dst,amount);
+
+ if(realBuf.iDataSize == 0)
+ {
+ LOGSTRING("DProfilerSampleStream::AddSamples - case 1");
+
+ // the buffer is empty
+ if(realBuf.iBufferSize >= (amount+4))
+ {
+ LOGSTRING("DProfilerSampleStream::AddSamples - case 1.1");
+
+ // the source buffer is smaller or of equal size than the amount of output data
+ PerformCopy((TUint8)aSamplerId,src,realBuf.iBufDes,0,amount);
+ realBuf.iDataSize += amount+4;
+ // the rest of the source buffer was copied at once, so signal the buffer
+ aBuffer.DataCopied();
+ }
+ else
+ {
+ LOGSTRING("DProfilerSampleStream::AddSamples - case 1.2");
+
+ // only a part of the source buffer will fit to the client side buffer
+ amount = realBuf.iBufferSize-4;
+ PerformCopy((TUint8)aSamplerId,src,realBuf.iBufDes,0,amount);
+ realBuf.iDataSize += amount+4;
+ // add the amount of bytes read to the source buffer
+ aBuffer.iDblBytesRead+=amount;
+ }
+ }
+ else
+ {
+ LOGSTRING("DProfilerSampleStream::AddSamples - case 2");
+
+ // there is data in the client buffer
+ dst += realBuf.iDataSize;
+ TInt remainingSpace = realBuf.iBufferSize-realBuf.iDataSize;
+
+ if( remainingSpace >= (amount+4) )
+ {
+ LOGSTRING("DProfilerSampleStream::AddSamples - case 2.1");
+
+ // the source buffer is smaller or of equal size than the amount of output data
+ PerformCopy((TUint8)aSamplerId,src,realBuf.iBufDes,realBuf.iDataSize,amount);
+ realBuf.iDataSize += (amount+4);
+ // the rest of the source buffer was copied at once, so signal the buffer
+ aBuffer.DataCopied();
+ }
+ else
+ {
+ LOGSTRING("DProfilerSampleStream::AddSamples - case 2.2");
+
+ // only a part of the source buffer will fit to the client side buffer
+ if(remainingSpace >= 12)
+ {
+ LOGSTRING("DProfilerSampleStream::AddSamples - case 2.3");
+
+ amount = remainingSpace-4;
+ // there are at least 8 bytes left for data, write it
+ PerformCopy((TUint8)aSamplerId,src,realBuf.iBufDes,realBuf.iDataSize,amount);
+ realBuf.iDataSize += (amount+4);
+ // add the amount of bytes read to the source buffer
+ aBuffer.iDblBytesRead+=amount;
+ }
+ }
+ }
+
+ // copy the data in the modified TBapBuf structure back to the client
+ LOGSTRING("DProfilerSampleStream::AddSamples - writing TBapBuf");
+
+ Kern::ThreadDesWrite(iClient,(TAny*)(realBuf.iDes),ptr,0,KChunkShiftBy0,iClient);
+
+ // if the client side buffer is full or nearly full, signal the client
+ LOGSTRING("DProfilerSampleStream::AddSamples - data copied");
+
+ if(realBuf.iBufferSize-realBuf.iDataSize < 12)
+ {
+ LOGSTRING("DProfilerSampleStream::AddSamples - release buffer");
+
+ LOGSTRING2("DProfilerSampleStream::AddSamples - completing request 0x%x",iPendingRequest);
+
+ Kern::RequestComplete(iClient,iPendingRequest,KErrNone);
+
+ iPendingRequest = 0;
+ iCurrentBuffer = 0;
+ //iClient = 0;
+ }
+
+ // free the lock
+ iAddingSamples--;
+ }
+ LOGSTRING("DProfilerSampleStream::AddSamples - exit");
+ }
+
+
+
+inline TInt DProfilerSampleStream::EndSampling(DProfilerSampleBuffer& aBuffer,TInt aSamplerId)
+ {
+ LOGSTRING2("DProfilerSampleStream::EndSampling, sampler ID: %d",aSamplerId);
+
+ // switch the buffer to double buffer
+ // even though it would not be full yet
+ // the switch is done only once / end sampling procedure
+ // (Only with BufferOk status)
+ aBuffer.EndSampling();
+
+ LOGSTRING2("DProfilerSampleStream::EndSampling, iClient: 0x%x",iClient);
+
+ if(aBuffer.iBufferStatus != DProfilerSampleBuffer::BufferDataEnd)
+ {
+ // add these final samples to the client buffer
+ AddSamples(aBuffer,aSamplerId);
+
+ // if all data was copied to the buffer, the buffer status is now BufferOk
+
+ if(aBuffer.iBufferStatus != DProfilerSampleBuffer::BufferOk)
+ {
+ LOGSTRING("DProfilerSampleStream::EndSampling - more data to copy");
+ // there is still more data to copy, the pending request should have been
+ // completed in AddSamples(), because the client buffer got filled
+ return 1;
+ }
+ else
+ {
+ // buffer status was changed to BufferOk in AddSamples() -
+ // this means all data from it could be copied
+ // now we have to change the status of the buffer to BufferDataEnd, so
+ // we know that the particular buffer has no more data to copy
+ LOGSTRING("DProfilerSampleStream::EndSampling - switch to BufferDataEnd");
+ aBuffer.iBufferStatus = DProfilerSampleBuffer::BufferDataEnd;
+ }
+ }
+
+ // the buffer was completely emptied to the client buffer, or there was no
+ // data to copy to the client side
+ LOGSTRING("DProfilerSampleStream::EndSampling - no more data to copy");
+
+ return 0;
+ }
+
+inline void DProfilerSampleStream::PerformCopy(TUint8 aSamplerId,TUint8* aSrc,TPtr8* aDst,TInt aOffset,TInt aAmount)
+ {
+ LOGSTRING2("DProfilerSampleStream::PerformCopy for sampler ID: %d",aSamplerId);
+ LOGSTRING5("DProfilerSampleStream::PerformCopy - 0x%x -> 0x%x - %d - offset: %d",aSrc, aDst, aAmount, aOffset);
+ TUint32 header;
+ header = aAmount & 0x00ffffff;
+ header += (aSamplerId << 24);
+ TPtr8 ptr((TUint8*)&header,4);
+ ptr.SetLength(4);
+
+ LOGSTRING2("DProfilerSampleStream::PerformCopy - start header copy HDR = 0x%x",header);
+
+ // write the header
+ Kern::ThreadDesWrite(iClient,(TAny*)aDst,ptr,aOffset,KChunkShiftBy0);
+
+ LOGSTRING2("DProfilerSampleStream::PerformCopy - copied header %d bytes",ptr.Size());
+ aOffset+=4;
+
+ LOGSTRING("DProfilerSampleStream::PerformCopy - start copy");
+ // write the data
+ ptr.Set(aSrc,aAmount,aAmount);
+ ptr.SetLength(aAmount);
+
+ Kern::ThreadDesWrite(iClient,(TAny*)aDst,ptr,aOffset,KChunkShiftBy0);
+
+
+ LOGSTRING2("DProfilerSampleStream::PerformCopy - copied data %d bytes",ptr.Size());
+
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/ProfilerGenericClassesUsr.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,121 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef PROFILERGENERICCLASSESUSR_H
+#define PROFILERGENERICCLASSESUSR_H
+
+#include <piprofiler/ProfilerConfig.h>
+#include <piprofiler/ProfilerVersion.h>
+#include <piprofiler/ProfilerGenericClassesCommon.h>
+#include <piprofiler/PluginSampler.h>
+#include <piprofiler/WriterPluginInterface.h>
+
+#include <e32cmn.h>
+#include <e32std.h>
+#include <f32file.h>
+
+
+/*
+ *
+ * Class MProfilerBufferHandlerObserver definition
+ *
+ */
+class MProfilerBufferHandlerObserver
+ {
+public:
+ virtual TBapBuf* GetNextFreeBuffer() = 0;
+ virtual void AddToFilledBuffers(TBapBuf* aFilledBuffer) = 0;
+ };
+
+/*
+ *
+ * Class CProfilerBufferHandler definition
+ *
+ */
+// forward declarations
+class CProfilerSampleStream;
+
+class CProfilerBufferHandler : public CActive
+ {
+public:
+ static CProfilerBufferHandler* CProfilerBufferHandler::NewL(CProfilerSampleStream& aStream, RPluginSampler& aSampler);
+ CProfilerBufferHandler(CProfilerSampleStream& aStream, RPluginSampler& aSampler);
+ ~CProfilerBufferHandler();
+
+ void ConstructL();
+
+ // for plugins to start receiving trace data
+ void StartReceivingData();
+private:
+ void RunL();
+ TInt RunError(TInt aError);
+ void DoCancel();
+ void HandleEndOfStream();
+public:
+ TInt iFinished;
+private:
+ RPluginSampler& iSampler;
+ TBapBuf* iBufferInProcess;
+ TBool iEndOfStreamDetected;
+
+ CProfilerSampleStream& iObserver;
+ };
+
+/*
+ *
+ * Class CProfilerSampleStream definition
+ *
+ */
+class CWriterPluginInterface;
+
+class CProfilerSampleStream : public CBase, MProfilerBufferHandlerObserver
+{
+public:
+ static CProfilerSampleStream* CProfilerSampleStream::NewL(TInt aBufSize);
+ ~CProfilerSampleStream();
+
+ void ConstructL();
+
+ void Finalise();
+ void EmptyBuffers();
+ inline void AddToFreeBuffers(TBapBuf* freeBuffer);
+ void SetWriter(CWriterPluginInterface& aWriter);
+
+ // from MProfilerBufferHandlerObserver
+ TBapBuf* GetNextFreeBuffer();
+ void AddToFilledBuffers(TBapBuf* aFilledBuffer);
+ inline TBapBuf* GetNextFilledBuffer();
+ void ResetBuffers();
+ void InitialiseBuffers();
+ inline void NotifyWriter();
+private:
+ CProfilerSampleStream(TInt aBufSize);
+
+
+public:
+ TInt iFinished;
+ CWriterPluginInterface* iWriter;
+private:
+ TInt iBufferSize;
+ TBapBuf* iFreeBuffers;
+ TBapBuf* iFilledBuffers;
+};
+
+#include <piprofiler/ProfilerGenericClassesUsr.inl>
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/ProfilerGenericClassesUsr.inl Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,498 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <f32file.h>
+#include <e32svr.h>
+
+#include <piprofiler/ProfilerTraces.h>
+
+// constants
+const TInt KInitialFreeBufferAmount = 4;
+
+/*
+ *
+ * Class CProfilerBufferHandler implementation
+ *
+ */
+inline CProfilerBufferHandler* CProfilerBufferHandler::NewL(CProfilerSampleStream& aStream, RPluginSampler& aSampler)
+ {
+ LOGTEXT(_L("CProfilerBufferHandler::NewL - entry"));
+ CProfilerBufferHandler* self = new(ELeave) CProfilerBufferHandler(aStream, aSampler);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+inline CProfilerBufferHandler::CProfilerBufferHandler(CProfilerSampleStream& aStream, RPluginSampler& aSampler)
+ : CActive(EPriorityStandard),
+ iSampler(aSampler),
+ iObserver(aStream)
+ {
+ }
+
+inline CProfilerBufferHandler::~CProfilerBufferHandler()
+ {
+ LOGTEXT(_L("CProfilerBufferHandler::~CProfilerBufferHandler() - entry"));
+ }
+
+inline void CProfilerBufferHandler::ConstructL()
+ {
+ LOGTEXT(_L("CProfilerBufferHandler::ConstructL - entry"));
+ iBufferInProcess = 0;
+ iEndOfStreamDetected = false;
+
+ iFinished = 0;
+ // add the buffer handler to the active scheduler
+ CActiveScheduler::Add(this);
+ }
+
+inline void CProfilerBufferHandler::StartReceivingData()
+ {
+ LOGTEXT(_L("CProfilerBufferHandler::StartReceivingData - entry"));
+
+ iEndOfStreamDetected = false;
+ // this method initiates receiving data from the sampler
+ iBufferInProcess = iObserver.GetNextFreeBuffer();
+
+ LOGSTRING5("CProfilerBufferHandler::StartReceivingData - 0x%x -> b:0x%x s:%d d:%d",
+ iBufferInProcess,
+ iBufferInProcess->iBuffer,
+ iBufferInProcess->iBufferSize,
+ iBufferInProcess->iDataSize);
+
+ iSampler.FillThisStreamBuffer(iBufferInProcess,iStatus);
+
+ LOGTEXT(_L("CProfilerBufferHandler::StartReceivingData - SetActive"));
+ SetActive();
+
+ LOGTEXT(_L("CProfilerBufferHandler::StartReceivingData - exit"));
+ }
+
+inline TInt CProfilerBufferHandler::RunError(TInt aError)
+ {
+ // handle the error case by stopping the trace
+ HandleEndOfStream();
+ return aError;
+ }
+
+inline void CProfilerBufferHandler::HandleEndOfStream()
+ {
+ LOGTEXT(_L("CProfilerBufferHandler::RunError - entry"));
+ // Cancel has been called, the stream should be about to end now,
+ // we will wait for the rest of the buffers to be filled synchronously
+ // the end of the stream will be indicated through an empty buffer
+ // at first, complete the ongoing request
+ if(iStatus == KRequestPending && iBufferInProcess != 0)
+ {
+ LOGTEXT(_L("CProfilerBufferHandler::DoCancel - case 1"));
+
+ // wait for the buffer to be filled synchronously
+ User::WaitForRequest(iStatus);
+
+ // add the received buffer to the list of filled buffers
+ iObserver.AddToFilledBuffers(iBufferInProcess);
+ // continue writing to output
+ iObserver.NotifyWriter();
+
+ if(iBufferInProcess->iDataSize == 0)
+ {
+ // a buffer with size 0 was received
+ LOGTEXT(_L("CProfilerBufferHandler::DoCancel - case 1.1"));
+ iEndOfStreamDetected = true;
+ }
+
+ // there will be no more asynchronous requests
+ iBufferInProcess = 0;
+ }
+ else if (iBufferInProcess != 0)
+ {
+ LOGTEXT(_L("CProfilerBufferHandler::DoCancel - case 2"));
+
+ // add the buffer into filled, i.e. ready-to-write buffers
+ iObserver.AddToFilledBuffers(iBufferInProcess);
+ iObserver.NotifyWriter();
+
+ if(iBufferInProcess->iDataSize == 0)
+ {
+ // a buffer with size 0 was received
+ LOGTEXT(_L("CProfilerBufferHandler::DoCancel - case 2.1"));
+ iEndOfStreamDetected = true;
+ }
+ // there will be no more asynchronous requests
+ iBufferInProcess = 0;
+ }
+
+ // then, continue until end of stream has been reached
+ while(iEndOfStreamDetected == false)
+ {
+ // the end of stream has not yet been detected, so get more
+ // buffers from the sampler, until we get an empty one
+
+ if(iStatus == KRequestPending)
+ {
+ LOGTEXT(_L("CProfilerBufferHandler::DoCancel - ERROR 1"));
+ }
+
+ LOGTEXT(_L("CProfilerBufferHandler::DoCancel - case 3"));
+
+ TBapBuf* nextFree = iObserver.GetNextFreeBuffer();
+ iSampler.FillThisStreamBuffer(nextFree,iStatus);
+ // wait for the buffer to be filled synchronously
+ User::WaitForRequest(iStatus);
+
+ // call the writer plugin to write data to output
+ iObserver.AddToFilledBuffers(nextFree);
+ iObserver.NotifyWriter();
+
+ // check if end-of-data message (i.e. data size is 0 sized) received
+ if(nextFree->iDataSize == 0)
+ {
+ LOGTEXT(_L("CProfilerBufferHandler::DoCancel - case 3.1"));
+ // a buffer with size 0 was received
+ iEndOfStreamDetected = true;
+ nextFree = 0;
+ }
+ }
+ }
+
+inline void CProfilerBufferHandler::RunL()
+ {
+ LOGTEXT(_L("CProfilerBufferHandler::RunL - entry"));
+
+ // is called by the active scheduler
+ // when a buffer has been received
+
+ // buffer with dataSize 0 is returned when the sampling ends
+ if(iBufferInProcess->iDataSize != 0)
+ {
+ LOGTEXT(_L("CProfilerBufferHandler::RunL - buffer received"));
+
+ TBapBuf* nextFree = iObserver.GetNextFreeBuffer();
+
+ LOGSTRING5("CProfilerBufferHandler::RunL - 0x%x -> b:0x%x s:%d d:%d",
+ nextFree,
+ nextFree->iBuffer,
+ nextFree->iBufferSize,
+ nextFree->iDataSize);
+
+ iSampler.FillThisStreamBuffer(nextFree,iStatus);
+
+ LOGTEXT(_L("CProfilerBufferHandler::RunL - issued new sample command"));
+
+ // add the received buffer to the list of filled buffers
+ iObserver.AddToFilledBuffers(iBufferInProcess);
+ iObserver.NotifyWriter();
+
+ // the empty buffer is now the one being processed
+ iBufferInProcess = nextFree;
+
+ LOGTEXT(_L("CProfilerBufferHandler::RunL - SetActive"));
+ SetActive();
+ }
+ else
+ {
+ LOGTEXT(_L("CProfilerBufferHandler::RunL - end of stream detected"));
+ iEndOfStreamDetected = true;
+
+ // add the empty buffer to the writer so that it will also get the information
+ // about the finished stream
+ iObserver.AddToFilledBuffers(iBufferInProcess);
+ iObserver.NotifyWriter();
+
+ iBufferInProcess = 0;
+ Cancel();
+
+ }
+ LOGTEXT(_L("CProfilerBufferHandler::RunL - exit"));
+ }
+
+inline void CProfilerBufferHandler::DoCancel()
+ {
+ LOGTEXT(_L("CProfilerBufferHandler::DoCancel - entry"));
+ HandleEndOfStream();
+ LOGTEXT(_L("CProfilerBufferHandler::DoCancel - exit"));
+ }
+
+
+/*
+ *
+ * Class CProfilerSampleStream implementation
+ *
+ * - used by Plugin
+ **/
+
+inline CProfilerSampleStream* CProfilerSampleStream::NewL(TInt aBufSize)
+ {
+ LOGTEXT(_L("CProfilerSampleStream::NewL - entry"));
+ CProfilerSampleStream* self = new(ELeave) CProfilerSampleStream(aBufSize);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+inline CProfilerSampleStream::CProfilerSampleStream(TInt aBufSize) :
+ iBufferSize(aBufSize)
+ {
+ LOGTEXT(_L("CProfilerSampleStream::CProfilerSampleStream - entry"));
+
+ iFilledBuffers = 0;
+ iFreeBuffers = 0;
+ iFinished = 0;
+
+ LOGTEXT(_L("CProfilerSampleStream::CProfilerSampleStream - exit"));
+ }
+
+inline CProfilerSampleStream::~CProfilerSampleStream()
+ {
+ LOGTEXT(_L("CProfilerSampleStream::~CProfilerSampleStream - entry"));
+
+ // empty all buffers
+ EmptyBuffers();
+
+ LOGTEXT(_L("CProfilerSampleStream::~CProfilerSampleStream - exit"));
+ }
+
+inline void CProfilerSampleStream::ConstructL()
+ {
+
+ }
+
+inline void CProfilerSampleStream::SetWriter(CWriterPluginInterface& aWriter)
+ {
+ // set writer plugin
+ iWriter = &aWriter;
+ }
+
+inline void CProfilerSampleStream::Finalise()
+ {
+ LOGTEXT(_L("CProfilerSampleStream::Finalise - entry"));
+ }
+
+inline void CProfilerSampleStream::ResetBuffers()
+ {
+
+ // empty buffers
+ EmptyBuffers();
+
+ // re-initialise buffers
+ InitialiseBuffers();
+ }
+
+inline void CProfilerSampleStream::InitialiseBuffers()
+ {
+ // re-initialize member variables
+ iFilledBuffers = 0;
+ iFreeBuffers = 0;
+ iFinished = 0;
+
+ // create three(orig. two) new TBapBuf objects and add them to the
+ // list of free buffers
+ for(TInt i(0);i<KInitialFreeBufferAmount;i++)
+ {
+ // alloc new buffer
+ TBapBuf* newBuf = (TBapBuf*)User::Alloc(sizeof(TBapBuf));
+ newBuf->iBuffer = (TUint8*)User::Alloc(iBufferSize);
+
+ // initialize the new buffer
+ newBuf->iBufferSize = iBufferSize;
+ newBuf->iDataSize = 0;
+ newBuf->iNext = 0;
+ newBuf->iDes = new TPtr8((TUint8*)newBuf,sizeof(TBapBuf));
+ newBuf->iDes->SetLength(sizeof(TBapBuf));
+ newBuf->iBufDes = new TPtr8((TUint8*)newBuf->iBuffer,iBufferSize);
+ newBuf->iBufDes->SetLength(iBufferSize);
+ AddToFreeBuffers(newBuf);
+ }
+ }
+
+inline void CProfilerSampleStream::EmptyBuffers()
+ {
+ LOGTEXT(_L("CProfilerSampleStream::EmptyBuffers - entry"));
+
+ // delete all free buffers
+ while(iFreeBuffers != 0)
+ {
+ LOGSTRING2("CProfilerSampleStream::EmptyBuffers - deleting 0x%x",iFreeBuffers);
+
+ // store the next buffer in the list
+ TBapBuf* nextFree = iFreeBuffers->iNext;
+ // delete the first one in the list
+ delete iFreeBuffers->iBufDes;
+ delete iFreeBuffers->iDes;
+ delete iFreeBuffers->iBuffer;
+ delete iFreeBuffers;
+ // set the list start to the next buffer
+ iFreeBuffers = nextFree;
+ }
+ iFreeBuffers = 0;
+ LOGTEXT(_L("CProfilerSampleStream::EmptyBuffers - exit"));
+ }
+
+inline TBapBuf* CProfilerSampleStream::GetNextFreeBuffer()
+ {
+ LOGTEXT(_L("CProfilerSampleStream::GetNextFreeBuffer - entry"));
+
+ // get a new buffer from the free buffers list
+ TBapBuf* nextFree = iFreeBuffers;
+
+ // check if we got a buffer or not
+ if(nextFree == 0)
+ {
+ // if there are no free buffers,
+ // create a new one
+ LOGTEXT(_L("CProfilerSampleStream::GetNextFreeBuffer - creating new buffer"));
+ TBapBuf* newBuf = (TBapBuf*)User::Alloc(sizeof(TBapBuf));
+ if(newBuf != 0)
+ {
+ newBuf->iBuffer = (TUint8*)User::Alloc(iBufferSize);
+ if(newBuf->iBuffer != 0)
+ {
+ newBuf->iBufferSize = iBufferSize;
+ newBuf->iDataSize = 0;
+ newBuf->iNext = 0;
+ newBuf->iDes = new TPtr8((TUint8*)newBuf,sizeof(TBapBuf));
+ newBuf->iDes->SetLength(sizeof(TBapBuf));
+ newBuf->iBufDes = new TPtr8((TUint8*)newBuf->iBuffer,iBufferSize);
+ newBuf->iBufDes->SetLength(iBufferSize);
+ nextFree = newBuf;
+ }
+ else
+ {
+ LOGTEXT(_L("CProfilerSampleStream::GetNextFreeBuffer - Out of memory (1)!!"));
+ return 0;
+ }
+ }
+ else
+ {
+ LOGTEXT(_L("CProfilerSampleStream::GetNextFreeBuffer - Out of memory (2)!!"));
+ delete newBuf;
+ return 0;
+ }
+ }
+ else
+ {
+ // set the list to point to next free buffer
+ iFreeBuffers = nextFree->iNext;
+ }
+
+ LOGTEXT(_L("CProfilerSampleStream::GetNextFreeBuffer - exit"));
+ return nextFree;
+ }
+
+inline void CProfilerSampleStream::AddToFilledBuffers(TBapBuf* aFilledBuffer)
+ {
+ LOGSTRING2("CProfilerSampleStream::AddToFilledBuffers - entry, size %d", aFilledBuffer->iDataSize);
+
+ // add this buffer to the list of filled buffers
+ if(iFilledBuffers == 0)
+ {
+ // the list is empty, so add the the beginning of the list
+ // there is no next buffer in the list at the moment
+ aFilledBuffer->iNext = 0;
+ iFilledBuffers = aFilledBuffer;
+ }
+ else
+ {
+ // there are buffers in the list, add this buffer to the beginning of the list
+ aFilledBuffer->iNext = iFilledBuffers;
+ iFilledBuffers = aFilledBuffer;
+ }
+ LOGTEXT(_L("CProfilerSampleStream::AddToFilledBuffers - exit"));
+ }
+
+TBapBuf* CProfilerSampleStream::GetNextFilledBuffer()
+ {
+ LOGTEXT(_L("CProfilerSampleStream::GetNextFilledBuffer - entry"));
+
+ if(iFilledBuffers == 0)
+ {
+ // there are no filled buffers in the list
+ LOGTEXT(_L("CProfilerSampleStream::GetNextFilledBuffer - no filled bufs"));
+ return 0;
+ }
+ else
+ {
+ // get a buffer from the end of the list
+ TBapBuf* buf = iFilledBuffers;
+ TBapBuf* prev = 0;
+
+ if(buf->iNext == 0)
+ {
+ // this was the last (and only) buffer
+ iFilledBuffers = 0;
+ LOGTEXT(_L("CProfilerSampleStream::GetNextFilledBuffer - last filled"));
+ return buf;
+ }
+ else
+ {
+ LOGTEXT(_L("CProfilerSampleStream::GetNextFilledBuffer - searching last filled"));
+ while(buf->iNext != 0)
+ {
+ // there are two or more buffers in the list
+ // proceed until the end of the list is found
+ prev = buf;
+ buf = buf->iNext;
+ }
+ // now buf->next is 0, return buf and set the next
+ // element of prev to NULL
+ prev->iNext = 0;
+ LOGTEXT(_L("CProfilerSampleStream::GetNextFilledBuffer - found last"));
+ return buf;
+ }
+ }
+ }
+
+inline void CProfilerSampleStream::AddToFreeBuffers(TBapBuf* aFreeBuffer)
+ {
+ LOGTEXT(_L("CProfilerSampleStream::AddToFreeBuffers - entry"));
+
+ // set data size of the buffer to 0
+ aFreeBuffer->iDataSize = 0;
+
+ // add this buffer to the list of free buffers
+ if(iFreeBuffers == 0)
+ {
+ // this is the first buffer, so set the next to point to NULL
+ aFreeBuffer->iNext = 0;
+ }
+ else
+ {
+ // otherwise set to point to the beginning of the list
+ aFreeBuffer->iNext = iFreeBuffers;
+ }
+
+ // set this buffer to be the first one in the list
+ iFreeBuffers = aFreeBuffer;
+
+ LOGTEXT(_L("CProfilerSampleStream::AddToFreeBuffers - exit"));
+ }
+
+void CProfilerSampleStream::NotifyWriter()
+ {
+ // notify writer plugin to write data from filled buffer list
+ LOGTEXT(_L("CProfilerSampleStream::NotifyWriter() - entry"));
+ iWriter->WriteData();
+ LOGTEXT(_L("CProfilerSampleStream::NotifyWriter() - exit"));
+ }
+
+// end of file
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/ProfilerSession.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,417 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef __PROFILER_SESSION_H__
+#define __PROFILER_SESSION_H__
+
+#include <e32base.h>
+#include <e32svr.h>
+#include <piprofiler/ProfilerConfig.h>
+#include <piprofiler/ProfilerVersion.h>
+#include <piprofiler/ProfilerTraces.h>
+#include <piprofiler/ProfilerAttributes.h>
+
+_LIT(KProfilerName,"PIProfilerEngine");
+
+/**
+ * The RProfiler class provides a functional interface to the sampling profiler.
+ *
+ * The engine must already be running for this interface to work, this can be
+ * achieved by executing PIProfilerEngine.exe. The control methods are all static, and
+ * require no other context.
+ */
+NONSHARABLE_CLASS( RProfiler ) : public RSessionBase
+ {
+public:
+ enum TCommand {
+ // profiler controls
+ EStartSampling = 1,
+ EStartTimedSampling,
+ EStopSampling,
+// ELoadSettings,
+ EExitProfiler,
+ EFinalise,
+ EAttachClient,
+ ERemoveClient,
+
+ // general attributes
+ EGetGeneralAttributes,
+ EGetSamplerAttributes,
+ EGetSamplerAttributeCount,
+ ESetGeneralAttributes,
+ ESetSamplerAttributes,
+
+ // generic settings
+ ESetTraceFilePrefix,
+ ESetTraceFileDrive,
+ EGetSamplerVersion,
+ EGetFileName,
+ EGetActiveWriter,
+ ERefreshProfilerStatus
+ };
+
+ enum TSamplerState {
+ EIdle = 0,
+ EInitializing,
+ ERunning,
+ EStopping,
+ EStopped
+ };
+
+ enum TProfilingMode
+ {
+ EProfilingModeNormal = 0,
+ EProfilingModeTimed
+ };
+public:
+
+
+ /*
+ *
+ * Methods for commanding Profiler Engine
+ *
+ */
+
+ // get general settings
+ static inline TInt GetGeneralAttributes(TGeneralAttributes& aAttributes);
+
+ // get samplers; names, settings, states, descriptions etc. in one array containing all sampler attributes
+ static inline TInt GetSamplerAttributes(CArrayFixFlat<TSamplerAttributes>& aAttributeArray);
+
+ // save settings back to engine and plugins
+ static inline TInt SetGeneralAttributes(TGeneralAttributes aAttributes);
+
+ // save settings back to engine and plugins
+ static inline TInt SetSamplerAttributes(TSamplerAttributes aAttributes);
+
+ // refresh profiler engine status
+ static inline TInt RefreshProfilerStatus();
+
+ /** Start sampling */
+ static inline TInt StartSampling(TProfilingMode aProfilingMode = EProfilingModeNormal);
+ /** Stop sampling */
+ static inline TInt StopSampling();
+ /** Load settings */
+// static inline TInt LoadSettings(TDesC& aSettingsFile);
+ /** Exit profiler */
+ static inline TInt ExitProfiler();
+
+ /** Get file name */
+ static inline TInt GetFileName(TDes&);
+ /** Get active writer */
+ static inline TInt GetActiveWriter(TDes&);
+ /** Perform a test case */
+ static inline TInt Test(TUint32 testCase);
+ /** Issue a control request to the engine without data*/
+ static inline TInt ControlState(TCommand aRequest);
+ /** Issue a control request to the engine with descriptor data to write there*/
+ static inline TInt ControlWrite(TCommand aRequest,TDesC& data);
+ /** Issue a control request to the engine with numeric and descriptor data to write there*/
+ static inline TInt ControlWrite(TCommand aRequest,TInt numData, TDesC& data);
+ /** Issue a control request to read descriptor data from the engine*/
+ static inline TInt ControlRead(TCommand aRequest,TDes& data);
+ /** Actually sends the message to profiler engine*/
+ static inline TInt PerformControl( TCommand aRequest,
+ TDesC* fromDescriptor = NULL,
+ TUint32 numData1 = 0,
+ TDes* toDescriptor = NULL,
+ TUint32 numData2 = 0xffffffff);
+
+ static inline TInt AttachClient();
+ static inline TInt RemoveClient();
+
+private:
+ inline RProfiler();
+ };
+
+inline RProfiler::RProfiler()
+ {}
+
+//
+// Connect to the profiler engine, and issue the control request if successful
+//
+inline TInt RProfiler::ControlState(TCommand aRequest)
+ { return PerformControl(aRequest); }
+
+//
+// Connect to the profiler engine, and issue the control request if successful
+//
+inline TInt RProfiler::ControlWrite(TCommand aRequest,TDesC& data)
+ { return PerformControl(aRequest,&data,0); }
+
+//
+// Connect to the profiler engine, and issue the control request if successful
+//
+inline TInt RProfiler::ControlWrite(TCommand aRequest,TInt numData, TDesC& data)
+ { return PerformControl(aRequest,&data,numData); }
+
+//
+// Connect to the profiler engine, and issue the control request if successful
+//
+inline TInt RProfiler::ControlRead(TCommand aRequest,TDes& data)
+ { return PerformControl(aRequest,0,0,&data); }
+
+inline TInt RProfiler::PerformControl(TCommand aRequest,TDesC* fromDescriptor,TUint32 numData1,TDes* toDescriptor,TUint32 numData2)
+ {
+ LOGTEXT(_L("Creating a session to profiler"));
+ RProfiler p;
+ TUint count(0);
+ TInt r(KErrNone);
+
+ // in boot measurement mode, count until 30s
+ #ifdef PROFILER_BOOT_MEASUREMENT
+ while(count < 60)
+ #else
+ while(count < 6)
+ #endif
+ {
+ r = p.CreateSession(KProfilerName, TVersion(), 0);
+ if (r == KErrNone)
+ {
+ LOGSTRING2("Succeeded, sending a message %d", aRequest);
+ LOGSTRING5(" - parameters 0x%x 0x%x 0x%x 0x%x",fromDescriptor,numData1,toDescriptor,numData2);
+ TInt err = KErrNone;
+
+ TIpcArgs a;
+ a.Set(0,fromDescriptor);
+ a.Set(1,numData1);
+ a.Set(2,toDescriptor);
+ a.Set(3,numData2);
+ err = p.SendReceive(aRequest,a);
+
+ p.RSessionBase::Close();
+
+ if(err != KErrNone)
+ {
+ LOGSTRING2("Profiler responded with an error - code %d !!",err);
+ return err;
+ }
+ else
+ {
+ LOGTEXT(_L("OK, message sent, closing"));
+ return KErrNone;
+ }
+ }
+
+ LOGSTRING2("Error in opening session to profiler - code %d !!",r);
+ //#ifdef PROFILER_BOOT_MEASUREMENT
+ // there was an error contacting the Profiler
+ // indicates that the server is most probably not up
+ // however, since it should be(unless some resource is not yet ready)
+ // we can just wait
+ User::After(500000); // wait 1/2 s
+ count++;
+ //#else
+ // exit immediately on error
+ //return r;
+ //#endif
+ }
+ return r;
+ }
+
+// the new UI access methods
+inline TInt RProfiler::GetGeneralAttributes(TGeneralAttributes& aAttributes)
+ {
+#ifdef _TEST_
+ _LIT(KDefaultTraceOutput,"debug_output");
+ _LIT(KDefaultTraceFilePrefix,"PIProfiler_#");
+ _LIT(KDefaultTraceFileSaveDrive,"E:\\");
+ aAttributes.iTraceOutput.Copy(KDefaultTraceOutput);
+ aAttributes.iTraceFilePrefix.Copy(KDefaultTraceFilePrefix);
+ aAttributes.iSaveFileDrive.Copy(KDefaultTraceFileSaveDrive);
+#else
+ LOGTEXT(_L("Creating a session to profiler"));
+ RProfiler p;
+ TInt r(KErrNone);
+ r = p.CreateSession(KProfilerName, TVersion(), 0);
+ if (r == KErrNone)
+ {
+ LOGSTRING2("Succeeded, sending a message %d", EGetGeneralAttributes);
+
+ TPckg<TGeneralAttributes> attrPckg(aAttributes);
+ TIpcArgs a(&attrPckg);
+ r = p.SendReceive(RProfiler::EGetGeneralAttributes,a);
+
+ p.RSessionBase::Close();
+
+ if(r != KErrNone)
+ {
+ LOGSTRING2("Profiler responded with an error - code %d !!",r);
+ return r;
+ }
+ else
+ {
+ LOGTEXT(_L("OK, message sent, closing"));
+ return KErrNone;
+ }
+ }
+#endif
+ return r; // return error code
+ }
+inline TInt RProfiler::GetSamplerAttributes(CArrayFixFlat<TSamplerAttributes>& aAttributes)
+ {
+#ifdef _TEST_
+ _LIT(KDefaultTraceOutput,"debug_output");
+ _LIT(KDefaultTraceFilePrefix,"PIProfiler_#");
+ _LIT(KDefaultTraceFileSaveDrive,"E:\\");
+ aAttributes.iTraceOutput.Copy(KDefaultTraceOutput);
+ aAttributes.iTraceFilePrefix.Copy(KDefaultTraceFilePrefix);
+ aAttributes.iSaveFileDrive.Copy(KDefaultTraceFileSaveDrive);
+#else
+ // do receive stream of TSamplerAttributes
+ LOGTEXT(_L("Creating a session to profiler"));
+ RProfiler p;
+ TInt r(KErrNone);
+ r = p.CreateSession(KProfilerName, TVersion(), 0);
+ if (r == KErrNone)
+ {
+ TInt attrCount(0);
+ TPckg<TInt> pckg(attrCount);
+ TIpcArgs args(&pckg);
+
+ r = p.SendReceive(RProfiler::EGetSamplerAttributeCount, args);
+
+ HBufC8* buffer = HBufC8::NewL(attrCount*sizeof(TSamplerAttributes));
+ TPtr8 ptr(buffer->Des());
+ TIpcArgs args2(&ptr);
+ r = p.SendReceive(RProfiler::EGetSamplerAttributes, args2);
+
+ TInt len(ptr.Length());
+ TInt pos(0);
+ while (pos != len)
+ {
+ TPckgBuf<TSamplerAttributes> attrPckg;
+ attrPckg.Copy(ptr.Mid(pos, attrPckg.Length()));
+ pos += attrPckg.Length();
+
+ aAttributes.AppendL(attrPckg());
+ }
+
+ p.RSessionBase::Close();
+
+ if(r != KErrNone)
+ {
+ LOGSTRING2("Profiler responded with an error - code %d !!",r);
+ return r;
+ }
+ else
+ {
+ LOGTEXT(_L("OK, message sent, closing"));
+ return KErrNone;
+ }
+ }
+#endif
+ return KErrNone;
+ }
+
+inline TInt RProfiler::SetGeneralAttributes(TGeneralAttributes aAttributes)
+ {
+ // do receive stream of TSamplerAttributes
+ LOGTEXT(_L("Creating a session to profiler"));
+ RProfiler p;
+ TInt r(KErrNone);
+ r = p.CreateSession(KProfilerName, TVersion(), 0);
+ if (r == KErrNone)
+ {
+
+ TPckg<TGeneralAttributes> attrPckg(aAttributes);
+ TIpcArgs a(&attrPckg);
+ r = p.SendReceive(RProfiler::ESetGeneralAttributes,a);
+
+ p.RSessionBase::Close();
+
+ if(r != KErrNone)
+ {
+ LOGSTRING2("Profiler responded with an error - code %d !!",r);
+ return r;
+ }
+ else
+ {
+ LOGTEXT(_L("OK, message sent, closing"));
+ return KErrNone;
+ }
+ }
+ return r;
+ }
+
+// save settings back to engine and plugins
+inline TInt RProfiler::SetSamplerAttributes(TSamplerAttributes aAttributes)
+ {
+ // do receive stream of TSamplerAttributes
+ LOGTEXT(_L("Creating a session to profiler"));
+ RProfiler p;
+ TInt r(KErrNone);
+ r = p.CreateSession(KProfilerName, TVersion(), 0);
+ if (r == KErrNone)
+ {
+
+ TPckg<TSamplerAttributes> attrPckg(aAttributes);
+
+ TIpcArgs a;
+ a.Set(0,&attrPckg);
+
+ r = p.SendReceive(RProfiler::ESetSamplerAttributes,a);
+
+ p.RSessionBase::Close();
+
+ if(r != KErrNone)
+ {
+ LOGSTRING2("Profiler responded with an error - code %d !!",r);
+ return r;
+ }
+ else
+ {
+ LOGTEXT(_L("OK, message sent, closing"));
+ return KErrNone;
+ }
+ }
+ return r;
+ }
+
+inline TInt RProfiler::RefreshProfilerStatus()
+ {return ControlState(RProfiler::ERefreshProfilerStatus); }
+
+inline TInt RProfiler::StartSampling(RProfiler::TProfilingMode aProfilingMode)
+ {
+ RProfiler::TCommand command = RProfiler::EStartSampling;
+ if( aProfilingMode == RProfiler::EProfilingModeTimed )
+ {
+ command = RProfiler::EStartTimedSampling;
+ }
+ return ControlState(command);
+ }
+
+inline TInt RProfiler::StopSampling()
+ {return ControlState(RProfiler::EStopSampling);}
+
+inline TInt RProfiler::ExitProfiler()
+ {return ControlState(RProfiler::EExitProfiler);}
+
+inline TInt RProfiler::AttachClient()
+ {return ControlState(RProfiler::EAttachClient);}
+
+inline TInt RProfiler::RemoveClient()
+ {return ControlState(RProfiler::ERemoveClient);}
+
+inline TInt RProfiler::GetFileName(TDes& fileName)
+ {return ControlRead(EGetFileName,fileName);}
+
+inline TInt RProfiler::GetActiveWriter(TDes& writerDes)
+ {return ControlRead(EGetActiveWriter,writerDes);}
+
+#endif // __PROFILER_SESSION_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/ProfilerTraces.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,146 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef __PROFILER_TRACES_H__
+#define __PROFILER_TRACES_H__
+
+#include <e32def.h>
+
+
+// ---------------------------------------------------------------------------
+// You change these logging method values below! Recompile the application to take changes effect.
+
+ // logging methods
+ // 0 = No logging
+ // 1 = Flogger
+ // 2 = RDebug
+ // 3 = Flogger and RDebug
+
+#undef _DEBUG
+
+ #ifndef _DEBUG
+
+ // Logging method for UREL builds:
+ #define PROFILER_LOGGING_METHOD 0
+
+ #else
+
+ // Logging method for UDEB builds:
+ #define PROFILER_LOGGING_METHOD 2
+
+ #endif
+
+ #ifndef _KERNEL_DEBUG
+
+ // Logging method for UREL builds:
+ #define KERNEL_LOGGING_METHOD 0
+
+ #else
+
+ // Logging method for UDEB builds:
+ #define KERNEL_LOGGING_METHOD 1
+
+ #endif
+
+
+
+#ifndef __KERNEL_MODE__
+
+// ---------------------------------------------------------------------------
+// Do not make any changes to lines below...
+
+ #if PROFILER_LOGGING_METHOD == 1 || PROFILER_LOGGING_METHOD == 3
+
+ #include <flogger.h>
+ _LIT(KLogFolder,"PIProfiler");
+ _LIT(KLogFile,"PIProfiler_Trace.txt");
+
+ #endif
+
+ #if PROFILER_LOGGING_METHOD == 2 || PROFILER_LOGGING_METHOD == 3
+
+ #include <e32debug.h>
+
+ #endif
+
+
+ #if PROFILER_LOGGING_METHOD == 0
+
+ #define LOGTEXT(AAA)
+ #define LOGSTRING(AAA)
+ #define LOGSTRING2(AAA,BBB)
+ #define LOGSTRING3(AAA,BBB,CCC)
+ #define LOGSTRING4(AAA,BBB,CCC,DDD)
+ #define LOGSTRING5(AAA,BBB,CCC,DDD,EEE)
+
+
+ #elif PROFILER_LOGGING_METHOD == 1
+
+ #define LOGTEXT(AAA) RFileLogger::Write(KLogFolder(),KLogFile(),EFileLoggingModeAppend, AAA)
+ #define LOGSTRING(AAA) do { _LIT(tempLogDes,AAA); RFileLogger::Write(KLogFolder(),KLogFile(),EFileLoggingModeAppend,tempLogDes()); } while (0)
+ #define LOGSTRING2(AAA,BBB) do { _LIT(tempLogDes,AAA); RFileLogger::WriteFormat(KLogFolder(),KLogFile(),EFileLoggingModeAppend,TRefByValue<const TDesC>(tempLogDes()),BBB); } while (0)
+ #define LOGSTRING3(AAA,BBB,CCC) do { _LIT(tempLogDes,AAA); RFileLogger::WriteFormat(KLogFolder(),KLogFile(),EFileLoggingModeAppend,TRefByValue<const TDesC>(tempLogDes()),BBB,CCC); } while (0)
+ #define LOGSTRING4(AAA,BBB,CCC,DDD) do { _LIT(tempLogDes,AAA); RFileLogger::WriteFormat(KLogFolder(),KLogFile(),EFileLoggingModeAppend,TRefByValue<const TDesC>(tempLogDes()),BBB,CCC,DDD); } while (0)
+ #define LOGSTRING5(AAA,BBB,CCC,DDD,EEE) do { _LIT(tempLogDes,AAA); RFileLogger::WriteFormat(KLogFolder(),KLogFile(),EFileLoggingModeAppend,TRefByValue<const TDesC>(tempLogDes()),BBB,CCC,DDD,EEE); } while (0)
+
+ #elif PROFILER_LOGGING_METHOD == 2
+
+ #define LOGTEXT(AAA) RDebug::Print(AAA);
+ #define LOGSTRING(AAA) do { _LIT(tempLogDes,AAA); RDebug::Print(tempLogDes); } while (0)
+ #define LOGSTRING2(AAA,BBB) do { _LIT(tempLogDes,AAA); RDebug::Print(tempLogDes, BBB); } while (0)
+ #define LOGSTRING3(AAA,BBB,CCC) do { _LIT(tempLogDes,AAA); RDebug::Print(tempLogDes, BBB, CCC); } while (0)
+ #define LOGSTRING4(AAA,BBB,CCC,DDD) do { _LIT(tempLogDes,AAA); RDebug::Print(tempLogDes, BBB, CCC, DDD); } while (0)
+ #define LOGSTRING5(AAA,BBB,CCC,DDD,EEE) do { _LIT(tempLogDes,AAA); RDebug::Print(tempLogDes, BBB, CCC, DDD, EEE); } while (0)
+
+ #elif PROFILER_LOGGING_METHOD == 3
+
+ #define LOGTEXT(AAA) RDebug::Print(AAA); RFileLogger::Write(KLogFolder(),KLogFile(),EFileLoggingModeAppend, AAA)
+ #define LOGSTRING(AAA) do { _LIT(tempLogDes,AAA); RDebug::Print(tempLogDes); RFileLogger::Write(KLogFolder(),KLogFile(),EFileLoggingModeAppend,tempLogDes()); } while (0)
+ #define LOGSTRING2(AAA,BBB) do { _LIT(tempLogDes,AAA); RDebug::Print(tempLogDes, BBB); RFileLogger::WriteFormat(KLogFolder(),KLogFile(),EFileLoggingModeAppend,TRefByValue<const TDesC>(tempLogDes()),BBB); } while (0)
+ #define LOGSTRING3(AAA,BBB,CCC) do { _LIT(tempLogDes,AAA); RDebug::Print(tempLogDes, BBB, CCC); RFileLogger::WriteFormat(KLogFolder(),KLogFile(),EFileLoggingModeAppend,TRefByValue<const TDesC>(tempLogDes()),BBB,CCC); } while (0)
+ #define LOGSTRING4(AAA,BBB,CCC,DDD) do { _LIT(tempLogDes,AAA); RDebug::Print(tempLogDes, BBB, CCC, DDD); RFileLogger::WriteFormat(KLogFolder(),KLogFile(),EFileLoggingModeAppend,TRefByValue<const TDesC>(tempLogDes()),BBB,CCC,DDD); } while (0)
+ #define LOGSTRING5(AAA,BBB,CCC,DDD,EEE) do { _LIT(tempLogDes,AAA); RDebug::Print(tempLogDes, BBB, CCC, DDD, EEE); RFileLogger::WriteFormat(KLogFolder(),KLogFile(),EFileLoggingModeAppend,TRefByValue<const TDesC>(tempLogDes()),BBB,CCC,DDD,EEE); } while (0)
+
+ #endif
+
+#else __KERNEL_MODE__
+
+ #if KERNEL_LOGGING_METHOD == 0
+
+ #define LOGTEXT(AAA)
+ #define LOGSTRING(AAA)
+ #define LOGSTRING2(AAA,BBB)
+ #define LOGSTRING3(AAA,BBB,CCC)
+ #define LOGSTRING4(AAA,BBB,CCC,DDD)
+ #define LOGSTRING5(AAA,BBB,CCC,DDD,EEE)
+
+ #else
+
+ #define LOGTEXT(AAA) Kern::Printf(AAA)
+ #define LOGSTRING(AAA) Kern::Printf(AAA);
+ #define LOGSTRING2(AAA,BBB) Kern::Printf(AAA, BBB);
+ #define LOGSTRING3(AAA,BBB,CCC) Kern::Printf(AAA, BBB, CCC);
+ #define LOGSTRING4(AAA,BBB,CCC,DDD) Kern::Printf(AAA, BBB, CCC, DDD);
+ #define LOGSTRING5(AAA,BBB,CCC,DDD,EEE) Kern::Printf(AAA, BBB, CCC, DDD, EEE);
+
+ #endif
+#endif
+// ---------------------------------------------------------------------------
+
+#endif // __PROFILER_TRACES_H__
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/ProfilerVersion.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,47 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef PROFILER_TOOL_VERSION_H
+#define PROFILER_TOOL_VERSION_H
+
+ /*
+ *
+ * PI Profiler tool composition definitions
+ *
+ */
+
+ #define PROFILER_VERSION "PI Profiler v2.1.0"
+ #define PROFILER_VERSION_SHORT _L("2.00.0")
+ #define PROFILER_SAMPLER_VERSION _L("2.00.0")
+ #define PROFILER_RELEASE_DATE _L("23rd February 2009. ")
+
+ #define PROFILER_GPP_SAMPLER_VERSION _L("2.00") // SMPfied v2.00
+ #define PROFILER_GFC_SAMPLER_VERSION _L8("1.10")
+ #define PROFILER_ITT_SAMPLER_VERSION _L8("1.22")
+ #define PROFILER_MEM_SAMPLER_VERSION _L8("2.02")
+ #define PROFILER_PRI_SAMPLER_VERSION _L8("1.56")
+ #define PROFILER_BUP_SAMPLER_VERSION _L8("1.20")
+ #define PROFILER_IRQ_SAMPLER_VERSION _L8("1.20")
+ #define PROFILER_TIP_SAMPLER_VERSION _L8("1.10")
+ #define PROFILER_PEC_SAMPLER_VERSION _L8("1.24")
+ #define PROFILER_PWR_SAMPLER_VERSION _L8("1.57")
+ #define PROFILER_SCR_SAMPLER_VERSION _L8("1.57")
+ #define PROFILER_IPC_SAMPLER_VERSION _L8("1.59")
+ #define PROFILER_GPU_SAMPLER_VERSION _L8("1.00")
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/SamplerPluginInterface.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,257 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef __SAMPLER_PLUGIN_INTERFACE__
+#define __SAMPLER_PLUGIN_INTERFACE__
+
+#include <e32base.h>
+#include <ecom/ecom.h>
+#include <badesca.h>
+#include <piprofiler/ProfilerAttributes.h> // internal settings format presentations
+
+
+// Constant for indexing (iOrder):
+const TInt KSamplerPluginNotIndexed = -1;
+
+/**
+ * Constant: KSamplerPluginInterfaceUid
+ *
+ * Description: UID of this ECOM interface. It should be unique in the system.
+ * It is used to identify this specific custom interface.
+ * Implementations of this interface will use this ID, when they
+ * publish the implementation. Clients use this UID to search for
+ * implementations for this interface (the
+ * EcomInterfaceDefinition.inl does this).
+ */
+const TUid KSamplerPluginInterfaceUid = {0x2001E5BC};
+
+/**
+ *
+ * Description: UID of this ECOM interface. It should be unique in the system.
+ *
+ */
+enum TGenericSettingTypes
+{
+ EEnablePlugin,
+ EOutputSettings,
+ ESaveDrive,
+ EFilePrefix,
+ ETracingMode
+};
+
+
+enum TSamplerCaptionTypes
+ {
+ ECaptionLengthShort,
+ ECaptionLengthMedium,
+ ECaptionLengthLong,
+ ESettingsCaption
+ };
+
+
+/**
+* Used by GetValue(). These are the keys for retrieving a specific
+* value. This enum can be extended to provide other values as well as
+* long as the original keys are not changed.
+*/
+enum TSamplerPluginValueKeys
+ {
+
+ ESamplerPluginKeySettingsItemValueString = 1,
+ ESamplerPluginSettings,
+ ESamplerPluginEnabled,
+ ESamplerPluginDisabled,
+ ESamplerPluginType,
+ ESamplerPluginVersion
+ };
+
+
+/**
+ * Class: CSamplerInterfaceDefinition
+ *
+ * Description: Custom ECOM interface definition. This interface is used by
+ * clients to find specific instance and do corresponding
+ * calculation operation for given too numbers. Plugin
+ * implementations implement the Calculate function.
+ */
+class TBapBuf;
+class CProfilerSampleStream;
+
+class CSamplerPluginInterface : public CBase
+{
+
+ // CSamplerPluginLoader accesses iOrder which should not be accessed outside.
+ friend class CSamplerPluginLoader;
+
+public:
+ // Wrapper functions to handle ECOM "connectivity".
+ // These are implemented in EComInterfaceDefinition.inl.
+ // These functions are used only by the client.
+
+ /**
+ * Function: NewL
+ *
+ * Description: Wraps ECom object instantitation. Will search for
+ * interface implementation, which matches to given
+ * aOperationName.
+ *
+ * Param: aOperationName name of requested implementation.
+ * Implementations advertise their "name" as specified
+ * in their resource file field
+ * IMPLEMENTATION_INFO::default_data.
+ * For details, see EcomInterfaceDefinition.inl comments.
+ * In this example, the allowed values are "sum" and
+ * "multiply".
+ *
+ * Note: This is not a "normal" NewL method, since normally NewL
+ * methods are only defined for concrete classes.
+ * Note that also implementations of this interface provide
+ * NewL methods. They are the familiar NewL's, which create
+ * instance of classes.
+ */
+ static CSamplerPluginInterface* NewL(const TUid aImplementationUid, TAny* aInitParams);
+
+ /**
+ * Function: ~CSamplerPluginInterface
+ *
+ * Description: Wraps ECom object destruction. Notifies the ECOM
+ * framework that specific instance is being destroyed.
+ * See EcomInterfaceDefinition.inl for details.
+ */
+ virtual ~CSamplerPluginInterface();
+protected: // New
+
+ /**
+ * C++ constructor.
+ */
+ CSamplerPluginInterface();
+
+public:
+ // Public pure virtual functions, which are implemented by
+ // interface implementations (See ..\plugin)
+
+ /**
+ * Method for initializing and starting of profiling in single plugin implementation
+ * @param aStream is a data stream to store the gathered data, provided by engine
+ * @return TInt if no error KErrNone, else any of system-wide errors
+ */
+ virtual TInt ResetAndActivateL(CProfilerSampleStream& aStream) = 0;
+
+ /**
+ * Method for stopping of profiling in single plugin implementation
+ * @return TInt if no error KErrNone, else any of system-wide errors
+ */
+ virtual TInt StopSampling() = 0;
+
+ /**
+ * Method for checking if plugin is enabled
+ * @return TBool if enabled return ETrue else EFalse
+ */
+ virtual TBool Enabled() = 0;
+
+ /**
+ * Method for getting an array of sampler attributes, size of an array: 1...n
+ * @return array of settings of one or several sampler plugins
+ */
+ virtual void GetAttributesL(CArrayFixFlat<TSamplerAttributes>* aAttributeArray) = 0;
+
+ /**
+ * Method for setting configurations of single sampler attributes
+ * @param aAttributes contains settings of a single sampler plugin
+ */
+ virtual TInt SetAttributesL(TSamplerAttributes aAttributes) = 0;
+
+ /**
+ * Method for parsing text formatted settings block and converting
+ * it to TSamplerAttributes data structure
+ * @param aSingleSettingArray containing setting lines of a single sampler
+ * @return status of conversion, if success KErrNone, else KErrGeneral
+ */
+ virtual TInt ConvertRawSettingsToAttributes(CDesC8ArrayFlat* aSingleSettingArray) = 0;
+
+ /**
+ * Method for getting UID of this plugin.
+ * @param aSubId the implementation id of sub sampler
+ * @returns uid of sampler or sub sampler, if aSubId -1 uid of sampler, else uid of sub sampler
+ */
+ virtual TUid Id(TInt aSubId) const = 0;
+
+ /**
+ * Method for getting locally defined sub ID value inside a specific plug-in.
+ * @param aUid of a specific sampler
+ * @returns local ID of sampler or sub sampler
+ */
+ virtual TInt SubId(TUid aUid) const = 0;
+
+ /**
+ * Method for getting sampler type.
+ * @returns PROFILER_USER_MODE_SAMPLER, PROFILER_KERNEL_MODE_SAMPLER or PROFILER_DUMMY_MODE_SAMPLER
+ */
+ virtual TInt GetSamplerType() = 0;
+
+
+ // some internal inline methods, used by engine
+ inline TInt Flush();
+ inline TInt AddSample(TUint8* sample, TUint32 length, TInt limitSize);
+ inline void SetOrder( TInt aOrder );
+ inline static void ListAllImplementationsL(RImplInfoPtrArray& aImplInfoArray);
+
+ /**
+ * Static methods for getting setting value out of descriptor
+ *
+ * @param aBuf buffer where to convert the value
+ * @param aValue parameter where to store the requested type of value
+ */
+ inline static void Str2Bool(const TDesC8& aBuf, TBool& aValue);
+ inline static void Str2Int(const TDesC8& aBuf, TInt& aValue);
+ inline static void Str2Int(const TDesC8& aBuf, TUint32& aValue);
+
+ /** iDtor_ID_Key Instance identifier key. When instance of an
+ * implementation is created by ECOM framework, the
+ * framework will assign UID for it. The UID is used in
+ * destructor to notify framework that this instance is
+ * being destroyed and resources can be released.
+ */
+ TUid iDtor_ID_Key;
+
+ /**
+ * Index of the plugin in listbox. Used for CSamplerPluginLoader. Default
+ * value is KSamplerPluginNotIndexed which means not ordered. This value is
+ * read, if defined, from the opaque_data field of the plugin's resource
+ * definition. Index starts from 0.
+ */
+ TInt iOrder;
+
+public:
+ TInt iSamplerType;
+
+ // this variable must be defined by the extending classes!!
+ TInt iSamplerId;
+
+ CProfilerSampleStream* iStream;
+ TBool iEnabled;
+
+private:
+ TBapBuf* iBuffer;
+};
+
+#include <piprofiler/ProfilerGenericClassesUsr.h>
+#include <piprofiler/SamplerPluginInterface.inl>
+
+
+#endif // __SAMPLER_PLUGIN_INTERFACE__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/SamplerPluginInterface.inl Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,215 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+// LITERALS
+_LIT8(KTrue, "true");
+_LIT8(KFalse, "false");
+
+inline CSamplerPluginInterface::CSamplerPluginInterface()
+ : iOrder( KSamplerPluginNotIndexed )
+ {
+ iBuffer = 0;
+ iStream = 0;
+ }
+
+// -----------------------------------------------------------------------------
+// CSamplerPluginInterface::~CSamplerPluginInterface()
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+inline CSamplerPluginInterface::~CSamplerPluginInterface()
+ {
+ iBuffer = 0;
+ REComSession::DestroyedImplementation(iDtor_ID_Key);
+ }
+
+
+inline CSamplerPluginInterface* CSamplerPluginInterface::NewL(const TUid aImplementationUid, TAny* aInitParams)
+ {
+ // Define options, how the default resolver will find appropriate
+ // implementation.
+ return REINTERPRET_CAST(CSamplerPluginInterface*,
+ REComSession::CreateImplementationL(aImplementationUid,
+ _FOFF( CSamplerPluginInterface, iDtor_ID_Key ),
+ aInitParams));
+ }
+
+inline void CSamplerPluginInterface::ListAllImplementationsL(RImplInfoPtrArray& aImplInfoArray)
+ {
+ REComSession::ListImplementationsL(KSamplerPluginInterfaceUid, aImplInfoArray);
+ }
+
+inline void CSamplerPluginInterface::SetOrder( TInt aOrder )
+ {
+ iOrder = aOrder;
+ }
+
+inline TInt CSamplerPluginInterface::Flush()
+ {
+ // complete the header
+ TUint32 header;
+ header = (iBuffer->iDataSize & 0x00ffffff) - 4;
+ header += (iSamplerId << 24);
+
+ // flush the header info
+ iBuffer->iBuffer[0] = header;
+ iBuffer->iBuffer[1] = header >> 8;
+ iBuffer->iBuffer[2] = header >> 16;
+ iBuffer->iBuffer[3] = header >> 24;
+
+ // write data to filled buffers
+ iStream->AddToFilledBuffers(iBuffer);
+ // notify selected writer plugin to write data to output
+ iStream->NotifyWriter();
+
+ iBuffer = 0;
+
+ return KErrNone;
+}
+
+
+inline TInt CSamplerPluginInterface::AddSample(TUint8* aSample, TUint32 aLength, TInt aLimitSize)
+ {
+ LOGTEXT(_L("CSamplerPluginInterface::AddSample - entry"));
+ if(iBuffer == 0)
+ {
+ // get next free buffer where to write data
+ iBuffer = iStream->GetNextFreeBuffer();
+ iBuffer->iBufDes->Zero();
+
+ // get space for the header
+ TUint32 header = 0;
+ iBuffer->iBufDes->Append((TUint8*)&header, 4);
+ iBuffer->iDataSize += 4;
+ }
+
+ // add data to the buffer...
+ // if all data fit to the current buffer
+ if(iBuffer->iBufferSize - iBuffer->iDataSize >= (TInt)aLength)
+ {
+ iBuffer->iBufDes->Append(aSample, (TInt)aLength);
+ iBuffer->iDataSize += (TInt)aLength;
+ }
+ else
+ {
+ // fill in the buffer
+ TUint32 rest = iBuffer->iBufferSize - iBuffer->iDataSize;
+ iBuffer->iBufDes->Append(aSample, rest);
+ iBuffer->iDataSize += (TInt)rest;
+
+ // The buffer is full now, complete the header
+ TUint32 header;
+ header = (iBuffer->iDataSize & 0x00ffffff) - 4;
+ header += (iSamplerId << 24);
+ iBuffer->iBuffer[0] = header;
+ iBuffer->iBuffer[1] = header >> 8;
+ iBuffer->iBuffer[2] = header >> 16;
+ iBuffer->iBuffer[3] = header >> 24;
+
+ // write data to filled buffers
+ iStream->AddToFilledBuffers(iBuffer);
+ // notify selected writer plugin to write data to output
+ iStream->NotifyWriter();
+
+ // Fetch an empty buffer and reserve space for the header
+ iBuffer = iStream->GetNextFreeBuffer();
+ iBuffer->iBufDes->Zero();
+ header = 0;
+ iBuffer->iBufDes->Append((TUint8*)&header, 4);
+ iBuffer->iDataSize += 4;
+
+ // copy the rest of data to the new buffer
+ iBuffer->iBufDes->Append(aSample+rest, aLength-rest);
+ iBuffer->iDataSize += (TInt)aLength-rest;
+ }
+
+ // Once iBuffer->dataSize reaches the limitSize, data from iBuffer is flushed to file/debug port.
+ // If limitSize is set to zero, buffer is not changed until iBuffer gets full.
+ if(aLimitSize != 0)
+ {
+ if(iBuffer->iDataSize >= aLimitSize)
+ {
+ // The buffer is full now, complete the header
+ TUint32 header;
+ header = (iBuffer->iDataSize & 0x00ffffff) - 4;
+ header += (iSamplerId << 24);
+ iBuffer->iBuffer[0] = header;
+ iBuffer->iBuffer[1] = header >> 8;
+ iBuffer->iBuffer[2] = header >> 16;
+ iBuffer->iBuffer[3] = header >> 24;
+
+
+ // write data to filled buffers
+ iStream->AddToFilledBuffers(iBuffer);
+ // notify selected writer plugin to write data to output
+ iStream->NotifyWriter();
+
+ // Fetch an empty buffer and reserve space for the header
+ iBuffer = iStream->GetNextFreeBuffer();
+ iBuffer->iBufDes->Zero();
+ header = 0;
+ iBuffer->iBufDes->Append((TUint8*)&header, 4);
+ iBuffer->iDataSize += 4;
+ }
+ }
+ return KErrNone;
+ }
+
+// ----------------------------------------------------------------------------
+// Converts given descriptor into TBool value.
+// ----------------------------------------------------------------------------
+//
+inline void CSamplerPluginInterface::Str2Bool(const TDesC8& aBuf, TBool& aValue)
+ {
+ if (aBuf.CompareF(KFalse) == 0)
+ aValue = EFalse;
+ else
+ aValue = ETrue;
+ }
+
+// ----------------------------------------------------------------------------
+// Converts given descriptor into TInt value.
+// ----------------------------------------------------------------------------
+//
+inline void CSamplerPluginInterface::Str2Int(const TDesC8& aBuf, TInt& aValue)
+ {
+ TLex8 conv;
+ conv.Assign(aBuf);
+
+ if (conv.Val(aValue) != KErrNone)
+ aValue = 0;
+ }
+
+// ----------------------------------------------------------------------------
+// Converts given descriptor into TInt value.
+// ----------------------------------------------------------------------------
+//
+inline void CSamplerPluginInterface::Str2Int(const TDesC8& aBuf, TUint32& aValue)
+ {
+ TInt temp(0);
+
+ TLex8 conv;
+ conv.Assign(aBuf);
+
+ if (conv.Val(temp) != KErrNone)
+ aValue = 0;
+ else
+ aValue = (TUint32)temp;
+ }
+
+// End of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/WriterPluginInterface.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,174 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef __WRITERPLUGIN_INTERFACE__
+#define __WRITERPLUGIN_INTERFACE__
+
+#include <e32base.h>
+#include <ecom/ecom.h>
+#include <badesca.h>
+
+
+// Constant for indexing (iOrder):
+const TInt KWriterPluginNotIndexed = -1;
+
+/**
+ * Constant: KWriterPluginInterfaceUid
+ *
+ * Description: UID of this ECOM interface. It should be unique in the system.
+ * It is used to identify this specific custom interface.
+ * Implementations of this interface will use this ID, when they
+ * publish the implementation. Clients use this UID to search for
+ * implementations for this interface (the
+ * EcomInterfaceDefinition.inl does this).
+ */
+const TUid KWriterPluginInterfaceUid = {0x2001E5BD};
+
+/**
+* Used by GetValue(). These are the keys for retrieving a specific
+* value. This enum can be extended to provide other values as well as
+* long as the original keys are not changed.
+*/
+enum TWriterPluginValueKeys
+ {
+ EWriterPluginKeySettingsItemValueString = 1,
+ EWriterPluginSettings,
+ EWriterPluginEnabled,
+ EWriterPluginDisabled,
+ EWriterPluginType,
+ EWriterPluginVersion
+ };
+/**
+ *
+ * Description: UID of this ECOM interface. It should be unique in the system.
+ *
+ */
+
+/**
+ * Class: CWriterInterfaceDefinition
+ *
+ * Description: Custom ECOM interface definition. This interface is used by
+ * clients to find specific instance and do corresponding
+ * calculation operation for given too numbers. Plugin
+ * implementations implement the Calculate function.
+ */
+
+class CProfilerSampleStream;
+
+class CWriterPluginInterface : public CBase
+ {
+
+ // CSamplerPluginLoader accesses iOrder which should not be accessed outside.
+ friend class CWriterPluginLoader;
+
+public: // Wrapper functions to handle ECOM "connectivity".
+ // These are implemented in EComInterfaceDefinition.inl.
+ // These functions are used only by the client.
+ /**
+ * Function: NewL
+ *
+ * Description: Wraps ECom object instantitation. Will search for
+ * interface implementation, which matches to given
+ * aOperationName.
+ *
+ * Param: aOperationName name of requested implementation.
+ * Implementations advertise their "name" as specified
+ * in their resource file field
+ * IMPLEMENTATION_INFO::default_data.
+ * For details, see EcomInterfaceDefinition.inl comments.
+ * In this example, the allowed values are "sum" and
+ * "multiply".
+ *
+ * Note: This is not a "normal" NewL method, since normally NewL
+ * methods are only defined for concrete classes.
+ * Note that also implementations of this interface provide
+ * NewL methods. They are the familiar NewL's, which create
+ * instance of classes.
+ */
+ static CWriterPluginInterface* NewL(const TUid aImplementationUid, TAny* aInitParams);
+
+ /**
+ * Function: ~CWriterPluginInterface
+ *
+ * Description: Wraps ECom object destruction. Notifies the ECOM
+ * framework that specific instance is being destroyed.
+ * See EcomInterfaceDefinition.inl for details.
+ */
+ virtual ~CWriterPluginInterface();
+protected: // New
+
+ /**
+ * C++ constructor.
+ */
+ CWriterPluginInterface();
+
+public:
+ /**
+ * Method for getting caption of this plugin. This should be the
+ * localized name of the settings view to be shown in parent view.
+ *
+ * @param aCaption pointer to Caption variable
+ */
+ virtual TInt Start() = 0;
+
+ virtual void Stop() = 0;
+
+ virtual TUid Id() const = 0;
+
+ virtual void GetValue( const TWriterPluginValueKeys aKey, TDes& aValue ) = 0;
+
+ virtual void SetValue( const TWriterPluginValueKeys aKey, TDes& aValue ) = 0;
+
+ virtual void GetWriterVersion(TDes* aDes) = 0;
+
+ virtual TUint32 GetWriterType() = 0;
+
+ virtual TBool GetEnabled() = 0;
+
+ virtual void WriteData() = 0;
+ virtual void SetStream( CProfilerSampleStream& aStream ) = 0;
+
+ // internal inline functions
+ inline static void ListAllImplementationsL( RImplInfoPtrArray& aImplInfoArray );
+ inline void SetOrder( TInt aOrder );
+
+private:
+
+ /** iDtor_ID_Key Instance identifier key. When instance of an
+ * implementation is created by ECOM framework, the
+ * framework will assign UID for it. The UID is used in
+ * destructor to notify framework that this instance is
+ * being destroyed and resources can be released.
+ */
+ TUid iDtor_ID_Key;
+
+ /**
+ * Index of the plugin in listbox. Used for CSamplerPluginLoader. Default
+ * value is KSamplerPluginNotIndexed which means not ordered. This value is
+ * read, if defined, from the opaque_data field of the plugin's resource
+ * definition. Index starts from 0.
+ */
+ TInt iOrder;
+public:
+ TInt iAdditionalSettings;
+ TBool isEnabled;
+ };
+
+#include <piprofiler/WriterPluginInterface.inl>
+
+#endif // __WRITERPLUGIN_INTERFACE__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/WriterPluginInterface.inl Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,69 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+inline CWriterPluginInterface::CWriterPluginInterface()
+ : iOrder( KWriterPluginNotIndexed )
+ {
+
+ }
+
+// -----------------------------------------------------------------------------
+// CWriterPluginInterface::~CWriterPluginInterface()
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+inline CWriterPluginInterface::~CWriterPluginInterface()
+ {
+ // We don't unload the plugin object here. The loader
+ // has to do this for us. Without this kind of destruction idiom,
+ // the view framework can potentially unload an ECOM plugin dll whilst
+ // there are still child views (Created by the plugin) that are registered
+ // with the view framework. If this occurs, the plugin code segment isn't
+ // loaded anymore and so there is no way to run the subsequent destructor
+ // code => exception.
+
+ // If in the NewL some memory is reserved for member data, it must be
+ // released here. This interface does not have any instance variables so
+ // no need to delete anything.
+
+ // Inform the ECOM framework that this specific instance of the
+ // interface has been destroyed.
+ REComSession::DestroyedImplementation(iDtor_ID_Key);
+ }
+
+inline CWriterPluginInterface* CWriterPluginInterface::NewL(const TUid aImplementationUid, TAny* aInitParams)
+ {
+ // Define options, how the default resolver will find appropriate
+ // implementation.
+ return REINTERPRET_CAST(CWriterPluginInterface*,
+ REComSession::CreateImplementationL(aImplementationUid,
+ _FOFF( CWriterPluginInterface, iDtor_ID_Key ),
+ aInitParams));
+ }
+
+inline void CWriterPluginInterface::ListAllImplementationsL(RImplInfoPtrArray& aImplInfoArray)
+ {
+ REComSession::ListImplementationsL(KWriterPluginInterfaceUid, aImplInfoArray);
+ }
+
+inline void CWriterPluginInterface::SetOrder( TInt aOrder )
+ {
+ iOrder = aOrder;
+ }
+
+// end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/piprofiler_api.metaxml Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<api id="59f5d0509cc9c1556b04d7b6ff036bd0" dataversion="2.0">
+ <name>PIProfiler API</name>
+ <description>Defines the PIProfiler API, which is used for different PI Profiler sub projects.</description>
+ <type>c++</type>
+ <collection>piprofiler</collection>
+ <libs>
+ <lib name="piprofilerapi.lib"/>
+ </libs>
+ <release category="platform" sinceversion=""/>
+ <attributes>
+ <!-- This indicates wether the api provedes separate html documentation -->
+ <!-- or is the additional documentation generated from headers. -->
+ <!-- If you are unsuere then the value is "no" -->
+ <htmldocprovided>no</htmldocprovided>
+ <adaptation>no</adaptation>
+ </attributes>
+</api>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/BUPplugin/data/2001E5B6.rss Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,51 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <ecom/registryinfo.rh>
+
+// Declares info for two implementations
+RESOURCE REGISTRY_INFO theInfo
+ {
+ // UID for the DLL. See mmp files
+ //__SERIES60_3X__ can't be used in resource files
+ dll_uid = 0x2001E5B6;
+
+ // Declare array of interface info. This dll contains implementations for
+ // only one interface (CSamplerInterfaceDefinition).
+ interfaces =
+ {
+ INTERFACE_INFO
+ {
+ // UID of interface that is implemented
+ interface_uid = 0x2001E5BC;
+
+ implementations =
+ {
+ IMPLEMENTATION_INFO
+ {
+ implementation_uid = 0x2001E5B6;
+
+ version_no = 1;
+ display_name = "BUP Sampler";
+ default_data = "bup";
+ opaque_data = "6";
+ }
+ };
+ }
+ };
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/BUPplugin/group/BUPPlugin.mmp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,51 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <platform_paths.hrh>
+
+
+TARGET PIProfilerBUP.dll
+TARGETTYPE PLUGIN
+UID 0x10009D8D 0x2001E5B6
+VENDORID VID_DEFAULT
+CAPABILITY ALL -TCB
+SMPSAFE
+
+OS_LAYER_SYSTEMINCLUDE
+USERINCLUDE ../inc
+SOURCEPATH ../src
+
+START RESOURCE ../data/2001E5B6.rss
+TARGET PIProfilerBUP.rsc
+END
+
+SOURCE BupPluginImplementationTable.cpp
+SOURCE BupPlugin.cpp
+SOURCE TouchEventClientDll.cpp
+
+LIBRARY euser.lib
+LIBRARY bafl.lib
+LIBRARY ECom.lib
+LIBRARY apparc.lib
+LIBRARY cone.lib
+LIBRARY gdi.lib
+LIBRARY ws32.lib
+LIBRARY EFSRV.LIB
+LIBRARY charconv.lib
+LIBRARY commonengine.lib
+LIBRARY flogger.lib
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/BUPplugin/group/TouchAnimDll.mmp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,36 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <platform_paths.hrh>
+
+
+TARGET PIProfilerTouchEventAnim.DLL
+UID 0x10003B22 0x2001E5B7
+TARGETTYPE ANI
+EPOCSTACKSIZE 0x5000
+VENDORID VID_DEFAULT
+CAPABILITY ALL -TCB // -AllFiles -NetworkControl -DiskAdmin -MultimediaDD -TCB -DRM
+SMPSAFE
+
+OS_LAYER_SYSTEMINCLUDE
+USERINCLUDE ../inc
+SOURCEPATH ../src
+
+SOURCE TouchEventAnimDll.cpp
+
+LIBRARY euser.lib
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/BUPplugin/group/bld.inf Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,21 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+PRJ_MMPFILES
+TouchAnimDll.mmp
+BUPPlugin.mmp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/BUPplugin/inc/BupPlugin.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,211 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef PIPROFILER_BUPECOM_SAMPLER_H
+#define PIPROFILER_BUPECOM_SAMPLER_H
+
+#include <w32std.h>
+#include <w32std.h> // RWsSession
+#include <w32adll.h> // RAnim DLL
+#include <e32std.h>
+#include <e32property.h> // RProperty
+
+#include <piprofiler/ProfilerTraces.h>
+#include <piprofiler/ProfilerConfig.h>
+#include <piprofiler/ProfilerVersion.h>
+#include <piprofiler/SamplerPluginInterface.h>
+#include <piprofiler/ProfilerGenericClassesUsr.h>
+
+#include <data_caging_path_literals.hrh> // for KDC_SHARED_LIB_DIR
+
+// Button press&touch event Anim DLL interface
+#include "TouchEventClientDll.h"
+
+// caption definitions
+_LIT8(KBUPShortName, "bup");
+_LIT8(KBUPLongName, "Button and touch event capture");
+_LIT8(KBUPDescription, "Button and touch event sampler\nTracing button and touch screen events\nHW dep: N/A\nSW dep: S60 3.0\n");
+
+const TUid KProfilerKeyEventPropertyCat={0x2001E5AD};
+enum TProfilerKeyEventPropertyKeys
+ {
+ EProfilerKeyEventPropertySample = 7
+ };
+
+const TUid KGppPropertyCat={0x20201F70};
+enum TGppPropertyKeys
+ {
+ EGppPropertySyncSampleNumber
+ };
+
+
+static _LIT_SECURITY_POLICY_PASS(KAllowAllPolicy);
+static _LIT_SECURITY_POLICY_C1(KCapabilityNone, ECapability_None);
+
+_LIT(KDllName, "PIProfilerTouchEventAnim.DLL"); // animation server dll on user disk
+
+/*
+ *
+ * BUP sampler definition
+ *
+ */
+class CProfilerButtonListener;
+class CSamplerPluginInterface;
+
+class CBupPlugin : public CSamplerPluginInterface
+{
+public:
+ static CBupPlugin* NewL(const TUid aImplementationUid, TAny* aInitParams);
+ ~CBupPlugin();
+
+ TInt ResetAndActivateL(CProfilerSampleStream& aStream);
+ TInt StopSampling();
+ TBool Enabled() { return iEnabled; }
+
+ TInt CreateFirstSample();
+
+ // no sub samplers, from CSamplerPluginInterface
+ TInt SubId(TUid /*aId*/) const {return KErrNotFound;}
+ TInt GetSamplerType();
+
+ void GetAttributesL(CArrayFixFlat<TSamplerAttributes>* aAttributes);
+ TInt SetAttributesL(TSamplerAttributes aAttributes);
+ void InitiateSamplerAttributesL();
+
+ TInt ConvertRawSettingsToAttributes(CDesC8ArrayFlat* aSingleSettingArray);
+
+ TInt DoSetSamplerSettings(CDesC8ArrayFlat* aAllSettings, TDesC8& aSamplerName, TInt aIndex);
+ void SaveSettingToAttributes(const TDesC8& aSetting, TInt aIndex);
+
+ TUid Id(TInt aSubId) const;
+
+ void FillThisStreamBuffer(TBapBuf* nextFree,TRequestStatus& aStatus);
+
+private:
+ CBupPlugin();
+ void ConstructL();
+
+private:
+ TUint8 iVersion[20];
+ TPtr8 iVersionDescriptor;
+
+ TInt iSamplerType;
+
+ CProfilerButtonListener* iButtonListener;
+ CArrayFixFlat<TSamplerAttributes>* iSamplerAttributes;
+public:
+ TUint32* iSampleTime;
+};
+
+
+/*
+*
+* Base class for all windows
+*
+*/
+class CWsClient : public CActive
+ {
+ protected:
+ //construct
+ CWsClient();
+ CWsScreenDevice* iScreen;
+ RWsSession iWs;
+ public:
+ void ConstructL();
+ // destruct
+ ~CWsClient();
+ // main window
+ virtual void ConstructMainWindowL();
+ // terminate cleanly
+ void Exit();
+ // active object protocol
+ void IssueRequest(); // request an event
+ void DoCancel(); // cancel the request
+ virtual TInt RunError(TInt aError) = 0;
+ virtual void RunL() = 0; // handle completed request
+ virtual void HandleKeyEventL (TKeyEvent& aKeyEvent) = 0;
+
+ RWindowGroup Group() {return iGroup;};
+
+ private:
+ RWindowGroup iGroup;
+ CWindowGc* iGc;
+ friend class CWindow; // needs to get at session
+ RProperty iProperty;
+
+ };
+
+
+
+class CWindow;
+
+class CProfilerButtonListener : public CWsClient
+{
+public:
+ static CProfilerButtonListener* NewL(CBupPlugin* aSamplerm);
+ ~CProfilerButtonListener();
+private:
+ CProfilerButtonListener(CBupPlugin* aSampler);
+
+
+public:
+ void ConstructMainWindowL();
+ void HandleKeyEventL (TKeyEvent& aKeyEvent);
+ void RunL();
+ TInt RunError(TInt aError);
+ TInt StartL();
+ TInt Stop();
+
+private:
+ TUint8 iSample[8];
+
+ CBupPlugin* iSampler;
+ RProfilerTouchEventAnim* iAnim;
+ RAnimDll* iAnimDll;
+ CWindow* iMainWindow; // main window
+
+ TInt iSampleStartTime;
+};
+
+
+
+/*
+*
+* CWindow declaration
+*
+*/
+class CWindow : public CBase
+ {
+ protected:
+ RWindow iWindow; // window server window
+ TRect iRect; // rectangle re owning window
+ public:
+ CWindow(CWsClient* aClient);
+ void ConstructL (const TRect& aRect, CWindow* aParent=0);
+ ~CWindow();
+ // access
+ RWindow& Window(); // our own window
+ CWindowGc* SystemGc(); // system graphics context
+
+ CWsClient* Client() {return iClient;};
+ private:
+ CWsClient* iClient; // client including session and group
+ };
+
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/BUPplugin/inc/TouchEventAnimDll.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,83 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef _PROFILER_TOUCH_EVENT_ANIM_DLL_
+#define _PROFILER_TOUCH_EVENT_ANIM_DLL_
+
+/*
+*
+* TouchEventAnimDll.h
+*
+*/
+
+// system includes
+#include <w32adll.h>
+#include <e32def.h>
+
+
+
+/*
+*
+* Class definition of CProfilerTouchEventAnim
+*
+*/
+class CProfilerTouchEventAnim : public CWindowAnim
+{
+public:
+ CProfilerTouchEventAnim();
+ virtual ~CProfilerTouchEventAnim();
+
+ // from CWindowAnim
+ void ConstructL(TAny* aAny, TBool aHasFocus);
+ void Redraw();
+ void FocusChanged(TBool aState);
+ // from MEventHandler
+ TBool OfferRawEvent(const TRawEvent& aRawEvent);
+ // from CAnim
+ void Animate(TDateTime* aDateTime);
+ void Command(TInt aOpcode, TAny* aArgs);
+ TInt CommandReplyL(TInt aOpcode, TAny* aArgs);
+
+private:
+ TBool HandlePointerDown(TPoint aPoint);
+ TBool HandlePointerUp(TPoint aPoint);
+ TBool HandleKeyDown(TInt aScanCode);
+ TBool HandleKeyUp(TInt aScanCode);
+private:
+ TInt iState;
+};
+
+
+/*
+*
+* Class definition of CProfilerTouchEventAnimDll
+*
+*/
+
+class CProfilerTouchEventAnimDll : public CAnimDll
+{
+public:
+ CProfilerTouchEventAnimDll();
+
+public:
+ IMPORT_C CAnim* CreateInstanceL(TInt aType);
+
+};
+
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/BUPplugin/inc/TouchEventClientDll.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,50 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef _PROFILER_TOUCH_EVENT_CLIENT_DLL__
+#define _PROFILER_TOUCH_EVENT_CLIENT_DLL__
+
+#include <w32adll.h>
+
+class CProfilerTouchEventControl;
+
+class RProfilerTouchEventAnim : public RAnim
+{
+ public:
+ RProfilerTouchEventAnim( RAnimDll& aAnimDll );
+ void ConstructL( const RWindow& aParent );
+
+ void Activate();
+ void Deactivate();
+
+
+ enum KAnimCommands
+ {
+ KActivate = 70002,
+ KDeactivate = 70003
+ };
+ /**
+ * Closes the animation object
+ */
+ void Close();
+
+ private:
+ CProfilerTouchEventControl* iTouchEventControl;
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/BUPplugin/sis/BupPlugin_S60-30.pkg Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,44 @@
+;
+; Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+; All rights reserved.
+; This component and the accompanying materials are made available
+; under the terms of "Eclipse Public License v1.0"
+; which accompanies this distribution, and is available
+; at the URL "http://www.eclipse.org/legal/epl-v10.html".
+;
+; Initial Contributors:
+; Nokia Corporation - initial contribution.
+;
+; Contributors:
+;
+; Description:
+;
+; ShapeImplementation_30_gcce.pkg
+;
+
+;Language - standard language definitions
+&EN
+
+; standard sis file header
+#{"Shape plugin"},(0xE01F614F),2,0,0
+
+
+;
+;Localised Vendor name
+;
+%{"Forum Nokia"}
+
+;
+;Unique Vendor name
+;
+:"Forum Nokia"
+
+;
+;Supports Series 60 v 3.0
+;
+[0x101F7961], 0, 0, 0, {"Series60ProductID"}
+
+
+;Files to include. Check the source paths they match your SDK setup.
+"\Symbian\9.1\S60_3rd_MR\Epoc32\release\gcce\urel\shapeimplementation.dll" - "!:\sys\bin\shapeimplementation.dll"
+"\Symbian\9.1\S60_3rd_MR\epoc32\data\Z\Resource\plugins\shapeimplementation.rsc" - "!:\Resource\Plugins\shapeimplementation.RSC"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/BUPplugin/src/BupPlugin.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,582 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include "BupPlugin.h"
+//#include <piprofiler/EngineUIDs.h>
+
+#include <w32std.h> // for listening key events
+
+
+// LITERALS
+// CONSTANTS
+const TUid KSamplerBupPluginUid = { 0x2001E5B6 };
+
+/*
+ *
+ * class CBupPlugin implementation
+ *
+ */
+
+CBupPlugin* CBupPlugin::NewL(const TUid /*aImplementationUid*/, TAny* /*aInitParams*/)
+ {
+ LOGTEXT(_L("CBupPlugin::NewL() - entry"));
+ CBupPlugin* self = new (ELeave) CBupPlugin();
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+ LOGTEXT(_L("CBupPlugin::NewL() - exit"));
+ return self;
+ }
+
+CBupPlugin::CBupPlugin() :
+ iVersionDescriptor(&(this->iVersion[1]),0,19),
+ iSamplerType(PROFILER_USER_MODE_SAMPLER)
+ {
+ iSamplerId = PROFILER_BUP_SAMPLER_ID;
+ iEnabled = EFalse;
+ LOGTEXT(_L("CBupPlugin::CBupPlugin() - konstruktori"));
+ }
+
+void CBupPlugin::ConstructL()
+ {
+ LOGTEXT(_L("CBupPlugin::ConstructL() - entry"));
+
+ // initiate sampler attributes array
+ iSamplerAttributes = new(ELeave) CArrayFixFlat<TSamplerAttributes>(1); // only one sampler
+
+ // insert default attributes to array
+ InitiateSamplerAttributesL();
+
+ LOGTEXT(_L("CBupPlugin::ConstructL() - exit"));
+ }
+
+
+CBupPlugin::~CBupPlugin()
+ {
+ LOGTEXT(_L("CBupPlugin::~CBupPlugin() - entry"));
+ if(iButtonListener)
+ {
+ // check if button listener still running
+ if(Enabled())
+ {
+ // stop profiling
+ iButtonListener->Stop();
+ }
+ delete iButtonListener;
+ }
+
+ if(iSamplerAttributes)
+ {
+ iSamplerAttributes->Reset();
+ }
+ delete iSamplerAttributes;
+
+ LOGTEXT(_L("CBupPlugin::~CBupPlugin() - exit"));
+ }
+
+TUid CBupPlugin::Id(TInt /*aUid*/) const
+ {
+ LOGSTRING2("CBupPlugin::Id():0x%X", KSamplerBupPluginUid.iUid );
+ return KSamplerBupPluginUid;
+ }
+
+void CBupPlugin::InitiateSamplerAttributesL()
+ {
+ // create sampler attribute container
+ TSamplerAttributes attr(KSamplerBupPluginUid.iUid,
+ KBUPShortName(),
+ KBUPLongName(),
+ KBUPDescription(),
+ -1,
+ ETrue,
+ EFalse,
+ 0); // default item count
+ this->iSamplerAttributes->AppendL(attr);
+ }
+
+// returns setting array
+void CBupPlugin::GetAttributesL(CArrayFixFlat<TSamplerAttributes>* aAttributes)
+ {
+ // append my own attributes to complete array, requested by profiler engine
+ aAttributes->AppendL(iSamplerAttributes->At(0));
+ }
+
+TInt CBupPlugin::SetAttributesL(TSamplerAttributes aAttributes)
+ {
+ TSamplerAttributes attr;
+
+ attr = iSamplerAttributes->At(0);
+ // if UIDs match replace the old
+ if(attr.iUid == aAttributes.iUid)
+ {
+ // replace the old attribute container
+ iSamplerAttributes->Delete(0);
+ iSamplerAttributes->InsertL(0, aAttributes);
+ return KErrNone;
+ }
+ return KErrNotFound;
+ }
+
+/*
+ * Method for parsing and transforming text array settings into TSamplerAttributes (per each sub sampler),
+ * called by CSamplerController class
+ *
+ * @param array of raw text setting lines, e.g. [gpp]\nenabled=true\nsampling_period_ms=1\n
+ */
+TInt CBupPlugin::ConvertRawSettingsToAttributes(CDesC8ArrayFlat* aAllSettingsArray)
+ {
+ // local literals
+ _LIT8(KBUPShort, "bup");
+
+ TInt err(KErrNone);
+ TBuf8<16> samplerSearchName;
+ samplerSearchName.Copy(KBUPShort);
+
+ // get sampler specific settings
+ err = DoSetSamplerSettings(aAllSettingsArray, samplerSearchName, 0);
+
+ // returns KErrNone if settings found, otherwise KErrNotFound
+ return err;
+ }
+
+TInt CBupPlugin::DoSetSamplerSettings(CDesC8ArrayFlat* aAllSettings, TDesC8& aSamplerName, TInt aIndex)
+ {
+ //
+ TBuf8<16> samplerSearch;
+ samplerSearch.Copy(KBracketOpen);
+ samplerSearch.Append(aSamplerName);
+ samplerSearch.Append(KBracketClose);
+
+ // read a line
+ for (TInt i(0); i<aAllSettings->MdcaCount(); i++)
+ {
+ // check if this line has a setting block start, i.e. contains [xxx] in it
+ if (aAllSettings->MdcaPoint(i).CompareF(samplerSearch) == 0)
+ {
+ // right settings block found, now loop until the next block is found
+ for(TInt j(i+1);j<aAllSettings->MdcaCount();j++)
+ {
+ // check if the next settings block was found
+ if(aAllSettings->MdcaPoint(j).Left(1).CompareF(KBracketOpen) != 0)
+ {
+ // save found setting value directly to its owners attributes
+ SaveSettingToAttributes(aAllSettings->MdcaPoint(j), aIndex);
+ }
+ else
+ {
+ // next block found, return KErrNone
+ return KErrNone;
+ }
+ }
+ }
+ }
+
+ return KErrNotFound;
+ }
+
+/**
+ * Method for setting a specific descriptor (from settings file) to attribute structure
+ *
+ * @param aSetting
+ * @param aName
+ */
+void CBupPlugin::SaveSettingToAttributes(const TDesC8& aSetting, TInt aIndex)
+ {
+ // find the equal mark from the setting line
+ TInt sepPos = aSetting.Find(KSettingItemSeparator);
+ // check that '=' is found
+ if (sepPos > 0)
+ {
+ // check that the element matches
+ if (aSetting.Left(sepPos).CompareF(KEnabled) == 0)
+ {
+ TBool en;
+ CSamplerPluginInterface::Str2Bool(aSetting.Right(aSetting.Length()-sepPos-1), en);
+ if(iSamplerAttributes->At(aIndex).iEnabled != en)
+ {
+ iSamplerAttributes->At(aIndex).iEnabled = en;
+ }
+ }
+ }
+ }
+
+TInt CBupPlugin::GetSamplerType()
+ {
+ return iSamplerType;
+ }
+
+TInt CBupPlugin::ResetAndActivateL(CProfilerSampleStream& aStream)
+ {
+ LOGTEXT(_L("CBupPlugin::ResetAndActivate() - entry"));
+ TInt ret(KErrNone);
+
+ // check if sampler enabled
+ if(iSamplerAttributes->At(0).iEnabled)
+ {
+ // create first the listener instance
+ iButtonListener = CProfilerButtonListener::NewL(this);
+
+ LOGTEXT(_L("CBupPlugin::ResetAndActivate() - listener created"));
+
+ iStream = &aStream;
+ TInt length = this->CreateFirstSample();
+ iVersion[0] = (TUint8)length;
+ LOGSTRING2("CBupPlugin::ResetAndActivate() - AddSample, length %d",length);
+ ret = AddSample(iVersion, length+1, 0);
+ if(ret != KErrNone)
+ return ret;
+
+ // activate button listener
+ ret = iButtonListener->StartL();
+
+ iEnabled = ETrue;
+
+ LOGTEXT(_L("CBupPlugin::ResetAndActivate() - exit"));
+ }
+ return ret;
+
+ }
+
+TInt CBupPlugin::CreateFirstSample()
+ {
+ LOGTEXT(_L("CBupPlugin::CreateFirstSample - entry"));
+ this->iVersionDescriptor.Zero();
+ this->iVersionDescriptor.Append(_L8("Bappea_BUP_V"));
+ this->iVersionDescriptor.Append(PROFILER_BUP_SAMPLER_VERSION);
+ LOGTEXT(_L("CBupPlugin::CreateFirstSample - exit"));
+ return (TInt)(this->iVersionDescriptor.Length());
+ }
+
+TInt CBupPlugin::StopSampling()
+ {
+ if(iButtonListener)
+ {
+ iButtonListener->Stop();
+ delete iButtonListener; // delete listener after every trace
+ iButtonListener = NULL;
+ }
+
+ // set disabled
+ iEnabled = EFalse;
+
+ return KErrNone;
+ }
+
+void CBupPlugin::FillThisStreamBuffer(TBapBuf* /*aBapBuf*/, TRequestStatus& /*aStatus*/)
+ {
+ }
+
+/*
+ *
+ * Implementation of class CProfilerButtonListener
+ *
+ */
+CProfilerButtonListener::CProfilerButtonListener(CBupPlugin* aSampler)
+ {
+ LOGTEXT(_L("CProfilerButtonListener::CProfilerButtonListener() - konstuktori"));
+ this->iSampler = aSampler;
+ iSampleStartTime = 0;
+ LOGTEXT(_L("CProfilerButtonListener::CProfilerButtonListener() - konstuktori exit"));
+ }
+
+CProfilerButtonListener* CProfilerButtonListener::NewL(CBupPlugin* aSampler)
+ {
+ LOGTEXT(_L("CProfilerButtonListener::NewL() - entry"));
+ CProfilerButtonListener* self = new (ELeave) CProfilerButtonListener(aSampler);
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+ LOGTEXT(_L("CProfilerButtonListener::NewL() - exit"));
+ return self;
+ }
+
+CProfilerButtonListener::~CProfilerButtonListener()
+ {
+ LOGTEXT(_L("CProfilerButtonListener::~CProfilerButtonListener() - entry af"));
+
+ if(iMainWindow)
+ {
+ LOGTEXT(_L("CProfilerButtonListener::~CProfilerButtonListener(): flushing iWs"));
+ iWs.Flush();
+ LOGTEXT(_L("CProfilerButtonListener::~CProfilerButtonListener(): finishing"));
+ }
+ delete iMainWindow;
+ LOGTEXT(_L("CProfilerButtonListener::~CProfilerButtonListener() - exit"));
+ }
+
+void CProfilerButtonListener::ConstructMainWindowL()
+ {
+ LOGTEXT(_L("CProfilerButtonListener::ConstructMainWindowL() - Entry"));
+
+ CWindow* window = new (ELeave) CWindow(this);
+ CleanupStack::PushL( window );
+ window->ConstructL(TRect(TPoint(0,0), TSize(0,0)));
+ delete iMainWindow;
+ iMainWindow = window;
+ CleanupStack::Pop( window );
+
+ LOGTEXT(_L("CProfilerButtonListener::ConstructMainWindowL() - Exit"));
+ }
+
+void CProfilerButtonListener::HandleKeyEventL (TKeyEvent& /*aKeyEvent*/)
+ {
+ LOGTEXT(_L("CProfilerButtonListener::HandleKeyEventL() - Start"));
+ LOGTEXT(_L("CProfilerButtonListener::HandleKeyEventL() - End"));
+ }
+
+
+TInt CProfilerButtonListener::RunError(TInt aError)
+ {
+ // get rid of everything we allocated
+ // deactivate the anim dll before killing window, otherwise anim dll dies too early
+ iAnim->Deactivate();
+ iAnim->Close();
+
+ iAnimDll->Close();
+
+ return aError;
+ }
+
+void CProfilerButtonListener::RunL()
+ {
+ // resubscribe before processing new value to prevent missing updates
+ IssueRequest();
+
+ TInt c = 0;
+ if(RProperty::Get(KProfilerKeyEventPropertyCat, EProfilerKeyEventPropertySample, c) == KErrNone)
+ {
+ // do something with event
+ LOGSTRING2("CProfilerButtonListener::RunL() - event [%d] received",c);
+
+ iSample[0] = c;
+ iSample[1] = c >> 8;
+ iSample[2] = c >> 16;
+ iSample[3] = c >> 24;
+
+ // Space for GPP sample time
+ TUint32 sampleTime = User::NTickCount() - iSampleStartTime;
+ LOGSTRING2("CProfilerButtonListener::RunL() - sample time is %d",sampleTime);
+
+ iSample[4] = sampleTime;
+ iSample[5] = sampleTime >> 8;
+ iSample[6] = sampleTime >> 16;
+ iSample[7] = sampleTime >> 24;
+
+ iSampler->AddSample(iSample, 8, 0xb0);
+ }
+ }
+
+TInt CProfilerButtonListener::StartL()
+ {
+ LOGTEXT(_L("CProfilerButtonListener::StartL() - Activate touch server dll"));
+ TInt err(KErrNone);
+
+ // get the property value
+ TInt r = RProperty::Get(KGppPropertyCat, EGppPropertySyncSampleNumber, iSampleStartTime);
+ if(r != KErrNone)
+ {
+ LOGSTRING2("CProfilerButtonListener::StartL() - getting iSyncOffset failed, error %d", r);
+ }
+
+ iAnimDll = new (ELeave) RAnimDll(iWs);
+ LOGTEXT(_L("CProfilerButtonListener::StartL() - #1"));
+
+ TParse* fp = new (ELeave) TParse();
+ CleanupStack::PushL(fp);
+ fp->Set( KDllName, &KDC_SHARED_LIB_DIR , NULL );
+ LOGSTRING2("CProfilerButtonListener::StartL() - touch event server: %S" , &(fp->FullName()));
+
+ err = iAnimDll->Load(fp->FullName());
+ // check if anim dll load failed
+ if(err != KErrNone)
+ {
+ CleanupStack::PopAndDestroy(fp);
+ // stop plugin if failed
+ iAnimDll->Close();
+ return KErrGeneral;
+ }
+ CleanupStack::PopAndDestroy(fp);
+ LOGTEXT(_L("CProfilerButtonListener::StartL() - #2"));
+
+ iAnim = new (ELeave) RProfilerTouchEventAnim(*iAnimDll);
+ LOGTEXT(_L("CProfilerButtonListener::StartL() - #3"));
+ iAnim->ConstructL(iMainWindow->Window());
+
+ // activate the animation dll for collecting touch and key events
+ iAnim->Activate();
+
+ // wait for a new sample
+ IssueRequest();
+
+ // hide this window group from the app switcher
+ iMainWindow->Client()->Group().SetOrdinalPosition(-1);
+ iMainWindow->Client()->Group().EnableReceiptOfFocus(EFalse);
+ return KErrNone;
+ }
+
+TInt CProfilerButtonListener::Stop()
+ {
+ LOGTEXT(_L("CProfilerButtonListener::Stop() - enter"));
+ // deactivate the anim dll before killing window, otherwise anim dll dies too early
+ iAnim->Deactivate();
+ iAnim->Close();
+
+ iAnimDll->Close();
+
+ Cancel();
+ LOGTEXT(_L("CProfilerButtonListener::Stop() - exit"));
+ return KErrNone;
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////
+////////////////////////// CWindow implementation /////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+CWindow::CWindow(CWsClient* aClient)
+: iClient(aClient)
+ {
+ LOGTEXT(_L("CWindow::CWindow()"));
+ }
+
+void CWindow::ConstructL (const TRect& aRect, CWindow* aParent)
+ {
+ LOGTEXT(_L("CWindow::ConstructL(): Start"));
+
+ // If a parent window was specified, use it; if not, use the window group
+ // (aParent defaults to 0).
+ RWindowTreeNode* parent= aParent ? (RWindowTreeNode*) &(aParent->Window()) : &(iClient->iGroup);
+ iWindow=RWindow(iClient->iWs); // use app's session to window server
+ User::LeaveIfError(iWindow.Construct(*parent,(TUint32)this));
+ LOGSTRING2("CWindow::ConstructL(): Start - window handle is: 0x%08x", this);
+ iRect = aRect;
+ iWindow.SetExtent(iRect.iTl, iRect.Size()); // set extent relative to group coords
+ iWindow.Activate(); // window is now active
+ LOGTEXT(_L("CWindow::ConstructL(): End"));
+ }
+
+
+CWindow::~CWindow()
+ {
+ LOGTEXT(_L("CWindow::~CWindow(): Start"));
+ iWindow.Close(); // close our window
+ LOGTEXT(_L("CWindow::~CWindow(): End"));
+ }
+
+RWindow& CWindow::Window()
+ {
+ LOGTEXT(_L("CWindow::Window()"));
+ return iWindow;
+ }
+
+CWindowGc* CWindow::SystemGc()
+ {
+ LOGTEXT(_L("CWindow::SystemGc()"));
+ return iClient->iGc;
+ }
+
+/////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////// CWsClient implementation ////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////
+CWsClient::CWsClient()
+: CActive(CActive::EPriorityStandard)
+ {
+ LOGTEXT(_L("CWsClient::CWsClient()"));
+ }
+
+void CWsClient::ConstructL()
+ {
+ LOGTEXT(_L("CWsClient::ConstructL() - Start"));
+ TInt r = RProperty::Define(EProfilerKeyEventPropertySample, RProperty::EInt, KAllowAllPolicy, KCapabilityNone);
+ if (r!=KErrAlreadyExists)
+ {
+ User::LeaveIfError(r);
+ }
+
+ CActiveScheduler::Add(this);
+
+ // attach to
+ User::LeaveIfError(iProperty.Attach(KProfilerKeyEventPropertyCat,EProfilerKeyEventPropertySample));
+
+ // get a session going
+ User::LeaveIfError(iWs.Connect());
+
+ // construct screen device and graphics context
+ iScreen=new (ELeave) CWsScreenDevice(iWs); // make device for this session
+ User::LeaveIfError(iScreen->Construct( 0 )); // and complete its construction
+ User::LeaveIfError(iScreen->CreateContext(iGc)); // create graphics context
+
+ // construct our one and only window group
+ iGroup=RWindowGroup(iWs);
+ User::LeaveIfError(iGroup.Construct((TInt)this, EFalse)); // meaningless handle; enable focus
+
+ // construct main window
+ ConstructMainWindowL();
+
+ LOGTEXT(_L("CWsClient::CWsClient() - End"));
+ }
+
+CWsClient::~CWsClient()
+ {
+ LOGTEXT(_L("CWsClient::~CWsClient() - Start"));
+
+ // get rid of everything we allocated
+ delete iGc;
+ delete iScreen;
+
+ iGroup.Close();
+ // finish with window server
+ iWs.Close();
+
+ LOGTEXT(_L("CWsClient::~CWsClient() - Exit"));
+ }
+
+void CWsClient::Exit()
+ {
+ LOGTEXT(_L("CWsClient::Exit() - Start"));
+
+ // destroy window group
+ iGroup.Close();
+ // finish with window server
+ iProperty.Close();
+ iWs.Close();
+ LOGTEXT(_L("CWsClient::Exit() - Exit"));
+ }
+
+void CWsClient::IssueRequest()
+ {
+ LOGTEXT(_L("CWsClient::IssueRequest() - Start"));
+ iProperty.Subscribe( iStatus );
+ SetActive(); // so we're now active
+ LOGTEXT(_L("CWsClient::IssueRequest() - Exit"));
+ }
+
+void CWsClient::DoCancel()
+ {
+ LOGTEXT(_L("CWsClient::DoCancel() - Start"));
+ // clean up the sample property
+ iProperty.Cancel();
+ iProperty.Close();
+ LOGTEXT(_L("CWsClient::DoCancel() - Exit"));
+ }
+
+void CWsClient::ConstructMainWindowL()
+ {
+ LOGTEXT(_L("CWsClient::ConstructMainWindowL()"));
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/BUPplugin/src/BupPluginImplementationTable.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,39 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+// INCLUDE FILES
+#include <e32std.h>
+#include <ecom/implementationproxy.h>
+
+#include "BupPlugin.h"
+
+
+// Provides a key value pair table, this is used to identify
+// the correct construction function for the requested interface.
+const TImplementationProxy ImplementationTable[] =
+{
+ IMPLEMENTATION_PROXY_ENTRY(0x2001E5B6, CBupPlugin::NewL)
+};
+
+// Function used to return an instance of the proxy table.
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+{
+ aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
+ return ImplementationTable;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/BUPplugin/src/TouchEventAnimDll.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,205 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+#include <e32base.h>
+#include <e32cons.h>
+#include <w32std.h>
+#include <in_sock.h>
+#include <txtfrmat.h>
+#include <e32property.h>
+#include <piprofiler/ProfilerTraces.h>
+
+// user includes
+#include "TouchEventAnimDll.h"
+
+// control commands
+static const TInt KActivate = 70002;
+static const TInt KDeactivate = 70003;
+
+// touch events
+static const TInt KTouchEventDown = 69999;
+static const TInt KTouchEventUp = 70000;
+
+static const TInt KUpEventOffset = 70000;
+
+_LIT( KTouchEventServer, "PIProfilerTouchEvent server" );
+enum TAnimationPanics
+ {
+ EProfilerTouchEventServerPanic = 100
+ };
+
+const TUid KProfilerKeyEventPropertyCat={0x2001E5AD};
+enum TProfilerKeyEventPropertyKeys
+ {
+ EProfilerKeyEventPropertySample = 7
+ };
+
+/*
+*
+* Implementation of CProfilerTouchEventAnim
+*
+*/
+CProfilerTouchEventAnim::CProfilerTouchEventAnim() : iState(EFalse)
+ {
+ LOGTEXT(_L("CProfilerTouchEventAnim::CProfilerTouchEventAnim - entry"));
+ }
+
+CProfilerTouchEventAnim::~CProfilerTouchEventAnim()
+ {
+ LOGTEXT(_L("CProfilerTouchEventAnim::~CProfilerTouchEventAnim - entry"));
+ //iFunctions->GetRawEvents( EFalse ); // disable capture
+ LOGTEXT(_L("CProfilerTouchEventAnim::~CProfilerTouchEventAnim - exit"));
+ }
+
+void CProfilerTouchEventAnim::ConstructL(TAny* /*aArgs*/, TBool /*aHasFocus*/)
+ {
+ LOGTEXT(_L("CProfilerTouchEventAnim::ConstructL - entry"));
+ iFunctions->GetRawEvents( ETrue );
+ LOGTEXT(_L("CProfilerTouchEventAnim::ConstructL - exit"));
+ }
+
+void CProfilerTouchEventAnim::Command(TInt /*aOpcode*/, TAny* /*aArgs*/)
+ {
+
+ }
+
+TInt CProfilerTouchEventAnim::CommandReplyL(TInt aOpcode, TAny* /*aArgs*/)
+ {
+ LOGSTRING2("CProfilerTouchEventAnim::CommandReplyL - entry, aOpcode: %d", aOpcode);
+ switch(aOpcode)
+ {
+ case KActivate: // activate
+ iState = ETrue;
+ LOGTEXT(_L("CProfilerTouchEventAnim::CommandReplyL - activate"));
+ break;
+ case KDeactivate: // deactivate
+ iState = EFalse;
+ iFunctions->GetRawEvents( EFalse ); // disable capture
+ LOGTEXT(_L("CProfilerTouchEventAnim::CommandReplyL - deactivate"));
+ break;
+ default:
+ User::Panic( KTouchEventServer, EProfilerTouchEventServerPanic );
+ LOGSTRING2("CProfilerTouchEventAnim::CommandReplyL - panic, code %d", EProfilerTouchEventServerPanic);
+ return EProfilerTouchEventServerPanic;
+
+ }
+ return KErrNone;
+ }
+
+
+TBool CProfilerTouchEventAnim::OfferRawEvent(const TRawEvent& aRawEvent)
+ {
+ LOGTEXT(_L("CProfilerTouchEventAnim::OfferRawEvent - entry"));
+ if(iState == EFalse)
+ return EFalse; // if not activated yet just pass through
+
+
+ switch(aRawEvent.Type())
+ {
+ // handle the pointer events here
+ case TRawEvent::EButton1Down:
+ {
+ LOGTEXT(_L("CProfilerTouchEventAnim::OfferRawEvent - pointer down"));
+ return HandlePointerDown(aRawEvent.Pos());
+ }
+ case TRawEvent::EButton1Up:
+ {
+ LOGTEXT(_L("CProfilerTouchEventAnim::OfferRawEvent - pointer up"));
+ return HandlePointerUp(aRawEvent.Pos());
+ }
+
+ // handle the key events here, replacing the BUP trace functionality
+ case TRawEvent::EKeyDown:
+ {
+ TInt scan = aRawEvent.ScanCode() & 0xFFFF;
+ return HandleKeyDown(scan);
+ }
+ case TRawEvent::EKeyUp:
+ {
+ TInt scan = (aRawEvent.ScanCode() & 0xFFFF)+KUpEventOffset; //
+ return HandleKeyUp(scan);
+ }
+ default:
+ return EFalse; // no action
+ }
+ }
+
+TBool CProfilerTouchEventAnim::HandlePointerDown( TPoint /*aPoint*/ )
+ {
+ RProperty::Set(KProfilerKeyEventPropertyCat,EProfilerKeyEventPropertySample, KTouchEventDown);
+ return EFalse;
+ }
+
+TBool CProfilerTouchEventAnim::HandlePointerUp( TPoint /*aPoint*/ )
+ {
+ RProperty::Set(KProfilerKeyEventPropertyCat,EProfilerKeyEventPropertySample, KTouchEventUp);
+ return EFalse;
+ }
+
+TBool CProfilerTouchEventAnim::HandleKeyDown( TInt aScanCode )
+ {
+ LOGSTRING2("CProfilerTouchEventAnim::HandleKeyDown - scancode = %d", aScanCode);
+ RProperty::Set(KProfilerKeyEventPropertyCat,EProfilerKeyEventPropertySample, aScanCode);
+ return EFalse;
+ }
+
+TBool CProfilerTouchEventAnim::HandleKeyUp( TInt aScanCode )
+ {
+ LOGSTRING2("CProfilerTouchEventAnim::HandleKeyUp - scancode = %d", aScanCode);
+ RProperty::Set(KProfilerKeyEventPropertyCat,EProfilerKeyEventPropertySample, aScanCode);
+ return EFalse;
+ }
+
+
+void CProfilerTouchEventAnim::Animate(TDateTime* /*aDateTime*/)
+ {
+ }
+
+void CProfilerTouchEventAnim::Redraw()
+ {
+ }
+
+void CProfilerTouchEventAnim::FocusChanged(TBool /*aState*/)
+ {
+ }
+
+
+/*
+*
+* Implementation of CProfilerTouchEventAnimDll
+*
+*/
+CProfilerTouchEventAnimDll::CProfilerTouchEventAnimDll() : CAnimDll()
+ {
+ }
+
+CAnim* CProfilerTouchEventAnimDll::CreateInstanceL(TInt /*aType*/)
+ {
+ LOGTEXT(_L("CProfilerTouchEventAnimDll::CreateInstanceL - entry"));
+ return (new (ELeave) CProfilerTouchEventAnim());
+ }
+
+
+// DLL entry
+EXPORT_C CAnimDll* CreateCAnimDllL()
+ {
+ return (new (ELeave) CProfilerTouchEventAnimDll);
+ }
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/BUPplugin/src/TouchEventClientDll.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,60 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include "TouchEventClientDll.h"
+#include <piprofiler/ProfilerTraces.h>
+
+/*
+ *
+ * class RProfilerTouchEventAnim implementation
+ *
+ */
+void RProfilerTouchEventAnim::ConstructL( const RWindow& aParent)
+{
+ LOGTEXT(_L("RProfilerTouchEventAnim::ConstructL - entry"));
+ LOGTEXT(_L("RProfilerTouchEventAnim::ConstructL - calling RAnim::Construct..."));
+ RAnim::Construct(aParent, 0, TPtrC8());
+}
+
+
+RProfilerTouchEventAnim::RProfilerTouchEventAnim( RAnimDll &aAnimDll ) :
+ RAnim( aAnimDll )
+{
+}
+
+void RProfilerTouchEventAnim::Activate()
+{
+ LOGTEXT(_L("RProfilerTouchEventAnim::Activate - entry"));
+ TInt err = RAnim::CommandReply(KActivate);
+ LOGSTRING2("RProfilerTouchEventAnim::Activate - error: %d", err);
+}
+
+void RProfilerTouchEventAnim::Deactivate()
+{
+ LOGTEXT(_L("RProfilerTouchEventAnim::Deactivate - entry"));
+ TInt err = RAnim::CommandReply(KDeactivate);
+ LOGSTRING2("RProfilerTouchEventAnim::Deactivate - error: %d", err);
+}
+
+void RProfilerTouchEventAnim::Close()
+ {
+ RAnim::Close();
+ }
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/DebugOutputWriterPlugin/data/2001E5BA.rss Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,51 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <ecom/registryinfo.rh>
+
+// Declares info for two implementations
+RESOURCE REGISTRY_INFO theInfo
+ {
+ // UID for the DLL. See mmp files
+ //__SERIES60_3X__ can't be used in resource files
+ dll_uid = 0x2001E5BA;
+
+ // Declare array of interface info. This dll contains implementations for
+ // only one interface (CSamplerInterfaceDefinition).
+ interfaces =
+ {
+ INTERFACE_INFO
+ {
+ // UID of interface that is implemented
+ interface_uid = 0x2001E5BD;
+
+ implementations =
+ {
+ IMPLEMENTATION_INFO
+ {
+ implementation_uid = 0x2001E5BA;
+
+ version_no = 1;
+ display_name = "Debug output writer implementation";
+ default_data = "dow";
+ opaque_data = "1";
+ }
+ };
+ }
+ };
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/DebugOutputWriterPlugin/group/DebOutWriterPlugin.mmp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,51 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <platform_paths.hrh>
+
+
+TARGET PIProfilerDebugWriter.dll
+TARGETTYPE PLUGIN
+UID 0x10009D8D 0x2001E5BA
+#ifdef WINSCW
+VENDORID 0
+#else
+VENDORID VID_DEFAULT
+#endif
+CAPABILITY ALL -TCB // AllFiles ReadDeviceData ReadUserData UserEnvironment WriteDeviceData WriteUserData
+SMPSAFE
+
+OS_LAYER_SYSTEMINCLUDE
+USERINCLUDE ../inc ../traces
+#ifdef OST_TRACE_COMPILER_IN_USE
+USERINCLUDE ../traces
+#endif
+SOURCEPATH ../src
+
+START RESOURCE ../data/2001E5BA.rss
+TARGET piprofilerdebugwriter.rsc
+END
+
+SOURCE DebOutWriterPlugin.cpp
+SOURCE DebOutWriterPluginImplementationTable.cpp
+
+LIBRARY euser.lib
+LIBRARY ECom.lib
+LIBRARY EFSRV.LIB
+LIBRARY commonengine.lib
+LIBRARY flogger.lib
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/DebugOutputWriterPlugin/group/bld.inf Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,20 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+PRJ_MMPFILES
+DebOutWriterPlugin.mmp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/DebugOutputWriterPlugin/inc/DebOutWriterPlugin.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,137 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+// This file defines the API for DebOutWriterPlugin.dll
+
+#ifndef __DEBOUTWRITERPLUGIN_H__
+#define __DEBOUTWRITERPLUGIN_H__
+
+// Include Files
+#include <w32std.h>
+#include <piprofiler/WriterPluginInterface.h>
+#include <piprofiler/ProfilerGenericClassesUsr.h>
+#include <e32base.h> // CBase
+#include <e32std.h> // TBuf
+#include <e32property.h>
+
+#ifdef OST_TRACE_COMPILER_IN_USE
+// trace core ldd activation/deactivation interface
+#include <TcDriverIf.h>
+
+// trace core ldd global definitions
+_LIT( KTcLdd, "tcldd.ldd" );
+GLDEF_D RTcDriver tcldd;
+
+#endif
+
+_LIT(KDebOutShortName, "dow");
+
+// forward declarations
+class CDebOutWriterHandler;
+
+// Class Definitions
+
+class CDebOutWriterPlugin : public CWriterPluginInterface
+ {
+public:
+ // new function
+ static CDebOutWriterPlugin* NewL(const TUid aImplementationUid, TAny* /*aInitParams*/);
+ ~CDebOutWriterPlugin();
+
+ void DoCancel();
+ static void PrintDescriptorAsBase64(TDesC8& aDes, TRequestStatus* aStatus, TUint32 sampleTime, TBool aEmptying);
+
+public: // new functions
+
+ TInt Start();
+
+ void Stop();
+
+ void GetValue( const TWriterPluginValueKeys aKey, TDes& aValue );
+
+ void SetValue( const TWriterPluginValueKeys aKey, TDes& aValue );
+
+ TUid Id() const;
+
+ void GetWriterVersion(TDes* aDes);
+
+ TUint32 GetWriterType();
+
+ void SetStream(CProfilerSampleStream& aStream) { iStream = &aStream; }
+
+ void HandleError(TInt aError);
+
+ void WriteData();
+private: // new functions
+ CDebOutWriterPlugin(const TUid aImplementationUid);
+ void ConstructL();
+
+ void GetValueL( const TWriterPluginValueKeys aKey, TDes& aValue );
+ void SetValueL( const TWriterPluginValueKeys aKey, TDes& aValue );
+ TBool GetEnabled();
+public:
+ CProfilerSampleStream* iStream;
+private: // data
+ TBapBuf* iBufferBeingWritten;
+
+ TInt iWriterType;
+ TInt iWriterId;
+ CDebOutWriterHandler* iWriterHandler;
+ RProperty iErrorStatus;
+
+ };
+
+/*
+ *
+ * Definition of class CDebOutWriterHandler
+ *
+ */
+class CDebOutWriterHandler : public CActive
+ {
+public:
+
+
+ static CDebOutWriterHandler* NewL(CDebOutWriterPlugin* aWriter);
+ ~CDebOutWriterHandler();
+ void DoCancel();
+ void StartL();
+
+ void Stop();
+
+ void Reset();
+private:
+ CDebOutWriterHandler(CDebOutWriterPlugin* aWriter);
+
+ void ConstructL();
+ void RunL();
+
+ void WriteBufferToOutput(TBapBuf* aBuf);
+ void PrintBufferToOutput(TBapBuf* aBuffer, TRequestStatus& aStatus);
+ void HandleFullBuffers();
+private:
+ CDebOutWriterPlugin* iWriter;
+ RFile iFile;
+ RFs iFs;
+ TBuf<256> iFileName;
+// CPeriodic* iTimer;
+ TBapBuf* iBufferBeingWritten;
+ TBool iStopping;
+ };
+
+#endif // __DEBOUTWRITERPLUGIN_H__
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/DebugOutputWriterPlugin/sis/DebOutWriterPlugin_EKA2.pkg Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,36 @@
+;
+; Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+; All rights reserved.
+; This component and the accompanying materials are made available
+; under the terms of "Eclipse Public License v1.0"
+; which accompanies this distribution, and is available
+; at the URL "http://www.eclipse.org/legal/epl-v10.html".
+;
+; Initial Contributors:
+; Nokia Corporation - initial contribution.
+;
+; Contributors:
+;
+; Description:
+;
+; Installation file for DebOutWriterPlugin dll
+;
+; This is an auto-generated PKG file by Carbide.
+; This file uses variables specific to Carbide builds that will not work
+; on command-line builds. If you want to use this generated PKG file from the
+; command-line tools you will need to modify the variables with the appropriate
+; values: $(EPOCROOT), $(PLATFORM), $(TARGET)
+
+;
+; UID is the dll's UID
+;
+#{"DebOutWriterPlugin DLL"},(0x00DA58C7),1,0,0
+
+
+;Localised Vendor name
+%{"Vendor-EN"}
+
+;Unique Vendor name
+:"Vendor"
+
+"$(EPOCROOT)Epoc32\release\$(PLATFORM)\$(TARGET)\DebOutWriterPlugin.dll" -"!:\sys\bin\DebOutWriterPlugin.dll"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/DebugOutputWriterPlugin/src/DebOutWriterPlugin.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,542 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+// Include Files
+
+#include "DebOutWriterPlugin.h"
+#include <e32base.h>
+//#include <piprofiler/EngineUIDs.h>
+#include <piprofiler/ProfilerTraces.h>
+#ifdef OST_TRACE_COMPILER_IN_USE
+#include <OpenSystemTrace.h>
+#include "DebOutWriterPluginTraces.h"
+#endif
+
+// engine properties
+const TUid KEngineStatusPropertyCat={0x2001E5AD};
+enum TEnginePropertyKeys
+ {
+ EProfilerEngineStatus = 8,
+ EProfilerErrorStatus
+ };
+
+// CONSTANTS
+// own UID
+const TUid KDebOutWriterPluginUid = { 0x2001E5BA };
+
+// Member Functions
+/*
+ *
+ * Class CDebOutWriterPlugin implementation
+ *
+ */
+
+CDebOutWriterPlugin* CDebOutWriterPlugin::NewL(const TUid /*aImplementationUid*/, TAny* /*aInitParams*/)
+{
+ LOGTEXT(_L("CDebOutWriterPlugin::NewL() - entry"));
+ CDebOutWriterPlugin* self = new (ELeave) CDebOutWriterPlugin(KDebOutWriterPluginUid);
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+ LOGTEXT(_L("CDebOutWriterPlugin::NewL() - exit"));
+ return self;
+}
+
+CDebOutWriterPlugin::CDebOutWriterPlugin(const TUid aImplementationUid) :
+ iWriterType(aImplementationUid.iUid)
+ {
+ LOGTEXT(_L("CDebOutWriterPlugin::CDebOutWriterPlugin - entry"));
+ isEnabled = EFalse;
+ iWriterId = Id().iUid;
+ LOGTEXT(_L("CDebOutWriterPlugin::CDebOutWriterPlugin - exit"));
+ }
+
+CDebOutWriterPlugin::~CDebOutWriterPlugin()
+ {
+ LOGTEXT(_L("CDebOutWriterPlugin::~CDebOutWriterPlugin - entry"));
+
+ iErrorStatus.Close();
+
+ if(iWriterHandler)
+ {
+ iWriterHandler->Cancel();
+ delete iWriterHandler;
+ }
+ LOGTEXT(_L("CDebOutWriterPlugin::~CDebOutWriterPlugin - exit"));
+ }
+
+void CDebOutWriterPlugin::ConstructL()
+ {
+ // second phase constructor, anything that may leave must be constructed here
+
+ LOGTEXT(_L("CDebOutWriterPlugin::ConstructL() - entry"));
+ iWriterHandler = CDebOutWriterHandler::NewL(this);
+ User::LeaveIfError(iErrorStatus.Attach(KEngineStatusPropertyCat, EProfilerErrorStatus));
+
+ LOGTEXT(_L("CDebOutWriterPlugin::ConstructL() - exit"));
+ }
+
+TInt CDebOutWriterPlugin::Start()
+ {
+ LOGTEXT(_L("CDebOutWriterPlugin::Start() - entry"));
+
+#ifdef OST_TRACE_COMPILER_IN_USE
+ TInt err(KErrNone);
+ // activate traces on TraceCore
+ RTcDriverParameters tcdp_ThreadIdentification;
+ tcdp_ThreadIdentification.iComponentId = KOstTraceComponentID;
+ tcdp_ThreadIdentification.iGroupId = CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64START;
+ err = tcldd.ActivateTrace(tcdp_ThreadIdentification);
+
+ tcdp_ThreadIdentification.iGroupId = CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64LINE;
+ err = tcldd.ActivateTrace(tcdp_ThreadIdentification);
+
+ tcdp_ThreadIdentification.iGroupId = CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64FIN;
+ err = tcldd.ActivateTrace(tcdp_ThreadIdentification);
+
+ tcdp_ThreadIdentification.iGroupId = CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64END;
+ err = tcldd.ActivateTrace(tcdp_ThreadIdentification);
+
+ RDebug::Print(_L("Debug output activated"));
+ if(err != KErrNone)
+ RDebug::Print(_L("TraceCore LDD API responded: %d"), err);
+#endif
+
+ LOGTEXT(_L("CDebOutWriterPlugin::Start() - exit"));
+ return KErrNone;
+ }
+
+void CDebOutWriterPlugin::Stop()
+ {
+ LOGTEXT(_L("CDebOutWriterPlugin::Stop() - entry"));
+ iWriterHandler->Stop();
+#ifdef OST_TRACE_COMPILER_IN_USE
+ TInt err(KErrNone);
+ // activate traces on TraceCore
+ RTcDriverParameters tcdp_ThreadIdentification;
+ tcdp_ThreadIdentification.iComponentId = KOstTraceComponentID;
+ tcdp_ThreadIdentification.iGroupId = CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64START;
+ err = tcldd.DeactivateTrace(tcdp_ThreadIdentification);
+
+ tcdp_ThreadIdentification.iGroupId = CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64LINE;
+ err = tcldd.DeactivateTrace(tcdp_ThreadIdentification);
+
+ tcdp_ThreadIdentification.iGroupId = CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64FIN;
+ err = tcldd.DeactivateTrace(tcdp_ThreadIdentification);
+
+ tcdp_ThreadIdentification.iGroupId = CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64END;
+ err = tcldd.DeactivateTrace(tcdp_ThreadIdentification);
+
+ RDebug::Print(_L("Debug output deactivated"));
+ if(err != KErrNone)
+ RDebug::Print(_L("TraceCore LDD API responded: %d"), err);
+#endif
+ LOGTEXT(_L("CDebOutWriterPlugin::Stop() - exit"));
+ }
+
+TUid CDebOutWriterPlugin::Id() const
+ {
+ LOGSTRING2("CDebOutWriterPlugin::Id(): 0x%X", KDebOutWriterPluginUid.iUid );
+ return KDebOutWriterPluginUid;
+ //return iDtor_ID_Key;
+ }
+
+TBool CDebOutWriterPlugin::GetEnabled()
+ {
+ return isEnabled;
+ }
+
+void CDebOutWriterPlugin::SetValue( const TWriterPluginValueKeys aKey,
+ TDes& aValue )
+ {
+ TRAP_IGNORE( SetValueL( aKey, aValue ) );
+ }
+
+
+void CDebOutWriterPlugin::GetValue( const TWriterPluginValueKeys aKey,
+ TDes& aValue )
+ {
+ TRAP_IGNORE( GetValueL( aKey, aValue ) );
+ }
+
+
+
+void CDebOutWriterPlugin::SetValueL( const TWriterPluginValueKeys aKey, TDes& /*aValue*/ )
+{
+ LOGTEXT(_L("CDebOutWriterPlugin::SetValueL - entry"));
+
+ switch( aKey )
+ {
+ case EWriterPluginEnabled:
+ isEnabled = ETrue;
+ LOGTEXT(_L("CDebOutWriterPlugin::SetValueL - plugin enabled"));
+ break;
+ case EWriterPluginDisabled:
+ isEnabled = EFalse;
+ LOGTEXT(_L("CDebOutWriterPlugin::SetValueL - plugin disabled"));
+ break;
+ case EWriterPluginSettings:
+ //result = StringLoader::LoadL(PROFILER_KERNEL_MODE_SAMPLER);
+ LOGTEXT(_L("CDebOutWriterPlugin::SetValueL - setting plugin settings"));
+ break;
+ default:
+ break;
+ }
+ LOGTEXT(_L("CDebOutWriterPlugin::SetValueL - exit"));
+
+}
+
+TUint32 CDebOutWriterPlugin::GetWriterType()
+ {
+ return iWriterType;
+ }
+
+
+void CDebOutWriterPlugin::GetValueL( const TWriterPluginValueKeys aKey, TDes& aValue )
+ {
+ switch( aKey )
+ {
+ case EWriterPluginVersion:
+
+ GetWriterVersion(&aValue);
+ break;
+ case EWriterPluginType:
+ break;
+ default:
+ break;
+ }
+ }
+
+void CDebOutWriterPlugin::GetWriterVersion(TDes* aDes)
+ {
+ _LIT(KDebugOutputWriterVersion, "1.0.0");
+ aDes->Append(KDebugOutputWriterVersion);
+ }
+
+void CDebOutWriterPlugin::DoCancel()
+{
+ LOGTEXT(_L("CDebOutWriterPlugin::DoCancel - entry"));
+}
+
+void CDebOutWriterPlugin::WriteData()
+ {
+ // Activate handler to write data from buffer to output
+ LOGTEXT(_L("CDiskWriterPlugin::WriteData() - entry"));
+ TRAP_IGNORE(iWriterHandler->StartL());
+ LOGTEXT(_L("CDiskWriterPlugin::WriteData() - exit"));
+ }
+
+void CDebOutWriterPlugin::HandleError(TInt aError)
+ {
+ TInt err(KErrNone);
+ err = iErrorStatus.Set(aError);
+ if(err != KErrNone)
+ {
+ RDebug::Print(_L("CDiskWriterPlugin::HandleError() - error: %d"), err);
+ }
+ }
+
+void CDebOutWriterPlugin::PrintDescriptorAsBase64( TDesC8& aDes,
+ TRequestStatus* aStatus,
+ TUint32 sampleTime,
+ TBool aEmptying)
+{
+ LOGTEXT(_L("CDebOutWriterPlugin::PrintDescriptorAsBase64() - entry"));
+ TUint len = aDes.Length();
+
+ // we must wait for the sample tick to be printed, in case
+ // prints are performed at user side, otherwise the kernel
+ // prints will corrupt the data
+ if(sampleTime != 0xffffffff)
+ {
+ TUint32 remains = sampleTime%1000;
+
+ if(remains > 800)
+ {
+ TTimeIntervalMicroSeconds32 timeToWait = ((1050-remains)*1000);
+ User::After(timeToWait);
+ }
+ }
+
+ TBuf16<75> buf;
+
+ // Header
+#ifdef OST_TRACE_COMPILER_IN_USE
+ OstTrace0( PIPROFILER_TRACE_OUT, CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64START,
+ "<PIPROF>=================================================================" );
+#else
+ RDebug::Print(_L("<PIPROF>================================================================="));
+#endif
+ buf.Zero();
+
+ // base64 encoding table
+ const char uu_base64[64] =
+ {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
+ 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+ 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+ 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+ 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
+ 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+ 'w', 'x', 'y', 'z', '0', '1', '2', '3',
+ '4', '5', '6', '7', '8', '9', '+', '/'
+ };
+
+ TChar byte1, byte2, byte3, byte4;
+ TUint8 count = 0x30;
+ // base64 encoding
+ for(TUint i = 0, j = 0; i < len; i += 3, j = (j + 1) % 18)
+ {
+ // byte 1
+ byte1 = uu_base64[(aDes[i] >> 2) & 0x3F];
+
+ // byte 2
+ if(i+1 < len)
+ byte2 = uu_base64[(aDes[i] << 4) & 0x3f | (aDes[i+1] >> 4)];
+ else
+ byte2 = uu_base64[(aDes[i] << 4) & 0x3f];
+
+ // byte 3
+ if(i+1 < len && i+2 < len)
+ byte3 = uu_base64[(aDes[i+1] << 2) & 0x3f | (aDes[i+2] >> 6)];
+ else if(i+1 < len)
+ byte3 = uu_base64[(aDes[i+1] << 2) & 0x3f];
+ else
+ byte3 = '=';
+
+ // byte 4
+ if(i+2 < len)
+ byte4 = uu_base64[aDes[i+2] & 0x3f];
+ else
+ byte4 = '=';
+
+ // append to buffer
+ buf.Append(byte1);
+ buf.Append(byte2);
+ buf.Append(byte3);
+ buf.Append(byte4);
+
+ // output 72 chars / line
+ if(j == 17)
+ {
+ // add check number at the end of line
+ buf.Append(count);
+#ifdef OST_TRACE_COMPILER_IN_USE
+ OstTraceExt1( PIPROFILER_TRACE_OUT, CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64LINE, "<PIPROF>%S", &buf );
+#else
+ RDebug::Print(_L("<PIPROF>%S"),&buf);
+#endif
+ count++;
+ if(count > 0x39)
+ count = 0x30;
+ buf.Zero();
+ }
+ }
+
+#ifdef OST_TRACE_COMPILER_IN_USE
+ OstTraceExt1( PIPROFILER_TRACE_OUT, CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64FIN, "<PIPROF>%S", &buf );
+#else
+ RDebug::Print(_L("<PIPROF>%S"),&buf);
+#endif
+ buf.Zero();
+
+ // footer
+#ifdef OST_TRACE_COMPILER_IN_USE
+ OstTrace0( PIPROFILER_TRACE_OUT, CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64END,
+ "<PIPROF>=================================================================" );
+#else
+ RDebug::Print(_L("<PIPROF>================================================================="));
+#endif
+
+ if(!aEmptying)
+ {
+ if(aStatus != 0)
+ User::RequestComplete(aStatus,0);
+ }
+
+ LOGTEXT(_L("CDebOutWriterPlugin::PrintDescriptorAsBase64() - exit"));
+}
+
+
+
+/*
+ *
+ * Implementation of class CDebOutWriterHandler
+ *
+ */
+CDebOutWriterHandler::CDebOutWriterHandler(CDebOutWriterPlugin* aWriter) :
+ CActive(EPriorityStandard)
+ {
+ LOGTEXT(_L("CDebOutWriterHandler::CDebOutWriterHandler - entry"));
+ iWriter = aWriter;
+
+ // set initial mode to non-stopping
+ iStopping = EFalse;
+
+ // add the handler to the active scheduler
+ CActiveScheduler::Add(this);
+ LOGTEXT(_L("CDebOutWriterHandler::CDebOutWriterHandler - exit"));
+ }
+
+CDebOutWriterHandler* CDebOutWriterHandler::NewL(CDebOutWriterPlugin* aWriter)
+{
+ LOGTEXT(_L("CDebOutWriterHandler::NewL() - entry"));
+ CDebOutWriterHandler* self = new (ELeave) CDebOutWriterHandler(aWriter);
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+ LOGTEXT(_L("CDebOutWriterHandler::NewL() - exit"));
+ return self;
+}
+
+CDebOutWriterHandler::~CDebOutWriterHandler()
+ {
+ LOGTEXT(_L("CDebOutWriterHandler::~CDebOutWriterHandler - entry"));
+
+ LOGTEXT(_L("CDebOutWriterHandler::~CDebOutWriterHandler - exit"));
+ }
+
+void CDebOutWriterHandler::ConstructL()
+ {
+
+ }
+
+void CDebOutWriterHandler::StartL()
+ {
+ LOGTEXT(_L("CDebOutWriterHandler::StartL - entry"));
+ if(!IsActive())
+ {
+ LOGTEXT(_L("CDiskWriterHandler::StartL - is not active"));
+
+ TBapBuf* nextBuf = iWriter->iStream->GetNextFilledBuffer();
+ LOGSTRING2("CDiskWriterHandler::StartL - got next filled 0x%x",nextBuf);
+
+ if(nextBuf != 0)
+ {
+ LOGTEXT(_L("CDiskWriterHandler::StartL - writing to file"));
+ WriteBufferToOutput(nextBuf);
+ }
+ }
+ LOGTEXT(_L("CDebOutWriterHandler::StartL - entry"));
+ }
+
+void CDebOutWriterHandler::Stop()
+ {
+ LOGTEXT(_L("CDebOutWriterHandler::Stop - entry"));
+
+ // do write once more to write the logged data to output
+ // set to stopping mode, needed for emptying the remaining full buffers
+ iStopping = ETrue;
+
+ // stop the timer
+ Reset();
+
+ // set mode back to non-stopping
+ iStopping = EFalse;
+ LOGTEXT(_L("CDebOutWriterHandler::Stop - exit"));
+ }
+
+void CDebOutWriterHandler::Reset()
+ {
+
+ // start writing new buffer if there is one available
+ TBapBuf* nextBuf = iWriter->iStream->GetNextFilledBuffer();
+
+ // empty the rest of the buffers synchronously
+ while(nextBuf != 0)
+ {
+ if(nextBuf->iDataSize != 0)
+ {
+ LOGTEXT(_L("CDiskWriterHandler::Reset - writing to file"));
+ iWriter->PrintDescriptorAsBase64(*(nextBuf->iBufDes),&iStatus,0xffffffff, iStopping);
+ }
+
+ // empty buffers when profiling stopped
+ iWriter->iStream->AddToFreeBuffers(nextBuf);
+
+ LOGTEXT(_L("CDiskWriterHandler::Reset - get next full buffer"));
+ // start writing new buffer if there is one available
+ nextBuf = iWriter->iStream->GetNextFilledBuffer();
+ LOGSTRING2("CDiskWriterHandler::Reset - got next filled 0x%x",nextBuf);
+ }
+ }
+
+void CDebOutWriterHandler::HandleFullBuffers()
+ {
+ LOGTEXT(_L("CDiskWriterHandler::HandleFullBuffers - entry"));
+ // previous write operation has finished
+ // release the previous buffer
+ iWriter->iStream->AddToFreeBuffers(iBufferBeingWritten);
+
+ LOGTEXT(_L("CDiskWriterHandler::HandleFullBuffers - get next full buffer"));
+ // start writing new buffer if there is one available
+ TBapBuf* nextBuf = iWriter->iStream->GetNextFilledBuffer();
+
+ if(nextBuf != 0)
+ {
+ LOGTEXT(_L("CDiskWriterHandler::HandleFullBuffers - writing to file"));
+ if(nextBuf->iDataSize != 0)
+ {
+ WriteBufferToOutput(nextBuf);
+ }
+ }
+ LOGTEXT(_L("CDiskWriterHandler::HandleFullBuffers - exit"));
+ }
+
+void CDebOutWriterHandler::RunL()
+ {
+ // call function to complete full buffer handling
+ HandleFullBuffers();
+ }
+
+void CDebOutWriterHandler::DoCancel()
+ {
+
+ }
+
+void CDebOutWriterHandler::WriteBufferToOutput(TBapBuf* aBuf)
+ {
+ LOGTEXT(_L("CDebOutWriterHandler::WriteBufferToOutput - entry"));
+ iBufferBeingWritten = aBuf;
+
+ // set the data length just to be sure
+ iBufferBeingWritten->iBufDes->SetLength(aBuf->iDataSize);
+
+ LOGTEXT(_L("CDiskWriterPlugin::WriteBufferToOutput - writing to file"));
+// PrintBufferToOutput(iBufferBeingWritten, iStatus);
+ iWriter->PrintDescriptorAsBase64(*(iBufferBeingWritten->iBufDes),&iStatus,0xffffffff, iStopping);
+ // set AO back to active, until filled buffers are emptied
+ SetActive();
+
+ LOGTEXT(_L("CDebOutWriterHandler::WriteBufferToOutput - exit"));
+ }
+
+// private
+void CDebOutWriterHandler::PrintBufferToOutput(TBapBuf* aBuffer, TRequestStatus& aStatus)
+ {
+ LOGTEXT(_L("CDebOutWriterHandler::WriteBufferToOutput() - debug out writer tick activated"));
+
+ TPtrC8& aDes = (TPtrC8&)*(aBuffer->iBufDes);
+#ifdef BAPPEA_SAMPLE_MARKS
+ TUint32 time = iSampler->GetSampleTime();
+#else
+ TUint32 time = 0xffffffff;
+#endif
+ iWriter->PrintDescriptorAsBase64(aDes,&aStatus,time, iStopping);
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/DebugOutputWriterPlugin/src/DebOutWriterPluginImplementationTable.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,39 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+// INCLUDE FILES
+#include <e32std.h>
+#include <ecom/implementationproxy.h>
+
+#include "DebOutWriterPlugin.h"
+
+
+// Provides a key value pair table, this is used to identify
+// the correct construction function for the requested interface.
+const TImplementationProxy ImplementationTable[] =
+{
+ IMPLEMENTATION_PROXY_ENTRY(0x2001E5BA, CDebOutWriterPlugin::NewL)
+};
+
+// Function used to return an instance of the proxy table.
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+{
+ aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
+ return ImplementationTable;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/DiskWriterPlugin/data/2001E5BB.rss Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,51 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <ecom/registryinfo.rh>
+
+// Declares info for two implementations
+RESOURCE REGISTRY_INFO theInfo
+ {
+ // UID for the DLL. See mmp files
+ //__SERIES60_3X__ can't be used in resource files
+ dll_uid = 0x2001E5BB;
+
+ // Declare array of interface info. This dll contains implementations for
+ // only one interface (CSamplerInterfaceDefinition).
+ interfaces =
+ {
+ INTERFACE_INFO
+ {
+ // UID of interface that is implemented
+ interface_uid = 0x2001E5BD;
+
+ implementations =
+ {
+ IMPLEMENTATION_INFO
+ {
+ implementation_uid = 0x2001E5BB;
+
+ version_no = 1;
+ display_name = "Disk output writer implementation";
+ default_data = "dsw";
+ opaque_data = "0";
+ }
+ };
+ }
+ };
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/DiskWriterPlugin/group/DiskWriterPlugin.mmp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,50 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <platform_paths.hrh>
+
+
+TARGET PIProfilerDiskWriter.dll
+TARGETTYPE PLUGIN
+UID 0x10009D8D 0x2001E5BB
+#ifdef WINSCW
+VENDORID 0
+#else
+VENDORID VID_DEFAULT
+#endif
+CAPABILITY ALL -TCB // AllFiles ReadDeviceData ReadUserData UserEnvironment WriteDeviceData WriteUserData
+SMPSAFE
+
+OS_LAYER_SYSTEMINCLUDE
+USERINCLUDE ../inc
+SOURCEPATH ../src
+
+START RESOURCE ../data/2001E5BB.rss
+TARGET piprofilerdiskwriter.rsc
+END
+
+SOURCE DiskWriterPlugin.cpp
+SOURCE DiskWriterPluginImplementationTable.cpp
+
+LIBRARY sysutil.lib
+LIBRARY euser.lib
+LIBRARY ECom.lib
+LIBRARY EFSRV.LIB
+LIBRARY commonengine.lib
+LIBRARY flogger.lib
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/DiskWriterPlugin/group/bld.inf Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,20 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+PRJ_MMPFILES
+DiskWriterPlugin.mmp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/DiskWriterPlugin/inc/DiskWriterPlugin.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,133 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef __DISKWRITERPLUGIN_H__
+#define __DISKWRITERPLUGIN_H__
+
+// Include Files
+#include <w32std.h>
+#include <piprofiler/WriterPluginInterface.h>
+#include <piprofiler/ProfilerGenericClassesUsr.h>
+#include <e32base.h> // CBase
+#include <e32std.h> // TBuf
+#include <e32property.h>
+
+_LIT(KFileOutShortName, "dsw");
+
+// forward declarations
+class CDiskWriterHandler;
+class CProfilerSampleStream;
+
+// Class Definitions
+
+class CDiskWriterPlugin : public CWriterPluginInterface
+ {
+public:
+ // new function
+ static CDiskWriterPlugin* NewL(const TUid aImplementationUid, TAny* aInitParams);
+ ~CDiskWriterPlugin();
+
+ void DoCancel();
+
+
+public: // new functions
+
+ TInt Start();
+
+ void Stop();
+
+ void GetValue( const TWriterPluginValueKeys aKey, TDes& aValue );
+
+ void SetValue( const TWriterPluginValueKeys aKey, TDes& aValue );
+
+ TUid Id() const;
+
+ void GetWriterVersion(TDes* aDes);
+
+ TUint32 GetWriterType();
+
+ void HandleError(TInt aError);
+
+ void WriteData();
+
+ void SetStream(CProfilerSampleStream& aStream) { iStream = &aStream; }
+
+private: // new functions
+ CDiskWriterPlugin(const TUid aImplementationUid);
+ void ConstructL();
+
+ void GetValueL( const TWriterPluginValueKeys aKey, TDes& aValue );
+ void SetValueL( const TWriterPluginValueKeys aKey, TDes& aValue );
+ TBool GetEnabled();
+
+ TInt DisplayNotifier(const TDesC& aLine1, const TDesC& aLine2, const TDesC& aButton1, const TDesC& aButton2);
+public:
+ CProfilerSampleStream* iStream;
+private: // data
+
+ TBuf<256> iFileName;
+ TInt iWriterType;
+ TInt iWriterId;
+ CDiskWriterHandler* iWriterHandler;
+ RProperty iErrorStatus;
+ };
+
+/*
+ *
+ * Definition of class CDiskWriterHandler
+ *
+ */
+class CDiskWriterHandler : public CActive //CBase
+ {
+public:
+
+
+ static CDiskWriterHandler* NewL(CDiskWriterPlugin* aWriter);
+ ~CDiskWriterHandler();
+
+ void StartL();
+
+ void Stop();
+ void RunL();
+ TInt RunError(TInt aError);
+
+ void DoCancel();
+ void WriteBufferToOutput(TBapBuf* aBuf);
+ void Reset();
+
+ TInt TestFile(const TDesC& totalPrefix);
+private:
+ CDiskWriterHandler(CDiskWriterPlugin* aWriter);
+
+ void ConstructL();
+ void WriteMemBufferToFile(TDesC8& aDes, TRequestStatus& aStatus);
+ static TInt Write(TAny* aObject);
+ void HandleFullBuffers();
+ void DoWrite();
+
+private:
+ RFile iFile;
+ RFs iFs;
+ TBuf<256> iFileName;
+ CDiskWriterPlugin* iWriter;
+ TBapBuf* iBufferBeingWritten;
+ TBool iStopping;
+ };
+
+#endif // __DEBOUTWRITERPLUGIN_H__
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/DiskWriterPlugin/sis/DiskWriterPlugin_EKA2.pkg Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,36 @@
+;
+; Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+; All rights reserved.
+; This component and the accompanying materials are made available
+; under the terms of "Eclipse Public License v1.0"
+; which accompanies this distribution, and is available
+; at the URL "http://www.eclipse.org/legal/epl-v10.html".
+;
+; Initial Contributors:
+; Nokia Corporation - initial contribution.
+;
+; Contributors:
+;
+; Description:
+;
+; Installation file for DebOutWriterPlugin dll
+;
+; This is an auto-generated PKG file by Carbide.
+; This file uses variables specific to Carbide builds that will not work
+; on command-line builds. If you want to use this generated PKG file from the
+; command-line tools you will need to modify the variables with the appropriate
+; values: $(EPOCROOT), $(PLATFORM), $(TARGET)
+
+;
+; UID is the dll's UID
+;
+#{"DebOutWriterPlugin DLL"},(0x00DA58C7),1,0,0
+
+
+;Localised Vendor name
+%{"Vendor-EN"}
+
+;Unique Vendor name
+:"Vendor"
+
+"$(EPOCROOT)Epoc32\release\$(PLATFORM)\$(TARGET)\DebOutWriterPlugin.dll" -"!:\sys\bin\DebOutWriterPlugin.dll"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/DiskWriterPlugin/src/DiskWriterPlugin.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,476 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+// Include Files
+
+#include "DiskWriterPlugin.h" // CDiskWriterPlugin
+#include <e32base.h>
+#include <sysutil.h>
+//#include <piprofiler/EngineUIDs.h>
+
+// constants
+const TUid KDiskWriterPluginUid = { 0x2001E5BB }; // own UID
+
+// engine properties
+const TUid KEngineStatusPropertyCat={0x2001E5AD};
+enum TEnginePropertyKeys
+ {
+ EProfilerEngineStatus = 8,
+ EProfilerErrorStatus
+ };
+
+/*
+ *
+ * Class CDiskWriterPlugin implementation
+ *
+ */
+
+// Member Functions
+CDiskWriterPlugin* CDiskWriterPlugin::NewL(const TUid /*aImplementationUid*/, TAny* /*aInitParams*/)
+ {
+ LOGTEXT(_L("CDiskWriterPlugin::NewL() - entry"));
+ CDiskWriterPlugin* self = new (ELeave) CDiskWriterPlugin(KDiskWriterPluginUid);
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+ LOGTEXT(_L("CDiskWriterPlugin::NewL() - exit"));
+ return self;
+ }
+
+CDiskWriterPlugin::CDiskWriterPlugin(const TUid aImplementationUid) :
+ iWriterType(aImplementationUid.iUid)
+ {
+ LOGTEXT(_L("CDiskWriterPlugin::CDiskWriterPlugin - entry"));
+ isEnabled = EFalse;
+ iWriterId = Id().iUid;
+ LOGTEXT(_L("CDiskWriterPlugin::CDiskWriterPlugin - exit"));
+ }
+
+CDiskWriterPlugin::~CDiskWriterPlugin()
+ {
+ LOGTEXT(_L("CDiskWriterPlugin::~CDiskWriterPlugin - entry"));
+
+ iErrorStatus.Close();
+
+ if(iWriterHandler)
+ {
+ iWriterHandler->Cancel();
+ delete iWriterHandler;
+ }
+ LOGTEXT(_L("CDiskWriterPlugin::~CDiskWriterPlugin - exit"));
+ }
+
+void CDiskWriterPlugin::ConstructL()
+ {
+ // second phase constructor, anything that may leave must be constructed here
+ LOGTEXT(_L("CDiskWriterPlugin::ConstructL() - entry"));
+ iWriterHandler = CDiskWriterHandler::NewL(this);
+ User::LeaveIfError(iErrorStatus.Attach(KEngineStatusPropertyCat, EProfilerErrorStatus));
+ LOGTEXT(_L("CDiskWriterPlugin::ConstructL() - exit"));
+ }
+
+TUid CDiskWriterPlugin::Id() const
+ {
+ LOGSTRING2("CDiskWriterPlugin::Id():0x%X", KDiskWriterPluginUid.iUid );
+ return KDiskWriterPluginUid;
+ }
+
+void CDiskWriterPlugin::GetWriterVersion(TDes* aDes)
+ {
+ _LIT(KDiskWriterVersion, "1.0.0");
+ aDes->Append(KDiskWriterVersion);
+ }
+
+TInt CDiskWriterPlugin::Start()
+ {
+// if(isEnabled)
+// {
+// TRAPD(err, iWriterHandler->StartL());
+// if( err != KErrNone)
+// {
+// LOGTEXT(_L("Could not start writer plugin"));
+// return err;
+// }
+// }
+ return KErrNone;
+ }
+
+void CDiskWriterPlugin::Stop()
+ {
+ // stop writer handler normally
+ iWriterHandler->Stop();
+ }
+
+TBool CDiskWriterPlugin::GetEnabled()
+ {
+ return isEnabled;
+ }
+
+TUint32 CDiskWriterPlugin::GetWriterType()
+ {
+ return iWriterType;
+ }
+
+
+void CDiskWriterPlugin::SetValue( const TWriterPluginValueKeys aKey,
+ TDes& aValue )
+ {
+ TRAP_IGNORE( SetValueL( aKey, aValue ) );
+ }
+
+
+void CDiskWriterPlugin::GetValue( const TWriterPluginValueKeys aKey,
+ TDes& aValue )
+ {
+ TRAP_IGNORE( GetValueL( aKey, aValue ) );
+ }
+
+void CDiskWriterPlugin::SetValueL( const TWriterPluginValueKeys aKey, TDes& aValue )
+ {
+ TInt error(KErrNone);
+
+ switch( aKey )
+ {
+ case EWriterPluginEnabled:
+ isEnabled = ETrue;
+ LOGTEXT(_L("CDebOutWriterPlugin::SetValueL - plugin enabled"));
+ break;
+ case EWriterPluginDisabled:
+ isEnabled = EFalse;
+ LOGTEXT(_L("CDebOutWriterPlugin::SetValueL - plugin disabled"));
+ break;
+ case EWriterPluginSettings: // file name in case of disk writer plugin
+ iFileName.Zero();
+ iFileName.Append(aValue);
+ error = iWriterHandler->TestFile(iFileName);
+ User::LeaveIfError(error);
+ break;
+ default:
+ break;
+ }
+ }
+
+void CDiskWriterPlugin::GetValueL( const TWriterPluginValueKeys aKey, TDes& aValue )
+ {
+ switch( aKey )
+ {
+ case EWriterPluginVersion:
+ GetWriterVersion(&aValue);
+ break;
+ case EWriterPluginType:
+ break;
+ case EWriterPluginSettings: // file name in disk writer case
+ aValue.Copy(iFileName);
+ default:
+ break;
+ }
+ }
+
+void CDiskWriterPlugin::DoCancel()
+ {
+ LOGTEXT(_L("CDebOutWriterPlugin::DoCancel - entry"));
+ }
+
+void CDiskWriterPlugin::WriteData()
+ {
+ // Activate handler to write data from buffer to output
+ LOGTEXT(_L("CDiskWriterPlugin::WriteData() - entry"));
+ TRAP_IGNORE(iWriterHandler->StartL());
+ LOGTEXT(_L("CDiskWriterPlugin::WriteData() - exit"));
+ }
+
+void CDiskWriterPlugin::HandleError(TInt aError)
+ {
+ TInt err(KErrNone);
+ RDebug::Print(_L("CDiskWriterPlugin::HandleError() - error received: %d"), aError);
+ err = iErrorStatus.Set(aError);
+ if(err != KErrNone)
+ {
+ RDebug::Print(_L("CDiskWriterPlugin::HandleError() - error in updating property: %d"), err);
+ }
+ }
+
+/*
+ *
+ * Implementation of class CDiskWriterHandler
+ *
+ */
+
+CDiskWriterHandler* CDiskWriterHandler::NewL(CDiskWriterPlugin* aWriter)
+ {
+ LOGTEXT(_L("CDiskWriterHandler::NewL() - entry"));
+ CDiskWriterHandler* self = new (ELeave) CDiskWriterHandler(aWriter);
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+ LOGTEXT(_L("CDiskWriterHandler::NewL() - exit"));
+ return self;
+ }
+
+CDiskWriterHandler::CDiskWriterHandler(CDiskWriterPlugin* aWriter) :
+ CActive(EPriorityStandard)
+ {
+ LOGTEXT(_L("CDiskWriterHandler::CDiskWriterHandler - entry"));
+
+ iWriter = aWriter;
+
+ // set initial mode to non-stopping
+ iStopping = EFalse;
+
+ // add the handler to the active scheduler
+ CActiveScheduler::Add(this);
+
+ LOGTEXT(_L("CDiskWriterHandler::CDiskWriterHandler - exit"));
+ }
+
+
+CDiskWriterHandler::~CDiskWriterHandler()
+ {
+ LOGTEXT(_L("CDiskWriterHandler::~CDiskWriterHandler - entry"));
+
+ LOGTEXT(_L("CDiskWriterHandler::~CDiskWriterHandler - exit"));
+ }
+
+void CDiskWriterHandler::ConstructL()
+ {
+ }
+
+TInt CDiskWriterHandler::TestFile(const TDesC& totalPrefix)
+ {
+ TParse parse;
+
+ TInt err(KErrNone);
+ if((err = parse.Set(totalPrefix, NULL, NULL)) != KErrNone)
+ return err;
+
+ err = iFs.Connect();
+ if(err != KErrNone)
+ {
+ LOGTEXT(_L("CDiskWriterHandler::TestFile() - Failed to open a session to file server"));
+ return KErrNotFound;
+ }
+
+ iFs.MkDirAll(parse.FullName());
+
+ err = iFile.Replace(iFs,parse.FullName(),EFileWrite);
+ if(err != KErrNone)
+ {
+ iFs.Close();
+ return KErrNotFound;
+ }
+
+ iFileName.Copy(parse.FullName());
+
+ return KErrNone;
+ }
+
+void CDiskWriterHandler::Reset()
+ {
+ // cancel active object
+ Cancel();
+
+ // start writing new buffer if there is one available
+ TBapBuf* nextBuf = iWriter->iStream->GetNextFilledBuffer();
+
+ // empty the rest of the buffers synchronously
+ while(nextBuf != 0)
+ {
+ LOGTEXT(_L("CDiskWriterHandler::Reset - writing to file"));
+ if(nextBuf->iDataSize != 0)
+ {
+ LOGTEXT(_L("CDiskWriterHandler::Reset - writing to file"));
+ WriteMemBufferToFile(*(nextBuf->iBufDes),iStatus);
+ }
+
+ // empty buffers when profiling stopped
+ iWriter->iStream->AddToFreeBuffers(nextBuf);
+
+ LOGTEXT(_L("CDiskWriterHandler::Reset - get next full buffer"));
+ // start writing new buffer if there is one available
+ nextBuf = iWriter->iStream->GetNextFilledBuffer();
+ LOGSTRING2("CDiskWriterHandler::Reset - got next filled 0x%x",nextBuf);
+ }
+ }
+
+void CDiskWriterHandler::HandleFullBuffers()
+ {
+ LOGTEXT(_L("CDiskWriterHandler::HandleFullBuffers - entry"));
+ // previous write operation has finished
+ // release the previous buffer
+ iWriter->iStream->AddToFreeBuffers(iBufferBeingWritten);
+
+ LOGTEXT(_L("CDiskWriterHandler::HandleFullBuffers - get next full buffer"));
+ // start writing new buffer if there is one available
+ TBapBuf* nextBuf = iWriter->iStream->GetNextFilledBuffer();
+
+ if(nextBuf != 0)
+ {
+ LOGTEXT(_L("CDiskWriterHandler::HandleFullBuffers - writing to file"));
+ if(nextBuf->iDataSize != 0)
+ {
+ WriteBufferToOutput(nextBuf);
+ }
+ }
+ LOGTEXT(_L("CDiskWriterHandler::HandleFullBuffers - exit"));
+ }
+
+void CDiskWriterHandler::RunL()
+ {
+ LOGTEXT(_L("CDiskWriterHandler::RunL - entry"));
+ // call function to complete full buffer handling
+ HandleFullBuffers();
+ LOGTEXT(_L("CDiskWriterHandler::RunL - exit"));
+ }
+
+void CDiskWriterHandler::DoCancel()
+ {
+
+ }
+
+//-----------------------------------------------------------------------------
+// CPIProfilerTraceCoreLauncher::RunError(TInt aError)
+// Handle leaves from RunL().
+//-----------------------------------------------------------------------------
+TInt CDiskWriterHandler::RunError(TInt aError)
+ {
+ // no reason to continue if disk full or removed
+ iFile.Close();
+ // close handle to file server too
+ iFs.Close();
+ iFileName.Zero();
+
+ iWriter->HandleError(KErrDiskFull);
+ return aError;
+ }
+
+void CDiskWriterHandler::WriteMemBufferToFile(TDesC8& aDes, TRequestStatus& aStatus)
+ {
+ LOGTEXT(_L("CDiskWriterPlugin::WriteMemBufferToFile - entry"));
+
+ TUint sampleSize(aDes.Length());
+ TInt err(KErrNone);
+ TInt drive(0);
+ TDriveInfo info;
+ TBool noDiskSpace(EFalse);
+
+ err = iFile.Drive(drive,info);
+
+ // test available disk space
+ TRAP_IGNORE((noDiskSpace = SysUtil::DiskSpaceBelowCriticalLevelL(&iFs, sampleSize, drive)));
+ // check first if still space on disk
+ if(noDiskSpace)
+ {
+ // set error to disk full
+ err = KErrDiskFull;
+ LOGTEXT(_L("CDiskWriterPlugin::WriteMemBufferToFile - disk full, cannot write"));
+ }
+ else
+ {
+ // check if profiling in stopping mode
+ if(iStopping)
+ {
+ // RDebug::Print(_L("CDiskWriterPlugin::WriteMemBufferToFile - data written, length %d, stopping"), aDes.Length());
+ // write to file without status
+ err = iFile.Write(aDes);
+ }
+ else
+ {
+ // RDebug::Print(_L("CDiskWriterPlugin::WriteMemBufferToFile - data written, length %d"), aDes.Length());
+ // write to file with status
+ iFile.Write(aDes,aStatus);
+ }
+ }
+
+ // check if error in write
+ if(err != KErrNone)
+ {
+ // stop writer handler (and its timer) immediately, DO NOT try write data!
+ Cancel();
+
+ // no reason to continue if disk full or removed
+ // end of stream detected, file can be closed
+ iFile.Close();
+ // close handle to file server too
+ iFs.Close();
+ iFileName.Zero();
+
+ // set error status for engine to read
+ iWriter->HandleError(err);
+ }
+ LOGTEXT(_L("CDiskWriterPlugin::WriteMemBufferToFile - exit"));
+ }
+
+void CDiskWriterHandler::WriteBufferToOutput(TBapBuf* aBuf)
+ {
+ LOGTEXT(_L("CDiskWriterPlugin::WriteBufferToOutput - entry"));
+ iBufferBeingWritten = aBuf;
+
+ // set the data length just to be sure
+ iBufferBeingWritten->iBufDes->SetLength(aBuf->iDataSize);
+
+ LOGTEXT(_L("CDiskWriterPlugin::WriteBufferToOutput - writing to file"));
+ WriteMemBufferToFile(*(iBufferBeingWritten->iBufDes), iStatus);
+
+ // set AO back to active, until filled buffers are emptied
+ SetActive();
+
+ LOGTEXT(_L("CDiskWriterPlugin::WriteBufferToOutput - exit"));
+ }
+
+void CDiskWriterHandler::StartL()
+ {
+ LOGTEXT(_L("CDiskWriterHandler::StartL - entry"));
+ if(!IsActive())
+ {
+ LOGTEXT(_L("CDiskWriterHandler::StartL - is not active"));
+
+ TBapBuf* nextBuf = iWriter->iStream->GetNextFilledBuffer();
+ LOGSTRING2("CDiskWriterHandler::StartL - got next filled 0x%x",nextBuf);
+
+ if(nextBuf != 0)
+ {
+ LOGTEXT(_L("CDiskWriterHandler::StartL - writing to file"));
+ WriteBufferToOutput(nextBuf);
+ }
+ }
+ LOGTEXT(_L("CDiskWriterHandler::StartL - exit"));
+ }
+
+void CDiskWriterHandler::Stop()
+ {
+ LOGTEXT(_L("CDiskWriterHandler::Stop - entry"));
+
+ // set to stopping mode, needed for emptying the remaining full buffers
+ iStopping = ETrue;
+
+ // stop the timer
+ Reset();
+
+ // end of stream detected, file can be closed
+ iFile.Close();
+ // close handle to file server too
+ iFs.Close();
+ iFileName.Zero();
+
+ // set mode back to non-stopping
+ iStopping = EFalse;
+
+ LOGTEXT(_L("CDiskWriterHandler::Stop - exit"));
+ }
+
+// end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/DiskWriterPlugin/src/DiskWriterPluginImplementationTable.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,39 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+// INCLUDE FILES
+#include <e32std.h>
+#include <ecom/implementationproxy.h>
+
+#include "DiskWriterPlugin.h"
+
+
+// Provides a key value pair table, this is used to identify
+// the correct construction function for the requested interface.
+const TImplementationProxy ImplementationTable[] =
+{
+ IMPLEMENTATION_PROXY_ENTRY(0x2001E5BB, CDiskWriterPlugin::NewL)
+};
+
+// Function used to return an instance of the proxy table.
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+{
+ aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
+ return ImplementationTable;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/data/2001E5B2.rss Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,51 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <ecom/registryinfo.rh>
+
+// Declares info for two implementations
+RESOURCE REGISTRY_INFO theInfo
+ {
+ // UID for the DLL. See mmp files
+ //__SERIES60_3X__ can't be used in resource files
+ dll_uid = 0x2001E5B2;
+
+ // Declare array of interface info. This dll contains implementations for
+ // only one interface (CSamplerInterfaceDefinition).
+ interfaces =
+ {
+ INTERFACE_INFO
+ {
+ // UID of interface that is implemented
+ interface_uid = 0x2001E5BC;
+
+ implementations =
+ {
+ IMPLEMENTATION_INFO
+ {
+ implementation_uid = 0x2001E5B2;
+
+ version_no = 1;
+ display_name = "General Samplers; GPP, ITT, GFC, MEM, PRI";
+ default_data = "gen";
+ opaque_data = "0"; // the order number
+ }
+ };
+ }
+ };
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/group/GeneralsPlugin.mmp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,52 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <platform_paths.hrh>
+
+
+TARGET PIProfilerGenerals.dll
+TARGETTYPE PLUGIN
+UID 0x10009D8D 0x2001E5B2
+VENDORID VID_DEFAULT
+CAPABILITY ALL -TCB
+SMPSAFE
+
+EPOCSTACKSIZE 0x10000
+
+OS_LAYER_SYSTEMINCLUDE
+USERINCLUDE ../inc
+SOURCEPATH ../src
+
+START RESOURCE ../data/2001E5B2.rss
+TARGET PIProfilerGenerals.rsc
+END
+
+SOURCE GeneralsPluginImplementationTable.cpp
+SOURCE GeneralsPlugin.cpp
+
+LIBRARY euser.lib
+LIBRARY bafl.lib
+LIBRARY ECom.lib
+LIBRARY apparc.lib
+LIBRARY cone.lib
+LIBRARY ws32.lib
+LIBRARY charconv.lib
+LIBRARY commonengine.lib
+LIBRARY flogger.lib
+
+epocallowdlldata
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/group/GeneralsSampler.mmp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,52 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <platform_paths.hrh>
+#include "kernel/kern_ext.mmh"
+
+TARGET PIProfilerGeneralsSampler.ldd
+CAPABILITY ALL
+TARGETTYPE LDD
+UID 0x100000AF 0x2001E5B3
+VENDORID VID_DEFAULT
+SMPSAFE
+
+OS_LAYER_KERNEL_SYSTEMINCLUDE
+USERINCLUDE ../inc
+SOURCEPATH ../src
+
+SOURCE GeneralsDriver.cpp
+SOURCE GeneralsSampler.cia
+SOURCE GppSamplerImpl.cpp
+SOURCE IttEventHandler.cpp
+SOURCE IttSamplerImpl.cpp
+SOURCE MemoryEventHandler.cpp
+SOURCE MemSamplerImpl.cpp
+SOURCE PriSamplerImpl.cpp
+
+#ifdef SMP
+LIBRARY ekernsmp.lib
+#else
+LIBRARY ekern.lib
+#endif
+
+epocallowdlldata
+
+start wins
+win32_headers
+end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/group/bld.inf Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,25 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+//PRJ_PLATFORMS
+//DEFAULT ARMV5SMP
+
+PRJ_MMPFILES
+#ifdef MARM
+ GeneralsPlugin.mmp
+ GeneralsSampler.mmp
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/inc/GeneralsConfig.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,99 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef GENERALS_CONFIG_H
+#define GENERALS_CONFIG_H
+
+
+ // change this to reflect the ISA task amount
+ #define PROFILER_ISA_OS_TASK_AMOUNT 50
+
+ // don't change these definitions
+ #define PROFILER_DEFINE_ISA_TASK_NAME_ARRAY TBuf8<64> isaTaskNames[PROFILER_ISA_OS_TASK_AMOUNT];
+ #define PROFILER_DEFINE_ISA_TASK_NAME(name,number) isaTaskNames[number].Append(_L8(name));
+
+ // change these to reflect the real ISA task names and numbers
+ // the last number must be PROFILER_ISA_OS_TASK_AMOUNT-1
+
+ #define PROFILER_ISA_TASK_NAMES PROFILER_DEFINE_ISA_TASK_NAME("SRVSCKT_TASK",0)\
+ PROFILER_DEFINE_ISA_TASK_NAME("CSD_SRV_TASK",1) \
+ PROFILER_DEFINE_ISA_TASK_NAME("CSD_NTB_TASK",2) \
+ PROFILER_DEFINE_ISA_TASK_NAME("CSD_WTB_TASK",3) \
+ PROFILER_DEFINE_ISA_TASK_NAME("PH_TASK",4) \
+ PROFILER_DEFINE_ISA_TASK_NAME("L2_TASK",5) \
+ PROFILER_DEFINE_ISA_TASK_NAME("RR_TASK",6) \
+ PROFILER_DEFINE_ISA_TASK_NAME("GPRS_RLC_TASK",7) \
+ PROFILER_DEFINE_ISA_TASK_NAME("GPRS_MAC_TASK",8) \
+ PROFILER_DEFINE_ISA_TASK_NAME("RANC_TASK",9) \
+ PROFILER_DEFINE_ISA_TASK_NAME("MM_TASK",10) \
+ PROFILER_DEFINE_ISA_TASK_NAME("CC_TASK",11) \
+ PROFILER_DEFINE_ISA_TASK_NAME("SMS_TASK",12) \
+ PROFILER_DEFINE_ISA_TASK_NAME("RM_CONTROL_TASK",13) \
+ PROFILER_DEFINE_ISA_TASK_NAME("GSS_SERVER_TASK",14) \
+ PROFILER_DEFINE_ISA_TASK_NAME("CS_MAIN_TASK",15) \
+ PROFILER_DEFINE_ISA_TASK_NAME("GPRS_TASK",16) \
+ PROFILER_DEFINE_ISA_TASK_NAME("WMAC_TASK",17) \
+ PROFILER_DEFINE_ISA_TASK_NAME("WMHS_TASK",18) \
+ PROFILER_DEFINE_ISA_TASK_NAME("WRRC_TASK",19) \
+ PROFILER_DEFINE_ISA_TASK_NAME("WRLC_UL_TASK",20) \
+ PROFILER_DEFINE_ISA_TASK_NAME("WRLC_DL_TASK",21) \
+ PROFILER_DEFINE_ISA_TASK_NAME("WPH_TASK",22) \
+ PROFILER_DEFINE_ISA_TASK_NAME("WRAN_TASK",23) \
+ PROFILER_DEFINE_ISA_TASK_NAME("SSOM_TASK",24) \
+ PROFILER_DEFINE_ISA_TASK_NAME("ACCESSORY_TASK",25) \
+ PROFILER_DEFINE_ISA_TASK_NAME("ADL_TASK",26) \
+ PROFILER_DEFINE_ISA_TASK_NAME("AUDIO_TASK",27) \
+ PROFILER_DEFINE_ISA_TASK_NAME("PN_TASK",28) \
+ PROFILER_DEFINE_ISA_TASK_NAME("CORE_HI_TASK",29) \
+ PROFILER_DEFINE_ISA_TASK_NAME("CORE_LO_TASK",30) \
+ PROFILER_DEFINE_ISA_TASK_NAME("ENERGY_TASK",31) \
+ PROFILER_DEFINE_ISA_TASK_NAME("FBUS_TASK",32) \
+ PROFILER_DEFINE_ISA_TASK_NAME("PMM_FILE2_TASK",33) \
+ PROFILER_DEFINE_ISA_TASK_NAME("MDI_RCV_TASK",34) \
+ PROFILER_DEFINE_ISA_TASK_NAME("MDI_SEND_TASK",35) \
+ PROFILER_DEFINE_ISA_TASK_NAME("MONITOR_TASK",36) \
+ PROFILER_DEFINE_ISA_TASK_NAME("MTC_CTRL_TASK",37) \
+ PROFILER_DEFINE_ISA_TASK_NAME("MTC_WD_TASK",38) \
+ PROFILER_DEFINE_ISA_TASK_NAME("OBEX_TASK",39) \
+ PROFILER_DEFINE_ISA_TASK_NAME("APDU_SERVER_TASK",40) \
+ PROFILER_DEFINE_ISA_TASK_NAME("SIMSON_SERVER_TASK",41) \
+ PROFILER_DEFINE_ISA_TASK_NAME("SIMLOCK_TASK",42) \
+ PROFILER_DEFINE_ISA_TASK_NAME("SOS_USB_MM_TASK",43) \
+ PROFILER_DEFINE_ISA_TASK_NAME("SOS_PROXY_AUX_TASK",44) \
+ PROFILER_DEFINE_ISA_TASK_NAME("TERMINAL_ADAPTER_TASK",45) \
+ PROFILER_DEFINE_ISA_TASK_NAME("XTI_RECEIVE_TASK",46) \
+ PROFILER_DEFINE_ISA_TASK_NAME("XTI_SEND_TASK",47) \
+ PROFILER_DEFINE_ISA_TASK_NAME("STARTUP_AND_BACKGROUND_TASK",48) \
+ PROFILER_DEFINE_ISA_TASK_NAME("OS_IDLE_TASK",49)
+
+ // old definitions
+ #define PROFILER_GENERALS_SAMPLER_ID 100
+ #define PROFILER_GPP_SAMPLER_ID 1
+ #define PROFILER_GFC_SAMPLER_ID 2
+ #define PROFILER_ITT_SAMPLER_ID 3
+ #define PROFILER_MEM_SAMPLER_ID 4
+ #define PROFILER_PRI_SAMPLER_ID 5
+
+ #define PROFILER_GPP_SAMPLER_NAME _L("GPP")
+ #define PROFILER_GFC_SAMPLER_NAME _L("GFC")
+ #define PROFILER_ITT_SAMPLER_NAME _L("ITT")
+ #define PROFILER_MEM_SAMPLER_NAME _L("MEM")
+ #define PROFILER_PRI_SAMPLER_NAME _L("PRI")
+
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/inc/GeneralsDriver.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,59 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef __GENERALSSAMPLER_H__
+#define __GENERALSSAMPLER_H__
+
+/*
+ * The user-interface to the sampling device driver sued by the profiling engine
+ */
+#include <piprofiler/PluginSampler.h>
+
+#ifndef __KERNEL_MODE__
+#include <utf.h>
+#endif
+
+
+/**
+ * The user device driver class for controlling the plugin sampler.
+ */
+
+class RGeneralsSampler : public RPluginSampler
+{
+ public:
+ #ifndef __KERNEL_MODE__
+
+ /** Open a channel to the sampling device **/
+ inline TInt Open();
+
+ #endif // !__KERNEL_MODE__
+};
+
+_LIT(KPluginSamplerName,"PIProfilerGeneralsSampler");
+
+#ifndef __KERNEL_MODE__
+
+inline TInt RGeneralsSampler::Open()
+{
+ return DoCreate(KPluginSamplerName,TVersion(1,0,1),KNullUnit,NULL,NULL);
+}
+
+
+#endif
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/inc/GeneralsPlugin.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,147 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef PROFILER_GENERALSECOM_SAMPLER_H
+#define PROFILER_GENERALSECOM_SAMPLER_H
+
+#include <w32std.h>
+
+#include "GeneralsDriver.h"
+#include "GeneralsConfig.h"
+#include <piprofiler/SamplerPluginInterface.h>
+#include <piprofiler/ProfilerGenericClassesUsr.h>
+
+// constants
+const TUint KDefaultOutputCombination = 3;
+
+const TUint KSubSamplerCount = 5;
+
+// parent itself
+_LIT(KGENShortName, "gen");
+_LIT(KGENMediumName, "Generic samplers plug-in");
+_LIT(KGENLongName, "Generic samplers plug-in");
+
+// gpp caption definitions
+_LIT8(KGPPShortName, "gpp");
+#ifdef CARBIDE_NAMES
+_LIT8(KGPPLongName, "Address/Thread sampling");
+#else
+_LIT8(KGPPLongName, "CPU load sampler");
+#endif
+_LIT8(KGPPDescription, "CPU load sampler\nSampling thread and process load\nHW dep: N/A\nSW dep: S60 3.0\n");
+
+// gfc caption definitions
+_LIT8(KGFCShortName, "gfc");
+#ifdef CARBIDE_NAMES
+_LIT8(KGFCLongName, "Function call sampling");
+#else
+_LIT8(KGFCLongName, "Function call sampler");
+#endif
+_LIT8(KGFCDescription, "Function call sampler\nCapturing function call info\nHW dep: N/A\nSW dep: S60 3.0\n");
+
+// itt caption definitions
+_LIT8(KITTShortName, "itt");
+#ifdef CARBIDE_NAMES
+_LIT8(KITTLongName, "Dynamic binary support");
+#else
+_LIT8(KITTLongName, "Dynamic binary sampler");
+#endif
+_LIT8(KITTDescription, "Dynamic binary sampler\nTracing dynamically loaded binaries, e.g. from ROFS\nHW dep: N/A\nSW dep: S60 3.0\n");
+
+// mem caption definitions
+_LIT8(KMEMShortName, "mem");
+#ifdef CARBIDE_NAMES
+_LIT8(KMEMLongName, "Memory usage sampler");
+#else
+_LIT8(KMEMLongName, "Memory trace sampler");
+#endif
+_LIT8(KMEMDescription, "Memory trace sampler\nTracing memory, i.e. stack and chunk usage\nHW dep: N/A\nSW dep: S60 3.0\n");
+
+// pri caption definitions
+_LIT8(KPRIShortName, "pri");
+#ifdef CARBIDE_NAMES
+_LIT8(KPRILongName, "Thread priority sampling");
+#else
+_LIT8(KPRILongName, "Priority trace sampler");
+#endif
+_LIT8(KPRIDescription, "Priority trace sampler\nTracing thread priorities\nHW dep: N/A\nSW dep: S60 3.0\n");
+
+
+// forward definitions
+class CConfigInfoArray;
+class CProfilerBufferHandler;
+class CProfilerSampleStream;
+class TSamplerAttributes;
+
+class CGeneralsPlugin : public CSamplerPluginInterface
+{
+public:
+ static CGeneralsPlugin* NewL(const TUid aImplementationUid, TAny* /*aInitParams*/);
+ ~CGeneralsPlugin();
+
+ TUint32 GetSampleTime();
+
+ /*
+ * Sub sampler specific functions
+ *
+ */
+
+ // from CSamplerPluginInterface
+ TInt ResetAndActivateL(CProfilerSampleStream& aStream);
+ TInt StopSampling();
+ TBool Enabled() { return iEnabled; }
+
+ TUid Id( TInt aSubId ) const;
+ TInt SubId( TUid aSubId ) const; // internal
+
+ void GetAttributesL(CArrayFixFlat<TSamplerAttributes>* aAttributes);
+ TInt SetAttributesL(TSamplerAttributes aAttributes);
+ void InitiateSamplerAttributesL();
+
+ TInt ConvertRawSettingsToAttributes(CDesC8ArrayFlat* aSingleSettingArray);
+ TInt DoSetSamplerSettings(CDesC8ArrayFlat* aAllSettings, TDesC8& aSamplerName, TInt aIndex);
+ void SaveSettingToAttributes(const TDesC8& aSetting, TInt aIndex);
+
+ TInt GetSamplerType();
+
+ void InstallStreamForActiveTraces(RGeneralsSampler& sampler, CProfilerSampleStream& aStream);
+
+private:
+ CGeneralsPlugin();
+ void ConstructL();
+
+ TInt InitiateSamplerL();
+ TInt CleanSampler();
+ void SetSettingsToSamplers();
+
+private:
+ TUint8 iVersion[20];
+ TPtr8 iVersionDescriptor;
+
+ RGeneralsSampler iGeneralsSampler;
+
+ CProfilerBufferHandler* iBufferHandler;
+
+ CArrayFixFlat<TSamplerAttributes>* iSamplerAttributes;
+
+ TBuf8<9> iSearchTexts;
+public:
+ TUint32* iSampleTime;
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/inc/GfcSamplerImpl.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,249 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef PROFILER_GFC_SAMPLER_H
+#define PROFILER_GFC_SAMPLER_H
+
+
+#include "GeneralsConfig.h"
+
+#include <kern_priv.h>
+
+#include <piprofiler/ProfilerGenericClassesKrn.h>
+#include <piprofiler/ProfilerTraces.h>
+#include "GppSamplerImpl.h"
+
+extern void UsrModLr(TUint32*);
+
+
+/*
+ *
+ * GFC sampler definition
+ *
+ */
+
+template <int BufferSize>
+class DProfilerGfcSampler : public DProfilerGenericSampler<BufferSize>
+{
+public:
+ DProfilerGfcSampler(struct TProfilerGppSamplerData* );
+ ~DProfilerGfcSampler();
+
+ void Sample();
+ TInt Reset(DProfilerSampleStream* aStream, TUint32 aSyncOffset);
+private:
+ struct TProfilerGppSamplerData* gppSamplerData;
+ TUint32 gfcSample[3];
+
+ TUint8 encodedSample[15];
+ TUint32 repeat;
+};
+
+/*
+ *
+ * GFC sampler implementation
+ *
+ */
+
+template <int BufferSize>
+DProfilerGfcSampler<BufferSize>::DProfilerGfcSampler(struct TProfilerGppSamplerData* gppSamplerDataIn) :
+ DProfilerGenericSampler<BufferSize>(PROFILER_GFC_SAMPLER_ID)
+{
+ this->gppSamplerData = gppSamplerDataIn;
+ LOGSTRING2("CProfilerGfcSampler<%d>::CProfilerGfcSampler",BufferSize);
+}
+
+template <int BufferSize>
+TInt DProfilerGfcSampler<BufferSize>::Reset(DProfilerSampleStream* aStream, TUint32 aSyncOffset)
+{
+ LOGSTRING2("CProfilerGfcSampler<BufferSize> - entry",BufferSize);
+
+ this->repeat = 0;
+ for(TInt i(0);i<3;i++)
+ {
+ this->gfcSample[i] = 0;
+ }
+
+ LOGSTRING2("CProfilerGfcSampler<%d>::Reset - calling superclass reset",BufferSize);
+ DProfilerGenericSampler<BufferSize>::Reset(aStream);
+ LOGSTRING2("CProfilerGfcSampler<%d>::Reset - called superclass reset",BufferSize);
+
+ // add the first sample, indicating the gfc trace version
+ TUint8 firstSample[33];
+ TPtr8 firstSampleDesc(&(firstSample[1]),32);
+ firstSampleDesc.Zero();
+
+ firstSampleDesc.Append(_L8("Bappea_V"));
+ firstSampleDesc.Append(PROFILER_GFC_SAMPLER_VERSION);
+ firstSampleDesc.Append(_L8("_GFC"));
+ firstSample[0] = firstSampleDesc.Size();
+
+ this->iSampleBuffer->AddSample(firstSample,(firstSample[0]+1));
+
+ LOGSTRING2("CProfilerGfcSampler<BufferSize> - exit",BufferSize);
+
+ return KErrNone;
+}
+
+template <int BufferSize>
+void DProfilerGfcSampler<BufferSize>::Sample()
+{
+ LOGSTRING2("CProfilerGfcSampler<%d>::Sample",BufferSize);
+
+ TUint32 usr_mod_link_reg;
+
+ UsrModLr(&usr_mod_link_reg);
+
+ TUint32 pc(gppSamplerData->lastPcValue);
+ TUint32 lr(usr_mod_link_reg);
+ TUint32 sa(gppSamplerData->sampleNumber);
+
+ if(pc == gfcSample[0] && lr == gfcSample[1] && sa == gfcSample[2]+1)
+ {
+ // encode repeat
+ repeat++;
+ gfcSample[2] = sa;
+ LOGSTRING2("CProfilerGfcSampler<%d>::Sample - repeat",BufferSize);
+ return;
+ }
+ else if(repeat > 0)
+ {
+ TUint8 repeatSample[3];
+ repeatSample[0] = 0xff;
+ repeatSample[1] = (TUint8)(repeat>>8);
+ repeatSample[2] = (TUint8)repeat;
+ this->iSampleBuffer->AddSample(repeatSample,3);
+
+ LOGSTRING3("CProfilerGfcSampler<%d>::Sample - Encoded repeat %d",BufferSize,repeat);
+
+ repeat = 0;
+ }
+
+ TInt ptr(3);
+
+ // encode program counter value
+ if(pc>=gfcSample[0])
+ {
+ pc = (pc-gfcSample[0]);
+ encodedSample[0] = 0x80;
+ }
+ else
+ {
+ pc = (gfcSample[0]-pc);
+ encodedSample[0] = 0x00;
+ }
+
+ if(pc <= (TUint32)0xff)
+ {
+ encodedSample[0] |= 1;
+ encodedSample[ptr] = (TUint8)pc;ptr++;
+ }
+ else if(pc <= (TUint32)0xffff)
+ {
+ encodedSample[0] |= 2;
+ encodedSample[ptr] = (TUint8)pc;ptr++;
+ encodedSample[ptr] = (TUint8)(pc>>8);ptr++;
+ }
+ else if(pc <= (TUint32)0xffffff)
+ {
+ encodedSample[0] |= 3;
+ encodedSample[ptr] = (TUint8)pc;ptr++;
+ encodedSample[ptr] = (TUint8)(pc>>8);ptr++;
+ encodedSample[ptr] = (TUint8)(pc>>16);ptr++;
+ }
+ else
+ {
+ encodedSample[0] |= 4;
+ encodedSample[ptr] = (TUint8)pc;ptr++;
+ encodedSample[ptr] = (TUint8)(pc>>8);ptr++;
+ encodedSample[ptr] = (TUint8)(pc>>16);ptr++;
+ encodedSample[ptr] = (TUint8)(pc>>24);ptr++;
+ }
+
+ // encode link register value
+ if(lr>=gfcSample[1])
+ {
+ lr = (lr-gfcSample[1]);
+ encodedSample[1] = 0x80;
+ }
+ else
+ {
+ lr = (gfcSample[1]-lr);
+ encodedSample[1] = 0x00;
+ }
+
+ if(lr <= (TUint32)0xff)
+ {
+ encodedSample[1] |= 1;
+ encodedSample[ptr] = (TUint8)lr;ptr++;
+ }
+ else if(lr <= (TUint32)0xffff)
+ {
+ encodedSample[1] |= 2;
+ encodedSample[ptr] = (TUint8)lr;ptr++;
+ encodedSample[ptr] = (TUint8)(lr>>8);ptr++;
+ }
+ else if(lr <= (TUint32)0xffffff)
+ {
+ encodedSample[1] |= 3;
+ encodedSample[ptr] = (TUint8)lr;ptr++;
+ encodedSample[ptr] = (TUint8)(lr>>8);ptr++;
+ encodedSample[ptr] = (TUint8)(lr>>16);ptr++;
+ }
+ else
+ {
+ encodedSample[1] |= 4;
+ encodedSample[ptr] = (TUint8)lr;ptr++;
+ encodedSample[ptr] = (TUint8)(lr>>8);ptr++;
+ encodedSample[ptr] = (TUint8)(lr>>16);ptr++;
+ encodedSample[ptr] = (TUint8)(lr>>24);ptr++;
+ }
+
+ // endcode sample number difference
+ if( (sa - gfcSample[2]) < (TUint8)0xff)
+ {
+ encodedSample[2] = (sa-gfcSample[2]);
+ }
+ else
+ {
+ encodedSample[2] = 0xff;
+ encodedSample[ptr] = (TUint8)sa;ptr++;
+ encodedSample[ptr] = (TUint8)(sa>>8);ptr++;
+ encodedSample[ptr] = (TUint8)(sa>>16);ptr++;
+ encodedSample[ptr] = (TUint8)(sa>>24);ptr++;
+ }
+
+ // store the values for the next sample
+ gfcSample[0] = gppSamplerData->lastPcValue;
+ gfcSample[1] = usr_mod_link_reg;
+ gfcSample[2] = gppSamplerData->sampleNumber;
+
+ this->iSampleBuffer->AddSample(encodedSample,ptr);
+
+ LOGSTRING3("CProfilerGfcSampler<%d>::Sample Size %d",BufferSize,ptr);
+
+ return;
+
+}
+
+template <int BufferSize>
+DProfilerGfcSampler<BufferSize>::~DProfilerGfcSampler()
+{
+ LOGSTRING2("CProfilerGfcSampler<%d>::~CProfilerGfcSampler",BufferSize);
+}
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/inc/GppSamplerImpl.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,251 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef PROFILER_GPP_SAMPLER_H
+#define PROFILER_GPP_SAMPLER_H
+
+#include "GeneralsConfig.h"
+
+#include <e32cmn.h>
+
+#include <piprofiler/ProfilerGenericClassesKrn.h>
+#include <piprofiler/ProfilerTraces.h>
+
+// for RPropertyRef
+#include <sproperty.h>
+#include <e32cmn.h>
+
+/*
+ *
+ * GPP sampler definition
+ *
+ */
+class DGppSamplerImpl //: public DBase
+{
+public:
+
+ DGppSamplerImpl();
+ ~DGppSamplerImpl();
+
+ TUint8* EncodeTag(TUint8* aPtr);
+ TUint8* EncodeInt(TUint8* aPtr,TInt aValue);
+ TUint8* EncodeUint(TUint8* aPtr,TUint aValue);
+ TUint8* EncodeText(TUint8* aPtr, const TDesC& aDes);
+
+ TUint8* EncodeName(TUint8* aPtr, DObject& aObject,TUint32 id);
+ TUint8* EncodeThread(TUint8* aPtr, DThread& aThread);
+
+ TBool IsaTaskKnown(TUint8 task);
+ TUint8* EncodeIsaTask(TUint8* aPtr, TUint task);
+ TUint8* EncodeIsaName(TUint8* aPtr, TUint task,TBool process);
+
+ TUint8* EncodeRepeat(TUint8* aPtr);
+
+ TInt CreateFirstSample();
+ TInt SampleImpl();
+#ifdef __SMP__
+ TSpinLock* LockPtr();
+#endif
+ TInt iGppSamplingPeriod;
+ TUint8 tempBuf[512];
+ TUint iLastPc;
+
+ TBool iIsaSample;
+ TInt knownIsaTasks[256];
+ TUint8 knownIsaTaskCount;
+ TInt* isaOsTaskRunningAddr;
+ void Reset();
+ TUint32 iSampleCount;
+#ifdef __SMP__
+ TInt iCpuNumber;
+ TUint32 iStartTime;
+#endif
+ PROFILER_DEFINE_ISA_TASK_NAME_ARRAY
+
+private:
+ enum TState {EStop,ERunning,EStopping};
+
+ const TUint* iInterruptStack;
+
+ TUint iLastThread;
+ TUint iRepeat;
+#ifndef __SMP__
+ TUint32 iStartTime;
+#endif
+ RPropertyRef iIsaStartAddr;
+ RPropertyRef iIsaEndAddr;
+ RPropertyRef iIsaPluginStatus;
+ RPropertyRef iIsaOsTaskRunning;
+ TInt iIsaStatus;
+ TInt iIsaStart;
+ TInt iIsaEnd;
+ TUint32 iMask;
+ TUint32 iCpuSelector;
+};
+
+struct TProfilerGppSamplerData
+{
+//public:
+ TUint32 lastPcValue;
+ TUint32 sampleNumber;
+ TInt samplingPeriod;
+};
+
+template <int BufferSize>
+class DProfilerGppSampler : public DProfilerGenericSampler<BufferSize>
+{
+public:
+#ifndef __SMP__
+ DProfilerGppSampler();
+#else
+ DProfilerGppSampler(TInt aCpuNumber);
+#endif
+ ~DProfilerGppSampler();
+
+ struct TProfilerGppSamplerData* GetExportData();
+ void Sample();
+ TInt Reset(DProfilerSampleStream* aStream, TUint32 aSyncOffset);
+ TInt GetPeriod();
+
+private:
+ DGppSamplerImpl gppSamplerImpl;
+ struct TProfilerGppSamplerData exportData;
+#ifdef __SMP__
+ TInt iCpuNumber;
+#endif
+};
+
+/*
+ *
+ * GPP sampler implementation
+ *
+ */
+#ifndef __SMP__
+template <int BufferSize>
+DProfilerGppSampler<BufferSize>::DProfilerGppSampler() :
+ DProfilerGenericSampler<BufferSize>(PROFILER_GPP_SAMPLER_ID)
+ {
+ LOGSTRING2("CProfilerGppSampler<%d>::CProfilerGppSampler",BufferSize);
+ }
+#else
+template <int BufferSize>
+DProfilerGppSampler<BufferSize>::DProfilerGppSampler(TInt aCpuNumber) :
+ DProfilerGenericSampler<BufferSize>(PROFILER_GPP_SAMPLER_ID+(aCpuNumber*20)), iCpuNumber(aCpuNumber)
+ {
+ LOGSTRING2("CProfilerGppSampler<%d>::CProfilerGppSampler",BufferSize);
+ }
+#endif
+
+template <int BufferSize>
+DProfilerGppSampler<BufferSize>::~DProfilerGppSampler()
+ {
+ LOGSTRING2("CProfilerGppSampler<%d>::~CProfilerGppSampler",BufferSize);
+ }
+
+template <int BufferSize>
+TInt DProfilerGppSampler<BufferSize>::Reset(DProfilerSampleStream* aStream, TUint32 aSyncOffset)
+ {
+ LOGSTRING2("CProfilerGppSampler<%d>::Reset - calling superclass reset",BufferSize);
+ DProfilerGenericSampler<BufferSize>::Reset(aStream, 0);
+ LOGSTRING2("CProfilerGppSampler<%d>::Reset - called superclass reset",BufferSize);
+
+ this->gppSamplerImpl.Reset();
+
+#ifdef __SMP__
+ this->gppSamplerImpl.iCpuNumber = this->iCpuNumber;
+
+ // set common start time for all CPU samplers
+ this->gppSamplerImpl.iStartTime = aSyncOffset;
+#endif
+ this->gppSamplerImpl.iGppSamplingPeriod = this->iSamplingPeriod;
+ this->gppSamplerImpl.iSampleCount = 0;
+ this->exportData.sampleNumber = 0;
+ this->exportData.lastPcValue = 0;
+ this->exportData.samplingPeriod = this->gppSamplerImpl.iGppSamplingPeriod;
+
+ TInt length = gppSamplerImpl.CreateFirstSample();
+ LOGSTRING3("CProfilerGPPSampler<%d>::Reset - got first sample, size %d",BufferSize,length);
+
+ this->iSampleBuffer->AddSample(gppSamplerImpl.tempBuf,length);
+
+ // check if sampling period > 1 ms
+ // NOTE: feature supported in Performance Investigator 2.01 and above
+ if(this->gppSamplerImpl.iGppSamplingPeriod > 1)
+ {
+ // For Address/Thread (GPP) version 2.01 or above, the first word is the sampling period in milliseconds
+ TUint8* w = gppSamplerImpl.tempBuf;
+
+ (*w++) = (this->gppSamplerImpl.iGppSamplingPeriod >> 24) & 0xFF;
+ (*w++) = (this->gppSamplerImpl.iGppSamplingPeriod >> 16) & 0xFF;
+ (*w++) = (this->gppSamplerImpl.iGppSamplingPeriod >> 8) & 0xFF;
+ (*w++) = (this->gppSamplerImpl.iGppSamplingPeriod) & 0xFF;
+
+ this->iSampleBuffer->AddSample(gppSamplerImpl.tempBuf,4);
+ }
+
+ LOGSTRING2("CProfilerGPPSampler<%d>::Reset finished",BufferSize);
+ return KErrNone;
+ }
+
+template <int BufferSize>
+void DProfilerGppSampler<BufferSize>::Sample()
+ {
+ LOGSTRING2("CProfilerGppSampler<%d>::Sample",BufferSize);
+// if(this->gppSamplerImpl.iSampleCount % 1000 == 0)
+// {
+//#ifdef __SMP__
+// if(this->iCpuNumber == 0) // print sample tick only from CPU 0 context
+// {
+//#endif
+// Kern::Printf(("PIPROF SAMPLE TICK, #%d"),exportData.sampleNumber);
+//#ifdef __SMP__
+// }
+//#endif
+// }
+
+ TInt length(gppSamplerImpl.SampleImpl());
+
+ this->gppSamplerImpl.iSampleCount++;
+ this->exportData.sampleNumber += this->gppSamplerImpl.iGppSamplingPeriod;
+ this->exportData.lastPcValue = gppSamplerImpl.iLastPc;
+
+ if(length > 0)
+ {
+ this->iSampleBuffer->AddSample(gppSamplerImpl.tempBuf,length);
+ }
+
+ LOGSTRING3("CProfilerGppSampler<%d>::Sample - length %d",BufferSize,length);
+
+ return;
+ }
+
+
+template <int BufferSize>
+struct TProfilerGppSamplerData* DProfilerGppSampler<BufferSize>::GetExportData()
+ {
+ LOGSTRING2("CProfilerGppSampler<%d>::GetExportData",BufferSize);
+ return &(this->exportData);
+ }
+
+template <int BufferSize>
+TInt DProfilerGppSampler<BufferSize>::GetPeriod()
+ {
+ return this->gppSamplerImpl.iGppSamplingPeriod;
+ }
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/inc/IttEventHandler.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,65 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Event based ITT sampler skeleton copypasted from MemoryEventHandler.h
+*
+*/
+#include "IttSamplerImpl.h"
+
+#ifndef __PI_ITT_EVENT_HANDLER__
+#define __PI_ITT_EVENT_HANDLER__
+
+#include <piprofiler/ProfilerGenericClassesKrn.h>
+
+// CONSTANTS
+const TInt KITTBufferSize = 256;
+
+class DProfilerSampleBuffer;
+
+/*
+ * ITT event handler for listaning kernel events
+ */
+class DIttEventHandler : public DKernelEventHandler
+ {
+public:
+ // constructor
+ DIttEventHandler(DProfilerSampleBuffer* aSampleBuffer, TProfilerGppSamplerData* aGppSamplerDataIn);
+ TInt Create();
+ ~DIttEventHandler();
+ TInt Start();
+ TInt Stop();
+ TBool Tracking() {return iTracking;}
+
+ TBool SampleNeeded();
+
+private:
+ static TUint EventHandler(TKernelEvent aEvent, TAny* a1, TAny* a2, TAny* aThis);
+ TUint HandleEvent(TKernelEvent aType, TAny* a1, TAny* a2);
+ // handle code segments
+ TBool HandleAddCodeSeg(DCodeSeg* aSeg);
+ TBool HandleRemoveCodeSeg(DCodeSeg* aSeg);
+
+private:
+ /** Lock serialising calls to event handler */
+ DMutex* iLock;
+ TBool iTracking;
+ DProfilerSampleBuffer* iSampleBuffer;
+
+ TUint32 iCount;
+
+ TUint8 iSample[KITTBufferSize];
+ TPtr8 iSampleDescriptor;
+ TProfilerGppSamplerData* gppSamplerData;
+ };
+
+#endif //__PI_ITT_EVENT_HANDLER__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/inc/IttSamplerImpl.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,327 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#ifndef PROFILER_ITT_SAMPLER_H
+#define PROFILER_ITT_SAMPLER_H
+
+#include "GeneralsConfig.h"
+
+#include <kern_priv.h>
+
+#include <piprofiler/ProfilerGenericClassesKrn.h>
+#include <piprofiler/ProfilerTraces.h>
+#include "GppSamplerImpl.h"
+#include "IttEventHandler.h"
+
+// CONSTANTS
+const TInt KITTSampleBufferSize = 256;
+
+// flags
+#define ITT_EVENT_HANDLER // enable event based ITT sampling
+
+/*
+ *
+ * ITT sampler definition
+ *
+ */
+class DIttEventHandler;
+
+/*
+ * User side ITT sampler
+ */
+class IttSamplerImpl
+{
+public:
+ IttSamplerImpl();
+ ~IttSamplerImpl();
+
+ TInt SampleImpl(TUint32 pc,TUint32 sampleNum);
+ TBool SampleNeeded(TUint32 sampleNum);
+ TInt CreateFirstSample();
+ void Reset();
+ TInt ProcessEvent();
+
+ TUint8* itt_sample;
+ TInt iIttSamplingPeriod;
+ TInt iIttSamplingPeriodDiv2;
+ TBool iTimeToSample;
+#ifdef ITT_EVENT_HANDLER
+ TBool iEventReceived;
+ TBool iFirstSampleTaken;
+#endif
+
+private:
+#ifdef ITT_EVENT_HANDLER
+ TInt iCount;
+#endif
+ TInt currentLibCount;
+ TInt currentProcCount;
+
+ TUint8 sample[KITTSampleBufferSize ];
+ TPtr8 sampleDescriptor;
+
+ TBuf8<64> iVersionData;
+ SDblQue* codeSegList;
+
+};
+
+/*
+ * ITT sampler kernel part
+ *
+ */
+template <int BufferSize>
+class DProfilerIttSampler : public DProfilerGenericSampler<BufferSize>
+{
+public:
+ DProfilerIttSampler(struct TProfilerGppSamplerData* gppSamplerDataIn);
+ ~DProfilerIttSampler();
+
+ void Sample();
+ TInt Reset(DProfilerSampleStream* aStream, TUint32 aSyncOffset);
+ TInt PostSample();
+ TBool PostSampleNeeded();
+
+private:
+#ifdef ITT_EVENT_HANDLER
+ DIttEventHandler* iEventHandler;
+#endif
+ IttSamplerImpl ittSamplerImpl;
+ struct TProfilerGppSamplerData* gppSamplerData;
+ TBool sampleInProgress;
+ TBool sampleNeeded;
+};
+
+/*
+ * ITT sampler implementation
+ *
+ */
+template <int BufferSize>
+DProfilerIttSampler<BufferSize>::DProfilerIttSampler(struct TProfilerGppSamplerData* gppSamplerDataIn) :
+ DProfilerGenericSampler<BufferSize>(PROFILER_ITT_SAMPLER_ID)
+{
+ this->gppSamplerData = (struct TProfilerGppSamplerData*)gppSamplerDataIn;
+ this->sampleInProgress = false;
+ LOGSTRING2("CProfilerIttSampler<%d>::CProfilerIttSampler",BufferSize);
+}
+
+/*
+ * DProfilerIttSampler::Reset()
+ *
+ * @param DProfilerSampleStream* sample stream
+ * @param TUint32 Offset
+ */
+template <int BufferSize>
+TInt DProfilerIttSampler<BufferSize>::Reset(DProfilerSampleStream* aStream, TUint32 aSyncOffset)
+{
+ Kern::Printf("DProfilerIttSampler<%d>::Reset - calling superclass reset",BufferSize);
+ DProfilerGenericSampler<BufferSize>::Reset(aStream);
+
+ // check if reset called in stop (by driver)
+ if(aSyncOffset != 999999)
+ {
+#ifdef ITT_EVENT_HANDLER
+ // Itt event handler
+ if(iEventHandler)
+ {
+ // stop previous sampling if still running
+ Kern::Printf("Stopping DIttEventHandler");
+ iEventHandler->Stop();
+ iEventHandler->Close();
+ iEventHandler = NULL;
+ }
+
+ Kern::Printf("Initiating DIttEventHandler");
+ iEventHandler = new DIttEventHandler(this->iSampleBuffer, this->gppSamplerData);
+ if(iEventHandler)
+ {
+ Kern::Printf("Creating DIttEventHandler");
+ TInt err(iEventHandler->Create());
+ if(err != KErrNone)
+ {
+ Kern::Printf("Error in creation of DIttEventHandler, error %d", err);
+ return err;
+ }
+ }
+ else
+ {
+ Kern::Printf("Could not initiate DIttEventHandler");
+ return KErrGeneral;
+ }
+
+ // set first sample at the 10 ms, should be enough
+ this->ittSamplerImpl.iIttSamplingPeriod = 10;
+#else
+ this->ittSamplerImpl.iIttSamplingPeriod = this->iSamplingPeriod;
+#endif
+ this->ittSamplerImpl.iIttSamplingPeriodDiv2 = (TInt)(this->ittSamplerImpl.iIttSamplingPeriod / 2);
+ LOGSTRING3("CProfilerIttSampler<%d>::Reset - set ITT sampling period to %d",
+ BufferSize,this->ittSamplerImpl.iIttSamplingPeriod);
+ }
+ else
+ {
+ LOGSTRING2("DProfilerIttSampler<%d>::Reset - reset in stop", BufferSize);
+#ifdef ITT_EVENT_HANDLER
+ // destroy memory event handler
+ if(iEventHandler)
+ {
+ // stop previous sampling if still running
+ iEventHandler->Stop();
+ iEventHandler->Close();
+ iEventHandler = NULL;
+ }
+#endif
+ return KErrNone; // return if reset called in stop
+ }
+
+ TInt length(ittSamplerImpl.CreateFirstSample());
+ this->iSampleBuffer->AddSample((TUint8*)&length,1);
+ this->iSampleBuffer->AddSample(ittSamplerImpl.itt_sample, length);
+ this->sampleInProgress = false;
+ this->sampleNeeded = false;
+ //LOGSTRING("DProfilerIttSampler::Reset - exit");
+ this->ittSamplerImpl.Reset();
+ return KErrNone;
+
+}
+
+/*
+ * DProfilerIttSampler::PostSample
+ *
+ * Function for finishing sample
+ */
+template <int BufferSize>
+TInt DProfilerIttSampler<BufferSize>::PostSample()
+{
+#ifdef ITT_EVENT_HANDLER
+ if(!ittSamplerImpl.iFirstSampleTaken) // if we haven't read the initial state
+ {
+#endif
+ if(sampleNeeded)
+ {
+ this->sampleNeeded = false;
+ //LOGSTRING3("CProfilerIttSampler<%d>::PostSample - state %d",BufferSize,this->iSampleBuffer->GetBufferStatus());
+ //Kern::Printf("DProfilerIttSampler<%d>::PostSample - state %d",BufferSize,this->iSampleBuffer->GetBufferStatus());
+
+ TInt length = this->ittSamplerImpl.SampleImpl(this->gppSamplerData->lastPcValue,
+ this->gppSamplerData->sampleNumber);
+ if(length != 0)
+ {
+ LOGSTRING("ITT sampler PostSample - starting to sample");
+
+ while(length > 0)
+ {
+ this->iSampleBuffer->AddSample(ittSamplerImpl.itt_sample,length);
+ length = this->ittSamplerImpl.SampleImpl( this->gppSamplerData->lastPcValue,
+ this->gppSamplerData->sampleNumber );
+ if(length == 0)
+ {
+ LOGSTRING("MEM sampler PostSample - all samples generated!");
+ }
+ }
+ LOGSTRING("ITT sampler PostSample - finished sampling");
+ }
+ this->sampleInProgress = false;
+ }
+#ifdef ITT_EVENT_HANDLER
+ }
+ if(!iEventHandler->Tracking())
+ {
+ iEventHandler->Start();
+ Kern::Printf("DProfilerITTSampler<%d>::PostSample - ITT handler started",BufferSize);
+ }
+
+#endif
+
+ LOGSTRING2("ITT sampler PostSample - finished sampling, time: %d", gppSamplerData->sampleNumber);
+
+ // finally perform superclass postsample
+ TInt i(this->DProfilerGenericSampler<BufferSize>::PostSample());
+ return i;
+}
+
+/*
+ * DProfilerIttSampler::PostSampleNeeded()
+ *
+ * Function for deciding if sample handling is needed
+ */
+template <int BufferSize>
+TBool DProfilerIttSampler<BufferSize>::PostSampleNeeded()
+{
+ LOGSTRING3("CProfilerIttSampler<%d>::PostSampleNeeded - state %d",BufferSize,this->iSampleBuffer->GetBufferStatus());
+
+ TUint32 status = this->iSampleBuffer->iBufferStatus;
+
+ if(status == DProfilerSampleBuffer::BufferCopyAsap || status == DProfilerSampleBuffer::BufferFull || this->sampleNeeded == true)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+/*
+ * DProfilerIttSampler::Sample
+ *
+ * Function for initiating sampling
+ */
+template <int BufferSize>
+void DProfilerIttSampler<BufferSize>::Sample()
+{
+ LOGSTRING2("CProfilerIttSampler<%d>::Sample",BufferSize);
+
+ //#ifdef ITT_TEST
+ LOGSTRING2("CProfilerIttSampler<%d>::Sample",BufferSize);
+
+ if(ittSamplerImpl.SampleNeeded(this->gppSamplerData->sampleNumber) && this->sampleInProgress == false)
+ {
+ this->sampleInProgress = true;
+ this->sampleNeeded = true;
+
+ LOGSTRING2("CProfilerIttSampler<%d>::Sample - sample needed",BufferSize);
+ }
+#ifdef ITT_EVENT_HANDLER
+ // call this to increase the time stamp
+ else if(iEventHandler->SampleNeeded())
+ {
+ // set the flag for post sampling
+ this->sampleNeeded = true;
+ }
+#endif
+
+ LOGSTRING2("CProfilerIttSampler<%d>::Sample",BufferSize);
+ return;
+}
+
+/*
+ * Destructor
+ */
+template <int BufferSize>
+DProfilerIttSampler<BufferSize>::~DProfilerIttSampler()
+{
+ LOGSTRING2("CProfilerIttSampler<%d>::~CProfilerIttSampler",BufferSize);
+#ifdef ITT_EVENT_HANDLER
+ if(iEventHandler)
+ {
+ // stop previous sampling if still running
+ iEventHandler->Stop();
+ iEventHandler->Close();
+ iEventHandler = NULL;
+ }
+#endif
+}
+#endif
+// end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/inc/MemSamplerImpl.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,427 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef PROFILER_MEM_SAMPLER_H
+#define PROFILER_MEM_SAMPLER_H
+
+#include "GeneralsConfig.h"
+
+#include <kern_priv.h>
+
+#include <piprofiler/ProfilerGenericClassesKrn.h>
+#include <piprofiler/ProfilerTraces.h>
+#include "GppSamplerImpl.h"
+#include "MemoryEventHandler.h"
+#include <e32btrace.h>
+
+
+// constants
+// defines the maximum thread amount that is assumed to
+// be possible with MEM trace
+const TInt KSampleBufferSize = 257;
+const TInt KProfilerMaxThreadsAmount = 512;
+const TInt KProfilerMaxChunksAmount = 1024;
+const TInt KProfilerMaxLibrariesAmount = 1024;
+const TInt KProfilerTotalMemorySamplePeriod = 100;
+
+// flags
+#define MEM_EVENT_HANDLER
+//#define MEM_EVENT_HANDLER_LIBRARY_EVENTS
+
+/*
+ *
+ * MEM sampler definition
+ *
+ */
+
+class DMemoryEventHandler;
+
+class DMemSamplerImpl //: public DBase
+{
+public:
+ enum EProcessingState
+ {
+ EStartingToProcess,
+ EProcessingNames,
+ EProcessingData,
+ ENothingToProcess
+ };
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+ enum ESampleType
+ {
+ ESampleChunks,
+ ESampleThreads,
+ ESampleLibraries
+ };
+#endif
+
+ DMemSamplerImpl();
+ ~DMemSamplerImpl();
+
+ TInt CreateFirstSample();
+ TInt SampleImpl();
+ TBool SampleNeeded();
+ void Reset();
+ TInt ProcessChunks();
+ TInt ProcessThreads();
+ TInt GatherChunks();
+ TInt GatherThreads();
+
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+ TInt GatherLibraries();
+ TInt ProcessLibraries();
+#endif
+
+ TInt EncodeChunkData(DChunk& chunk);
+ TInt EncodeChunkName(DChunk& chunk);
+ TInt EncodeChunkData(DThread& thread);
+ TInt EncodeChunkName(DThread& thread);
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+ TInt EncodeChunkData(DLibrary& library);
+ TInt EncodeChunkName(DLibrary& library);
+#endif
+
+ TInt EncodeTotalMemoryName();
+ TInt EncodeTotalMemory();
+
+ TInt EncodeNameCode();
+ TInt EncodeDataCode();
+
+ DChunk* heapChunksToSample[KProfilerMaxChunksAmount];
+ DChunk* heapChunkNamesToReport[KProfilerMaxChunksAmount];
+ TInt iCount;
+ TInt iChunkCount;
+ TInt iNewChunkCount;
+ TBuf8<0x50> name;
+ DThread* threadsToSample[KProfilerMaxThreadsAmount];
+ DThread* threadNamesToReport[KProfilerMaxThreadsAmount];
+ TInt iThreadCount;
+ TInt iNewThreadCount;
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+ DLibrary* librariesToSample[KProfilerMaxLibrariesAmount];
+ DLibrary* libraryNamesToReport[KProfilerMaxLibrariesAmount];
+ TInt iLibraryCount;
+ TInt iNewLibraryCount;
+ TInt iLibrariesProcessing;
+#endif
+
+ TInt iChunksProcessing;
+ TInt iThreadsProcessing;
+ TInt iMemSamplingPeriod;
+ TInt iMemSamplingPeriodDiv2;
+ TInt iMemSamplingPeriodDiv3;
+
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+ ESampleType iSampleType;
+#else
+ TBool iSampleThreads;
+#endif
+
+ TBool iTimeToSample;
+
+ TBool iTotalMemoryOk;
+ TBool iTotalMemoryNameOk;
+
+ TUint8 sample[KSampleBufferSize];
+ TPtr8 sampleDescriptor;
+
+ // test
+#ifdef MEM_EVENT_HANDLER
+// DMemoryEventHandler* iEventHandler;
+ TBool iChunksGathered;
+ TBool iThreadsGathered;
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+ TBool iLibrariesGathered;
+#endif
+#endif
+};
+
+
+template <int BufferSize>
+class DProfilerMemSampler : public DProfilerGenericSampler<BufferSize>
+{
+public:
+ DProfilerMemSampler(struct TProfilerGppSamplerData*, TInt id);
+ ~DProfilerMemSampler();
+
+ void Sample();
+ TInt Reset(DProfilerSampleStream* aStream, TUint32 aSyncOffset);
+ TInt PostSample();
+ TBool PostSampleNeeded();
+
+private:
+#ifdef MEM_EVENT_HANDLER
+ DMemoryEventHandler* iEventHandler;
+#endif
+ DMemSamplerImpl memSamplerImpl;
+ struct TProfilerGppSamplerData* gppSamplerData;
+ TBool sampleNeeded;
+};
+
+/*
+ *
+ * MEM sampler implementation
+ *
+ */
+
+template <int BufferSize>
+DProfilerMemSampler<BufferSize>::DProfilerMemSampler(struct TProfilerGppSamplerData* gppSamplerDataIn, TInt id) :
+ DProfilerGenericSampler<BufferSize>(PROFILER_MEM_SAMPLER_ID)
+ {
+ LOGSTRING2("DProfilerMemSampler<%d>::CProfilerMemSampler",BufferSize);
+ this->gppSamplerData = gppSamplerDataIn;
+ this->iSamplingPeriod = 3000; // set default setting
+ }
+
+template <int BufferSize>
+TInt DProfilerMemSampler<BufferSize>::Reset(DProfilerSampleStream* aStream, TUint32 aSyncOffset)
+ {
+//#ifdef MEM_EVENT_HANDLER
+// Kern::Printf("DProfilerMemSampler<%d>::Reset - calling superclass reset",BufferSize);
+
+//#endif
+ // check if reset called in stop (by driver)
+ if(aSyncOffset != 999999)
+ {
+ DProfilerGenericSampler<BufferSize>::Reset(aStream);
+ memSamplerImpl.Reset();
+
+#ifdef MEM_EVENT_HANDLER
+ // reset member variables
+ this->memSamplerImpl.iThreadsGathered = false;
+ this->memSamplerImpl.iChunksGathered = false;
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+ this->memSamplerImpl.iLibrariesGathered = false;
+#endif
+
+ // memory event handler
+ if(iEventHandler)
+ {
+ // stop previous sampling if still running
+// Kern::Printf("Stopping DMemoryEventHandler");
+ iEventHandler->Stop();
+ iEventHandler->Close();
+ iEventHandler = NULL;
+ }
+
+// Kern::Printf("Initiating DMemoryEventHandler");
+ iEventHandler = new DMemoryEventHandler(this->iSampleBuffer);
+ if(iEventHandler)
+ {
+// Kern::Printf("Creating DMemoryEventHandler");
+ TInt err(iEventHandler->Create());
+ if(err != KErrNone)
+ {
+ Kern::Printf("Error in creation of DMemoryEventHandler, error %d", err);
+ return err;
+ }
+ }
+ else
+ {
+ Kern::Printf("Could not initiate DMemoryEventHandler");
+ return KErrGeneral;
+ }
+
+ // set first chunk&thread memory lookup at the 5 ms, should be enough
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+ this->memSamplerImpl.iMemSamplingPeriod = 45;
+#else
+ this->memSamplerImpl.iMemSamplingPeriod = 10;
+#endif
+
+#else
+ this->memSamplerImpl.iMemSamplingPeriod = this->iSamplingPeriod;
+#endif
+ this->memSamplerImpl.iMemSamplingPeriodDiv2 = (TInt)(this->memSamplerImpl.iMemSamplingPeriod / 2);
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+ this->memSamplerImpl.iMemSamplingPeriodDiv3 = (TInt)(this->memSamplerImpl.iMemSamplingPeriod / 3);
+#endif
+
+ LOGSTRING3("CProfilerMemSampler<%d>::Reset - set mem sampling period to %d",
+ BufferSize,this->memSamplerImpl.iMemSamplingPeriod);
+ }
+ else
+ {
+ LOGSTRING2("DProfilerMemSampler<%d>::Reset - reset in stop", BufferSize);
+#ifdef MEM_EVENT_HANDLER
+ // destroy memory event handler
+ if(iEventHandler)
+ {
+ // stop previous sampling if still running
+// Kern::Printf("Stopping DMemoryEventHandler");
+ iEventHandler->Stop();
+ iEventHandler->Close();
+ iEventHandler = NULL;
+ }
+#endif
+ return KErrNone; // return if reset called in stop
+ }
+
+ // add MEM sample header
+ TInt length(memSamplerImpl.CreateFirstSample());
+ this->iSampleBuffer->AddSample(memSamplerImpl.sample,length);
+
+ this->sampleNeeded = false;
+ LOGSTRING("DProfilerMemSampler::Reset - exit");
+ return KErrNone;
+ }
+
+template <int BufferSize>
+TInt DProfilerMemSampler<BufferSize>::PostSample()
+ {
+ this->sampleNeeded = false;
+
+ LOGSTRING3("DProfilerMemSampler<%d>::PostSample - state %d",BufferSize,this->iSampleBuffer->GetBufferStatus());
+
+#ifdef MEM_EVENT_HANDLER
+ // check if all threads and chunks (and libraries) are gathered
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+ if(!memSamplerImpl.iThreadsGathered || !memSamplerImpl.iChunksGathered || !memSamplerImpl.iLibrariesGathered)
+#else
+ if(!memSamplerImpl.iThreadsGathered || !memSamplerImpl.iChunksGathered)
+#endif
+ {
+#endif
+ // disable interrupts for checking the kernel containers (EChunk, EThread)
+// TInt interruptLevel(NKern::DisableInterrupts(0));
+
+ // first collect chunk data
+ TInt length(this->memSamplerImpl.SampleImpl());
+ if(length != 0)
+ {
+ // then, encode the sample to the buffer until no further data available
+ while(length > 0)
+ {
+ this->iSampleBuffer->AddSample(memSamplerImpl.sample,length);
+ length = this->memSamplerImpl.SampleImpl();
+
+ // indicate that the whole MEM sample ends by having a 0x00 in the end
+ if(length == 0)
+ {
+ TUint8 number(0);
+ LOGSTRING("MEM sampler PostSample - all samples generated!");
+
+ this->iSampleBuffer->AddSample(&number,1);
+ LOGSTRING2("MEM sampler PostSample - end mark added, time: %d", gppSamplerData->sampleNumber);
+ }
+ }
+ }
+ // restore interrupts and continue normal execution
+// NKern::RestoreInterrupts(interruptLevel);
+#ifdef MEM_EVENT_HANDLER
+ }
+ // check if all threads and chunks are gathered
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+ if(memSamplerImpl.iThreadsGathered && memSamplerImpl.iChunksGathered && memSamplerImpl.iLibrariesGathered)
+#else
+ if(memSamplerImpl.iThreadsGathered && memSamplerImpl.iChunksGathered)
+#endif
+ {
+ // start memory event tracking after checking the current memory status
+ if(!iEventHandler->Tracking())
+ {
+ iEventHandler->Start();
+// Kern::Printf("DProfilerMemSampler<%d>::PostSample - memory event handler started",BufferSize);
+ }
+
+ }
+#endif
+
+ LOGSTRING2("MEM sampler PostSample - finished sampling, time: %d", gppSamplerData->sampleNumber);
+
+ // finally perform superclass postsample
+ TInt i(this->DProfilerGenericSampler<BufferSize>::PostSample());
+ return i;
+ }
+
+template <int BufferSize>
+TBool DProfilerMemSampler<BufferSize>::PostSampleNeeded()
+ {
+ LOGSTRING3("DProfilerMemSampler<%d>::PostSampleNeeded - state %d",BufferSize,this->iSampleBuffer->GetBufferStatus());
+
+ TUint32 status(this->iSampleBuffer->iBufferStatus);
+
+ if(status == DProfilerSampleBuffer::BufferCopyAsap || status == DProfilerSampleBuffer::BufferFull || this->sampleNeeded == true)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+template <int BufferSize>
+void DProfilerMemSampler<BufferSize>::Sample()
+ {
+ LOGSTRING2("DProfilerMemSampler<%d>::Sample",BufferSize);
+
+ // check if sample is needed, i.e. the sampling interval is met
+ if(memSamplerImpl.SampleNeeded())
+ {
+ // set the flag for post sampling
+ this->sampleNeeded = true;
+
+ // start the MEM sample with the sample time
+ TUint8 number(4); // mem sampler id
+ this->iSampleBuffer->AddSample(&number,1);
+ this->iSampleBuffer->AddSample((TUint8*)&(gppSamplerData->sampleNumber),4);
+
+ // leave the rest of the processing for PostSample()
+ }
+
+#ifdef MEM_EVENT_HANDLER
+ // call this to increase the time stamp
+ else if(iEventHandler->SampleNeeded())
+ {
+ // set the flag for post sampling
+ this->sampleNeeded = true;
+ }
+
+// // check if time stamp is divibable with
+// if((memSamplerImpl.iCount % KProfilerTotalMemorySamplePeriod) == 0 &&
+// memSamplerImpl.iCount > 0)
+// {
+// // sample total memory once per 100 ms
+// memSamplerImpl.EncodeTotalMemory();
+//
+// // add end mark
+// TUint8 number(0);
+// this->iSampleBuffer->AddSample(&number,1);
+// }
+#endif
+
+ LOGSTRING2("CProfilerMemSampler<%d>::Sample",BufferSize);
+ return;
+ }
+
+template <int BufferSize>
+DProfilerMemSampler<BufferSize>::~DProfilerMemSampler()
+ {
+ LOGSTRING2("CProfilerMemSampler<%d>::~CProfilerMemSampler",BufferSize);
+#ifdef MEM_EVENT_HANDLER
+ // memory event handler
+ if(iEventHandler)
+ {
+ // stop previous sampling if still running
+// Kern::Printf("Stopping DMemoryEventHandler");
+ iEventHandler->Stop();
+ iEventHandler->Close();
+ iEventHandler = NULL;
+ }
+#endif
+ }
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/inc/MemoryEventHandler.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,91 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+#include "MemSamplerImpl.h"
+
+#ifndef __PI_MEMORY_EVENT_HANDLER__
+#define __PI_MEMORY_EVENT_HANDLER__
+
+#include <piprofiler/ProfilerGenericClassesKrn.h>
+
+// CONSTANTS
+const TInt KEventBufferSize = 257;
+
+class DProfilerSampleBuffer;
+
+class DMemoryEventHandler : public DKernelEventHandler
+ {
+public:
+ // constructor
+ DMemoryEventHandler(DProfilerSampleBuffer* aSampleBuffer);
+ TInt Create();
+ ~DMemoryEventHandler();
+ TInt Start();
+ TInt Stop();
+ TBool Tracking() {return iTracking;}
+
+ TBool SampleNeeded();
+
+private:
+ static TUint EventHandler(TKernelEvent aEvent, TAny* a1, TAny* a2, TAny* aThis);
+ TUint HandleEvent(TKernelEvent aType, TAny* a1, TAny* a2);
+ // handle chunk activity
+ TBool HandleAddChunk(DChunk* aChunk);
+ TBool HandleUpdateChunk(DChunk* aChunk);
+ TBool HandleDeleteChunk(DChunk* aChunk);
+ // handle chunk activity
+ TBool HandleAddThread(DThread* aThread);
+ TBool HandleUpdateThread(DThread* aThread);
+ TBool HandleDeleteThread(DThread* aThread);
+ // handle chunk activity
+ TBool HandleAddProcess(DProcess* aProcess);
+ TBool HandleUpdateProcess(DProcess* aProcess);
+ TBool HandleDeleteProcess(DProcess* aProcess);
+ // handle library activity
+ TBool HandleAddLibrary(DLibrary* aLibrary, DThread* aThread);
+ TBool HandleDeleteLibrary(DLibrary* aLibrary);
+
+ // data handling
+ TInt AddHeader();
+ TInt AddFooter();
+ TInt EncodeTotalMemory();
+ TInt EncodeNameCode();
+ TInt EncodeNewCode();
+ TInt EncodeUpdateCode();
+ TInt EncodeRemoveCode();
+ TInt EncodeChunkName(DThread& t);
+ TInt EncodeChunkName(DChunk& c);
+ TInt EncodeChunkName(DLibrary& l);
+ TInt EncodeChunkData(DThread& t);
+ TInt EncodeChunkData(DChunk& c);
+ TInt EncodeChunkData(DLibrary& l, DThread& t);
+private:
+ /** Lock serialising calls to event handler */
+ DMutex* iLock;
+ TBool iTracking;
+
+ DProfilerSampleBuffer* iSampleBuffer;
+ TInt iCounters[EEventLimit];
+
+ TUint32 iCount;
+
+ TUint8 iSample[KEventBufferSize];
+ TPtr8 iSampleDescriptor;
+
+ TUint32 iPreviousCount;
+ };
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/inc/PriSamplerImpl.h Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,245 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef PROFILER_PRI_SAMPLER_H
+#define PROFILER_PRI_SAMPLER_H
+
+#include "GeneralsConfig.h"
+
+#include <kern_priv.h>
+
+#include <piprofiler/ProfilerGenericClassesKrn.h>
+#include <piprofiler/ProfilerTraces.h>
+#include "GppSamplerImpl.h"
+
+// defines the maximum thread amount that is assumed to
+// be possible with PRI trace
+const TInt KProfilerMaxThreadAmount = 512;
+
+/*
+ *
+ * PRI sampler definition
+ *
+ */
+
+class DPriSamplerImpl //: public DBase
+{
+public:
+ enum EProcessingState
+ {
+ EStartingToProcess,
+ EProcessingNames,
+ EProcessingData,
+ ENothingToProcess
+ };
+
+ DPriSamplerImpl();
+ ~DPriSamplerImpl();
+
+ TInt CreateFirstSample();
+ TInt SampleImpl();
+ TBool SampleNeeded();
+ void Reset();
+ TInt ProcessChunks();
+
+ TInt EncodeChunkData(DThread& thread);
+ TInt EncodeChunkName(DThread& thread);
+
+ TInt EncodeNameCode();
+ TInt EncodeDataCode();
+
+ TInt iCountti;
+ DThread* threadsToSample[KProfilerMaxThreadAmount];
+ DThread* threadNamesToReport[KProfilerMaxThreadAmount];
+
+ TInt iThreadCount;
+ TInt iNewThreadCount;
+
+ TInt iProcessing;
+ TInt iPriSamplingPeriod;
+
+ TUint8 sample[257];
+ TPtr8 sampleDescriptor;
+#ifdef __SMP__
+ TInt iCpuNumber;
+ TUint32 iStartTime;
+#endif
+
+};
+
+template <int BufferSize>
+class DProfilerPriSampler : public DProfilerGenericSampler<BufferSize>
+{
+public:
+ DProfilerPriSampler(struct TProfilerGppSamplerData*, TInt id);
+ ~DProfilerPriSampler();
+
+ void Sample();
+ TInt Reset(DProfilerSampleStream* aStream, TUint32 aSyncOffset);
+ TInt PostSample();
+ TBool PostSampleNeeded();
+
+private:
+ DPriSamplerImpl priSamplerImpl;
+ struct TProfilerGppSamplerData* gppSamplerData;
+ TBool sampleNeeded;
+ TBool sampleInProgress;
+#ifdef __SMP__
+ TInt iCpuNumber;
+#endif
+};
+
+/*
+ *
+ * PRI sampler implementation
+ *
+ */
+//#ifndef __SMP__
+template <int BufferSize>
+DProfilerPriSampler<BufferSize>::DProfilerPriSampler(struct TProfilerGppSamplerData* gppSamplerDataIn, TInt id) :
+ DProfilerGenericSampler<BufferSize>(PROFILER_PRI_SAMPLER_ID)
+ {
+ LOGSTRING2("CProfilerPriSampler<%d>::CProfilerPriSampler",BufferSize);
+ this->gppSamplerData = gppSamplerDataIn;
+ this->sampleInProgress = false;
+ this->iSamplingPeriod = 3000; // set default setting
+ }
+//#else
+//template <int BufferSize>
+//DProfilerPriSampler<BufferSize>::DProfilerPriSampler(struct TProfilerGppSamplerData* gppSamplerDataIn, TInt id, TInt aCpuNumber) :
+// DProfilerGenericSampler<BufferSize>(PROFILER_PRI_SAMPLER_ID+(aCpuNumber*20)), iCpuNumber(aCpuNumber)
+// {
+// LOGSTRING2("CProfilerGppSampler<%d>::CProfilerGppSampler",BufferSize);
+// }
+//#endif
+
+template <int BufferSize>
+TInt DProfilerPriSampler<BufferSize>::Reset(DProfilerSampleStream* aStream, TUint32 aSyncOffset)
+ {
+ LOGSTRING2("CProfilerPriSampler<%d>::Reset - calling superclass reset",BufferSize);
+ DProfilerGenericSampler<BufferSize>::Reset(aStream);
+ LOGSTRING2("CProfilerPriSampler<%d>::Reset - called superclass reset",BufferSize);
+ priSamplerImpl.Reset();
+
+#ifdef __SMP__
+// this->priSamplerImpl.iCpuNumber = this->iCpuNumber;
+//
+// // set common start time for all CPU samplers
+// this->priSamplerImpl.iStartTime = aSyncOffset;
+#endif
+ this->priSamplerImpl.iPriSamplingPeriod = this->iSamplingPeriod;
+
+
+ LOGSTRING3("CProfilerPriSampler<%d>::Reset - set pri sampling period to",
+ BufferSize,this->priSamplerImpl.iPriSamplingPeriod);
+
+ TInt length(priSamplerImpl.CreateFirstSample());
+ this->iSampleBuffer->AddSample(priSamplerImpl.sample,length);
+
+ this->sampleInProgress = false;
+ this->sampleNeeded = false;
+
+ return KErrNone;
+ }
+
+template <int BufferSize>
+TInt DProfilerPriSampler<BufferSize>::PostSample()
+ {
+ if(sampleNeeded)
+ {
+ this->sampleNeeded = false;
+
+ LOGSTRING3("CProfilerPriSampler<%d>::PostSample - state %d",BufferSize,this->sampleBuffer->GetBufferStatus());
+
+ //TInt interruptLevel = NKern::DisableInterrupts(0);
+
+ TInt length(this->priSamplerImpl.SampleImpl());
+ if(length != 0)
+ {
+ LOGSTRING("PRI sampler PostSample - starting to sample");
+
+ // then, encode the sample to the buffer
+ while(length > 0)
+ {
+ this->iSampleBuffer->AddSample(priSamplerImpl.sample,length);
+ length = this->priSamplerImpl.SampleImpl();
+ // indicate that the whole PRI sample ends by having a 0x00 in the end
+ if(length == 0)
+ {
+ TUint8 number(0);
+ LOGSTRING("PRI sampler PostSample - all samples generated!");
+
+ this->iSampleBuffer->AddSample(&number,1);
+ LOGSTRING("PRI sampler PostSample - end mark added");
+ }
+ }
+ LOGSTRING("PRI sampler PostSample - finished sampling");
+ }
+ this->sampleInProgress = false;
+
+ //NKern::RestoreInterrupts(interruptLevel);
+ }
+
+ // finally perform superclass postsample
+ TInt i(this->DProfilerGenericSampler<BufferSize>::PostSample());
+ return i;
+ }
+
+template <int BufferSize>
+TBool DProfilerPriSampler<BufferSize>::PostSampleNeeded()
+ {
+ LOGSTRING3("CProfilerPriSampler<%d>::PostSampleNeeded - state %d",BufferSize,this->sampleBuffer->GetBufferStatus());
+
+ TUint32 status = this->iSampleBuffer->iBufferStatus;
+
+ if(status == DProfilerSampleBuffer::BufferCopyAsap || status == DProfilerSampleBuffer::BufferFull || this->sampleNeeded == true)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+
+template <int BufferSize>
+void DProfilerPriSampler<BufferSize>::Sample()
+ {
+ LOGSTRING2("CProfilerPriSampler<%d>::Sample",BufferSize);
+
+ if(priSamplerImpl.SampleNeeded() && this->sampleInProgress == false)
+ {
+ this->sampleInProgress = true;
+ this->sampleNeeded = true;
+ // start the PRI sample with the sample time
+ TUint8 number(4);
+ this->iSampleBuffer->AddSample(&number,1);
+ this->iSampleBuffer->AddSample((TUint8*)&(gppSamplerData->sampleNumber),4);
+
+ // leave the rest of the processing for PostSample()
+ }
+
+ LOGSTRING2("CProfilerPriSampler<%d>::Sample",BufferSize);
+ return;
+ }
+
+template <int BufferSize>
+DProfilerPriSampler<BufferSize>::~DProfilerPriSampler()
+ {
+ LOGSTRING2("CProfilerPriSampler<%d>::~CProfilerPriSampler",BufferSize);
+ }
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/src/GeneralsDriver.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,1152 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+//
+// LDD for thread time profiling
+//
+
+#include <kern_priv.h>
+#include <platform.h>
+#include <arm.h>
+
+#ifdef __SMP__
+#include <assp/naviengine/naviengine.h>
+#include <nkernsmp/arm/arm_gic.h>
+#include <nkernsmp/arm/arm_tmr.h>
+#endif
+
+#include "GeneralsDriver.h"
+#include <piprofiler/PluginDriver.h>
+#include <piprofiler/PluginSampler.h>
+#include <piprofiler/ProfilerTraces.h>
+
+#include "GppSamplerImpl.h"
+#include "GfcSamplerImpl.h"
+#include "IttSamplerImpl.h"
+#include "MemSamplerImpl.h"
+#include "PriSamplerImpl.h"
+
+
+#ifndef __SMP__
+extern TUint* IntStackPtr();
+extern void UsrModLr(TUint32*);
+#endif
+// for security check
+#define KProfilerExeSecurUid 0x2001E5AD
+static _LIT_SECURITY_POLICY_PASS(KAllowAllPolicy);
+static _LIT_SECURITY_POLICY_FAIL( KDenyAllPolicy );
+
+#define SEPARATE_DFC_QUEUE
+// CONSTANTS
+
+//_LIT(DProfilerThread,"DProfilerThread");
+//const TInt KDProfilerThreadPriority = 27;
+
+#ifdef SEPARATE_DFC_QUEUE
+const TInt KGeneralsDriverThreadPriority = 24;
+_LIT(KGeneralsDriverThread, "PIGeneralsDriver");
+
+#endif
+
+// global Dfc Que
+//TDynamicDfcQue* gDfcQ;
+
+//#ifdef __SMP__
+//
+//enum TNaviEngineAsspInterruptIdExtension
+//{
+// KIntProfilerBase = 99 // Sampling profiler interrupt base.
+// // Each CPU is assigned a sampling interrupt from this base
+// // CPU-0's sampling interrupt is KIntIdSamplingBase + 0
+// // CPU-n's sampling interrupt is KIntIdSamplingBase + n
+//};
+//#endif
+
+/*
+ *
+ *
+ * Class DGfcProfilerFactory definition
+ *
+ *
+ */
+
+class DGeneralsProfilerFactory : public DLogicalDevice
+{
+ public:
+ DGeneralsProfilerFactory();
+ ~DGeneralsProfilerFactory();
+
+ public:
+ virtual TInt Install();
+ virtual void GetCaps(TDes8& aDes) const;
+ virtual TInt Create(DLogicalChannelBase*& aChannel);
+};
+
+/*
+ *
+ *
+ * Class DGfcDriver definition
+ *
+ *
+ */
+class DPluginDriver;
+
+class DGeneralsDriver : public DPluginDriver
+{
+
+public:
+ DGeneralsDriver();
+ ~DGeneralsDriver();
+
+private:
+ TInt NewStart(TInt aRate);
+ static void NewDoProfilerProfile(TAny*);
+ static void NewDoDfc(TAny*);
+
+ // called by each core
+ static void Sample(TAny*);
+
+ TInt GetSampleTime(TUint32* time);
+ //TInt Test(TUint32 testCase);
+
+ TInt StartSampling();
+ TInt StopSampling();
+
+ void InitialiseSamplerList();
+
+ DProfilerSamplerBase* GetSamplerForId(TInt samplerId);
+ TInt GetSamplerVersion(TDes* aDes);
+
+#ifdef __SMP__
+ void UnbindInterrupts();
+#endif
+ TInt ProcessStreamReadRequest(TBapBuf* aBuf,TRequestStatus* aStatus);
+
+ TInt MarkTraceActive(TInt samplerIdToActivate);
+ TInt MarkTraceInactive(TInt samplerIdToDisable);
+ TInt OutputSettingsForTrace(TInt samplerId,TInt settings);
+ TInt AdditionalTraceSettings(TInt samplerId,TInt settings);
+ TInt AdditionalTraceSettings2(TInt samplerId,TInt settings);
+ TInt SetSamplingPeriod(TInt /*samplerId*/,TInt settings);
+private:
+ // create the driver in EKA-2 version
+ TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
+
+ // receive commands and control in EKA-2 version
+ void HandleMsg(TMessageBase* aMsg);
+private:
+ // timer mechanism in EKA-2 version
+ NTimer iTimer;
+ TDfc iNewDfc;
+ TInt iCount;
+ TInt iLastPcVal;
+ TInt iPeriod;
+
+ // sync sample number property for synchronizing other samplers
+ RPropertyRef iSampleStartTimeProp;
+ TInt iSampleStartTime;
+
+ DProfilerGppSampler<10000> gppSampler;
+#ifdef __SMP__
+ DProfilerGppSampler<10000> gppSampler2;
+ DProfilerGppSampler<10000> gppSampler3;
+ DProfilerGppSampler<10000> gppSampler4;
+#endif
+ DProfilerGfcSampler<10000> gfcSampler;
+ DProfilerIttSampler<10000> ittSampler;
+ DProfilerMemSampler<40000> memSampler;
+ DProfilerPriSampler<10000> priSampler;
+#ifdef __SMP__
+// DProfilerPriSampler<10000> priSampler2;
+// DProfilerPriSampler<10000> priSampler3;
+// DProfilerPriSampler<10000> priSampler4;
+#endif
+
+#ifndef __SMP__
+ static const TInt KSamplerAmount = 5;
+#else
+ static const TInt KSamplerAmount = 8;
+#endif
+ DProfilerSamplerBase* iSamplers[KSamplerAmount];
+ TInt iMaxCpus;
+ TUint32 iStartTime;
+
+#ifdef SEPARATE_DFC_QUEUE
+ TDynamicDfcQue* iDfcQ;
+#endif
+};
+
+/*
+ *
+ *
+ * Class DGeneralsProfilerFactory implementation
+ *
+ *
+ */
+
+DECLARE_STANDARD_LDD()
+ {
+ return new DGeneralsProfilerFactory();
+ }
+
+TInt DGeneralsProfilerFactory::Create(DLogicalChannelBase*& aChannel)
+ {
+ aChannel = new DGeneralsDriver;
+ return aChannel?KErrNone:KErrNoMemory;
+ }
+
+
+DGeneralsProfilerFactory::DGeneralsProfilerFactory()
+ {
+ // major, minor, and build version number
+ iVersion=TVersion(1,0,1);
+ }
+
+DGeneralsProfilerFactory::~DGeneralsProfilerFactory()
+ {
+// if (gDfcQ)
+// {
+// gDfcQ->Destroy();
+// }
+ }
+
+TInt DGeneralsProfilerFactory::Install()
+ {
+ return(SetName(&KPluginSamplerName));
+ }
+
+void DGeneralsProfilerFactory::GetCaps(TDes8& aDes) const
+ {
+ TCapsSamplerV01 b;
+
+ b.iVersion=TVersion(1,0,1);
+
+ aDes.FillZ(aDes.MaxLength());
+ aDes.Copy((TUint8*)&b,Min(aDes.MaxLength(),sizeof(b)));
+ }
+
+/*
+ *
+ *
+ * Class DGeneralsDriver implementation
+ *
+ *
+ */
+
+DGeneralsDriver::DGeneralsDriver() :
+ iTimer(NewDoProfilerProfile,this),
+ iNewDfc(NewDoDfc,this,NULL,7),
+#ifdef __SMP__
+ gppSampler(0),
+ gppSampler2(1),
+ gppSampler3(2),
+ gppSampler4(3),
+#endif
+ gfcSampler(gppSampler.GetExportData()),
+ ittSampler(gppSampler.GetExportData()),
+ memSampler(gppSampler.GetExportData(), PROFILER_MEM_SAMPLER_ID),
+ priSampler(gppSampler.GetExportData(), PROFILER_PRI_SAMPLER_ID)
+#ifdef __SMP__
+// ,priSampler2(gppSampler.GetExportData(), PROFILER_PRI_SAMPLER_ID),
+// priSampler3(gppSampler.GetExportData(), PROFILER_PRI_SAMPLER_ID),
+// priSampler4(gppSampler.GetExportData(), PROFILER_PRI_SAMPLER_ID)
+#endif
+ {
+ LOGSTRING("DGeneralsDriver::DGeneralsDriver()");
+
+ iState = EStopped;
+ iEndRequestStatus = 0;
+ doingDfc = 0;
+ sampleRunning = 0;
+ iSyncOffset = 0;
+ iStartTime = 0;
+ InitialiseSamplerList();
+ }
+
+/*
+ *
+ * This method has to be changed for each new sampler
+ *
+ */
+void DGeneralsDriver::InitialiseSamplerList()
+ {
+ // initialize all samplers to zero
+ for(TInt i(0);i<KSamplerAmount;i++)
+ {
+ iSamplers[i] = 0;
+ }
+
+ TInt i(0);
+ iSamplers[i] = &gppSampler;i++;
+#ifdef __SMP__
+ iSamplers[i] = &gppSampler2;i++;
+ iSamplers[i] = &gppSampler3;i++;
+ iSamplers[i] = &gppSampler4;i++;
+#endif
+ iSamplers[i] = &gfcSampler;i++;
+ iSamplers[i] = &ittSampler;i++;
+ iSamplers[i] = &memSampler;i++;
+ iSamplers[i] = &priSampler;i++;
+
+#ifdef __SMP__
+ // get the number of cpus
+ iMaxCpus = NKern::NumberOfCpus();
+#else
+ iMaxCpus = 0;
+#endif
+
+ // initialize synchronizing property
+ LOGSTRING("DGeneralsDriver::InitialiseSamplerList() - initializing property");
+ TInt r(iSampleStartTimeProp.Attach(KGppPropertyCat, EGppPropertySyncSampleNumber));
+ if (r!=KErrNone)
+ {
+ LOGSTRING2("DGeneralsDriver::InitialiseSamplerList() - error in attaching counter property, error %d", r);
+ }
+ LOGSTRING("DGeneralsDriver::InitialiseSamplerList() - defining properties");
+ r = iSampleStartTimeProp.Define(RProperty::EInt, KAllowAllPolicy, KDenyAllPolicy, 0, NULL);
+ if (r!=KErrNone)
+ {
+ LOGSTRING2("DGeneralsDriver::InitialiseSamplerList() - error in defining counter property, error %d", r);
+ }
+ }
+
+
+DProfilerSamplerBase* DGeneralsDriver::GetSamplerForId(TInt samplerIdToGet)
+ {
+ for(TInt i(0);i<KSamplerAmount;i++)
+ {
+ if(iSamplers[i]->iSamplerId == samplerIdToGet)
+ {
+ return iSamplers[i];
+ }
+ }
+ return (DProfilerSamplerBase*)0;
+ }
+
+TInt DGeneralsDriver::DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer)
+ {
+ TUint8 err(KErrNone);
+
+ if (!Kern::QueryVersionSupported(TVersion(1,0,1),aVer))
+ return KErrNotSupported;
+
+ // just for testing
+#ifndef __SMP__
+ LOGTEXT("Initializing the stack pointer");
+ stackTop=(TUint32*)IntStackPtr();
+ LOGSTRING2("Got stack pointer 0x%x",(TUint32)stackTop);
+#endif
+
+ iClient = &Kern::CurrentThread();
+ err = iClient->Open();
+
+ DProcess* clientProcess(iClient->iOwningProcess);
+ if (clientProcess)
+ {
+ //Require Power Management and All Files to use this driver
+ // Not ideal, but better than nothing
+ if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by GeneralsDriver.ldd")))
+ return KErrPermissionDenied;
+ if(!Kern::CurrentThreadHasCapability(ECapabilityAllFiles,__PLATSEC_DIAGNOSTIC_STRING("Checked by GeneralsDriver.ldd")))
+ return KErrPermissionDenied;
+
+ SSecurityInfo secureInfo = clientProcess->iS;
+ if (secureInfo.iSecureId != KProfilerExeSecurUid)
+ {
+ return KErrPermissionDenied;
+ }
+ }
+
+ // initiate sample stream ready for collecting the trace data
+ iSampleStream.InsertCurrentClient(iClient);
+
+ iTimer.Cancel();
+ iNewDfc.Cancel();
+
+ Kern::SetThreadPriority(24);
+
+#ifdef SEPARATE_DFC_QUEUE
+ err = Kern::DynamicDfcQCreate(iDfcQ, KGeneralsDriverThreadPriority, TBuf8<32>( KGeneralsDriverThread ));
+ if (KErrNone == err)
+ {
+ SetDfcQ(iDfcQ);
+ iNewDfc.SetDfcQ(iDfcQ);
+ iMsgQ.Receive();
+ return err;
+ }
+#else
+ SetDfcQ(Kern::DfcQue0());
+ iNewDfc.SetDfcQ(iDfcQ);
+ iMsgQ.Receive();
+#endif
+ return err;
+ }
+
+DGeneralsDriver::~DGeneralsDriver()
+ {
+ if (iState!=EStopped)
+ iTimer.Cancel();
+ iNewDfc.Cancel();
+
+#ifdef SEPARATE_DFC_QUEUE
+ if(iDfcQ)
+ iDfcQ->Destroy();
+#endif
+
+ iSampleStartTimeProp.Close();
+ Kern::SafeClose((DObject*&)iClient,NULL);
+ }
+
+
+TInt DGeneralsDriver::GetSampleTime(TUint32* time)
+ {
+ LOGSTRING("DGeneralsDriver::GetSampleTime - entry");
+
+ Kern::ThreadRawWrite( iClient,(TAny*)time,
+ (TAny*)&gppSampler.GetExportData()->sampleNumber,
+ 4, iClient);
+
+ LOGSTRING("DGeneralsDriver::GetSampleTime - exit");
+
+ return KErrNone;
+ }
+
+
+TInt DGeneralsDriver::GetSamplerVersion(TDes* aDes)
+ {
+ LOGSTRING2("DGeneralsDriver::GetSamplerVersion - 0x%x",aDes);
+
+ TBuf8<16> aBuf;
+ aBuf.Append(PROFILER_SAMPLER_VERSION);
+ Kern::ThreadDesWrite(iClient,aDes,aBuf,0,KChunkShiftBy0,iClient);
+ LOGSTRING("DGeneralsDriver::GetSamplerVersion - written client descriptor");
+ return KErrNone;
+ }
+
+TInt DGeneralsDriver::NewStart(TInt aDelay)
+ {
+ LOGSTRING("DGeneralsDriver::NewStart");
+ iEndRequestStatus = 0;
+
+ aDelay = Min(KMaxDelay, Max(KMinDelay, aDelay));
+
+ // always use this rate
+ iPeriod = aDelay;
+
+#ifdef __SMP__
+ /*
+ * Bind and enable the sampling interupts associated with each core.
+ */
+ TInt err(0);
+
+ TUint32 flags = NKern::EIrqBind_Count;
+
+// Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase - 32=%d", KIntProfilerBase -32 );
+ err = NKern::InterruptBind( KIntProfilerBase - 32 , DGeneralsDriver::Sample, this, flags, 0);
+ if(err < 0)
+ Kern::Printf(" InterruptBind KIntProfilerBase - 32 ret = %d", err );
+
+// Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase + 1 - 32=%d", KIntProfilerBase + 1-32 );
+ err = NKern::InterruptBind( KIntProfilerBase + 1 - 32 , DGeneralsDriver::Sample, this, flags, 0);
+ if(err < 0)
+ Kern::Printf(" InterruptBind KIntProfilerBase + 1 - 32 ret = %d", err );
+
+// Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase + 2 - 32=%d", KIntProfilerBase + 2 - 32 );
+ err = NKern::InterruptBind(KIntProfilerBase + 2 - 32 , DGeneralsDriver::Sample, this, flags, 0);
+ if(err < 0)
+ Kern::Printf(" InterruptBind KIntProfilerBase + 2 - 32 ret = %d", err );
+
+// Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase + 3 - 32=%d", KIntProfilerBase + 3 - 32 );
+ err = NKern::InterruptBind(KIntProfilerBase + 3 - 32 , DGeneralsDriver::Sample, this, flags, 0);
+ if(err < 0)
+ Kern::Printf(" InterruptBind KIntProfilerBase + 3 - 32 ret = %d", err );
+
+
+ err = NKern::InterruptEnable(KIntProfilerBase - 32);
+ if(err < 0)
+ Kern::Printf(" InterruptEnable KIntProfilerBase - 32 ret = %d", err );
+
+ err = NKern::InterruptEnable(KIntProfilerBase + 1 - 32);
+ if(err < 0)
+ Kern::Printf(" InterruptEnable KIntProfilerBase + 1 - 32 ret = %d", err );
+
+ err = NKern::InterruptEnable(KIntProfilerBase + 2 - 32);
+ if(err < 0)
+ Kern::Printf(" InterruptEnable KIntProfilerBase + 2 - 32 ret = %d", err );
+
+ err = NKern::InterruptEnable(KIntProfilerBase + 3 - 32);
+ if(err < 0)
+ Kern::Printf(" InterruptEnable KIntProfilerBase + 3 - 32 ret = %d", err );
+
+#endif
+
+ iTimer.OneShot(aDelay);
+
+ iState = ERunning;
+
+ return KErrNone;
+ }
+
+/*
+ * This function is run in each interrupt
+ */
+// EKA-2 implementation of the sampler method
+
+void DGeneralsDriver::NewDoProfilerProfile(TAny* aPtr)
+ {
+ LOGSTRING("DGeneralsDriver::NewDoProfilerProfile - entry");
+
+#ifdef __SMP__
+ TInt currCpu(NKern::CurrentCpu());
+#endif
+ TInt8 postSampleNeeded(0);
+ DGeneralsDriver& d=*(DGeneralsDriver*)aPtr;
+
+ if (d.iState == ERunning && d.sampleRunning == 0)
+ {
+ // start timer again
+ d.iTimer.Again(d.iPeriod);
+ d.sampleRunning++;
+
+#ifdef __SMP__
+ // print out the sample tick
+ if(d.gppSampler.GetExportData()->sampleNumber% 1000 == 0)
+ {
+ Kern::Printf(("PIPROF SAMPLE TICK, #%d"), d.gppSampler.GetExportData()->sampleNumber);
+ }
+ // call the actual CPU sampling function for CPU 0 (in NaviEngine), later may be on any of the CPUs
+ Sample(aPtr);
+
+ // post-sampling for NTimer interrupted CPU
+ postSampleNeeded += d.iSamplers[currCpu]->PostSampleNeeded();
+
+ /*
+ This is the master sampler from the watchdog timer, so
+ send interrupts to the other CPUs
+ */
+ TScheduler *theSched = TScheduler::Ptr();
+ GicDistributor* gicDist = (GicDistributor* )theSched->i_GicDistAddr;
+
+ for( TInt nCpu(0); nCpu < d.iMaxCpus; nCpu++ )
+ {
+ if( nCpu != currCpu )
+ {
+ gicDist->iSoftIrq = ( 0x10000 << nCpu ) | (KIntProfilerBase + nCpu);
+ }
+ // post-sampling for CPUs with specifically generated interrupts
+ postSampleNeeded += d.iSamplers[nCpu]->PostSampleNeeded();
+ }
+ arm_dsb();
+#endif
+ // then sample the rest of non-cpu samplers
+ for(TInt i(d.iMaxCpus);i<KSamplerAmount;i++)
+ {
+ if(d.iSamplers[i]->iEnabled)
+ {
+ d.iSamplers[i]->Sample();
+ postSampleNeeded += d.iSamplers[i]->PostSampleNeeded();
+ }
+ }
+
+ if(postSampleNeeded > 0 && d.doingDfc == 0)
+ {
+ d.doingDfc++;
+ d.iNewDfc.Add();
+
+ d.sampleRunning--;
+ return;
+ }
+ d.sampleRunning--;
+ }
+ else if (d.iState == EStopping && d.sampleRunning == 0)
+ {
+ // add a dfc for this final time
+ d.iNewDfc.Add();
+ Kern::Printf("DGeneralsDriver::Sample - sampling added to dfc queue");
+ }
+ else
+ {
+ // the previous sample has not finished,
+ Kern::Printf("DGeneralsDriver::NewDoProfilerProfile - Profiler Sampler Error - interrupted before finished sampling!!");
+ }
+ LOGSTRING("DGeneralsDriver::NewDoProfilerProfile - exit");
+ }
+
+
+
+void DGeneralsDriver::Sample(TAny* aPtr)
+ {
+ LOGSTRING("DGeneralsDriver::Sample - entry");
+
+#ifdef __SMP__
+ DGeneralsDriver& d=*(DGeneralsDriver*)aPtr;
+
+// TInt currCpu(NKern::CurrentCpu());
+
+ // sample the current cpu load
+// if(d.iSamplers[currCpu]->iEnabled)
+// {
+ d.iSamplers[NKern::CurrentCpu()]->Sample();
+// postSampleNeeded += d.iSamplers[currCpu]->PostSampleNeeded();
+// }
+#endif
+ LOGSTRING("DGeneralsDriver::Sample - exit");
+ }
+/*
+ * This function is run when any of the samplers
+ * requires post sampling
+ */
+void DGeneralsDriver::NewDoDfc(TAny* pointer)
+ {
+ DGeneralsDriver& d(*((DGeneralsDriver*)pointer));
+
+ if(d.iState == ERunning)
+ {
+ // for all enabled samplers, perform
+ // post sample if needed
+ for(TInt i(0);i<KSamplerAmount;i++)
+ {
+ if(d.iSamplers[i]->iEnabled)
+ {
+ if(d.iSamplers[i]->PostSampleNeeded())
+ {
+ d.iSamplers[i]->PostSample();
+ }
+ }
+ }
+ d.doingDfc--;
+ }
+
+ else if(d.iState == EStopping)
+ {
+ // for all enabled samplers,
+ // perform end sampling
+ TBool releaseBuffer(false);
+ for(TInt i(0);i<KSamplerAmount;i++)
+ {
+ if(d.iSamplers[i]->iEnabled)
+ {
+ LOGSTRING("DGeneralsDriver::NewDoDfc() - ending");
+ // perform end sampling for all samplers
+ // stream mode samplers may be pending, if they
+ // are still waiting for another client buffer
+ if(d.iSamplers[i]->EndSampling() == KErrNotReady)
+ {
+ LOGSTRING("DGeneralsDriver::NewDoDfc() - stream data pending");
+ releaseBuffer = true;
+ }
+ else
+ {
+ LOGSTRING("DGeneralsDriver::NewDoDfc() - no data pending");
+ releaseBuffer = true;
+ }
+ }
+ }
+
+ // At the end, once all the samplers are gone through, the buffer should be released
+ if (true == releaseBuffer)
+ {
+ LOGSTRING("DGeneralsDriver::NewDoDfc() - release the buffer");
+ d.iSampleStream.ReleaseIfPending();
+ }
+
+ d.iState = EStopped;
+ if(d.iEndRequestStatus != 0 && d.iClient != 0)
+ {
+ // sampling has ended
+ Kern::RequestComplete(d.iClient,d.iEndRequestStatus,KErrNone);
+ }
+ }
+ }
+
+
+/*
+ * All controls are handled here
+ */
+
+void DGeneralsDriver::HandleMsg(TMessageBase* aMsg)
+ {
+ TInt r(KErrNone);
+ TThreadMessage& m(*(TThreadMessage*)aMsg);
+
+ LOGSTRING5("DGeneralsDriver::HandleMsg 0x%x 0x%x 0x%x 0x%x",m.Int0(),m.Int1(),m.Int2(),m.Int3());
+
+ if(m.iValue == (TInt)ECloseMsg)
+ {
+ LOGSTRING("DGeneralsDriver::HandleMsg - received close message");
+ iTimer.Cancel();
+ iNewDfc.Cancel();
+
+ m.Complete(KErrNone,EFalse);
+ iMsgQ.CompleteAll(KErrServerTerminated);
+ LOGSTRING("DGeneralsDriver::HandleMsg - cleaned up the driver!");
+ return;
+ }
+
+ if (m.Client()!=iClient)
+ {
+ LOGSTRING("DGeneralsDriver::HandleMsg - ERROR, wrong client");
+ m.PanicClient(_L("GENERALSSAMPLER"),EAccessDenied);
+ return;
+ }
+
+ TInt id(m.iValue);
+ switch(id)
+ {
+ //Controls are handled here
+ case RPluginSampler::EMarkTraceActive:
+ LOGSTRING("DGeneralsDriver::HandleMsg - EMarkTraceActive");
+ r = MarkTraceActive((TInt)m.Int0());
+ break;
+
+ case RPluginSampler::EOutputSettingsForTrace:
+ LOGSTRING("DGeneralsDriver::HandleMsg - EOutputSettingsForTrace");
+ r = OutputSettingsForTrace((TInt)m.Int0(),(TInt)m.Int1());
+ break;
+
+ case RPluginSampler::EAdditionalTraceSettings:
+ LOGSTRING("DGeneralsDriver::HandleMsg - EAdditionalTraceSettings");
+ r = AdditionalTraceSettings((TInt)m.Int0(),(TInt)m.Int1());
+ break;
+
+ case RPluginSampler::EAdditionalTraceSettings2:
+ LOGSTRING("DGeneralsDriver::HandleMsg - EAdditionalTraceSettings2");
+ r = AdditionalTraceSettings2((TInt)m.Int0(),(TInt)m.Int1());
+ break;
+
+ case RPluginSampler::ESetSamplingPeriod:
+ LOGSTRING2("DGeneralsDriver::HandleMsg - ESetSamplingPeriod %d", (TInt)m.Int1());
+ r = SetSamplingPeriod((TInt)m.Int0(),(TInt)m.Int1());
+ break;
+
+ case RPluginSampler::EMarkTraceInactive:
+ LOGSTRING("DGeneralsDriver::HandleMsg - EMarkTraceInactive");
+ r = MarkTraceInactive((TInt)m.Int0());
+ break;
+
+ case RPluginSampler::ESample:
+ LOGSTRING("DGeneralsDriver::HandleMsg - ESample");
+ //r = Sample(); // hack. Original implementation of sample just returned 0
+ r = 0;
+ break;
+
+ case RPluginSampler::EStartSampling:
+ LOGSTRING("DGeneralsDriver::HandleMsg - EStartSampling");
+ r = StartSampling();
+ break;
+
+ case RPluginSampler::EGetSampleTime:
+ LOGSTRING("DGeneralsDriver::HandleMsg - EGetSampleTime");
+ r = GetSampleTime(reinterpret_cast<TUint32*>(m.Ptr0()));
+ break;
+
+ case RPluginSampler::EGetSamplerVersion:
+ LOGSTRING("DGeneralsDriver::HandleMsg - EGetSamplerVersion");
+ r = GetSamplerVersion(reinterpret_cast<TDes*>(m.Ptr0()));
+ break;
+
+ case RPluginSampler::ECancelStreamRead:
+ LOGSTRING("DGeneralsDriver::HandleMsg - ECancelStreamRead");
+ iStreamReadCancelStatus = reinterpret_cast<TRequestStatus*>(m.Ptr0());
+ r = ProcessStreamReadCancel();
+ break;
+
+
+ // Requests are handled here
+
+ case ~RPluginSampler::EStopAndWaitForEnd:
+ LOGSTRING("DGeneralsDriver::HandleMsg - EStopAndWaitForEnd");
+ iEndRequestStatus = reinterpret_cast<TRequestStatus*>(m.Ptr0());
+ r = StopSampling();
+#ifdef __SMP__
+ UnbindInterrupts();
+#endif
+ break;
+
+ case ~RPluginSampler::ERequestFillThisStreamBuffer:
+ LOGSTRING("DGeneralsDriver::HandleMsg - ERequestFillThisStreamBuffer");
+ r = ProcessStreamReadRequest( reinterpret_cast<TBapBuf*>(m.Ptr1()),
+ reinterpret_cast<TRequestStatus*>(m.Ptr0()));
+ break;
+
+ default:
+ LOGSTRING2("DGeneralsDriver::HandleMsg - ERROR, unknown command %d",id);
+ r = KErrNotSupported;
+ break;
+ }
+
+ LOGSTRING("DGeneralsDriver::HandleMsg - Completed");
+ m.Complete(r,ETrue);
+ }
+
+#ifdef __SMP__
+inline void DGeneralsDriver::UnbindInterrupts()
+ {
+ TInt err(0);
+
+ // disable interrupts when sampling stops, enabled again on start
+ err = NKern::InterruptDisable(KIntProfilerBase - 32);
+ if(err < 0)
+ Kern::Printf(" InterruptDisable KIntProfilerBase - 32 ret = %d", err );
+
+ err = NKern::InterruptDisable(KIntProfilerBase + 1 - 32);
+ if(err < 0)
+ Kern::Printf(" InterruptDisable KIntProfilerBase + 1 - 32 ret = %d", err );
+
+ err = NKern::InterruptDisable(KIntProfilerBase + 2 - 32);
+ if(err < 0)
+ Kern::Printf(" InterruptDisable KIntProfilerBase + 2 - 32 ret = %d", err );
+
+ err = NKern::InterruptDisable(KIntProfilerBase + 3 - 32);
+ if(err < 0)
+ Kern::Printf(" InterruptDisable KIntProfilerBase + 3 - 32 ret = %d", err );
+
+// Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase - 32=%d", KIntProfilerBase -32 );
+ err = NKern::InterruptUnbind( KIntProfilerBase - 32);
+ if(err < 0)
+ Kern::Printf(" InterruptUnbind KIntProfilerBase - 32 ret = %d", err );
+
+// Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase + 1 - 32=%d", KIntProfilerBase + 1-32 );
+ err = NKern::InterruptUnbind( KIntProfilerBase + 1 - 32);
+ if(err < 0)
+ Kern::Printf(" InterruptUnbind KIntProfilerBase + 1 - 32 ret = %d", err );
+
+// Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase + 2 - 32=%d", KIntProfilerBase + 2 - 32 );
+ err = NKern::InterruptUnbind(KIntProfilerBase + 2 - 32);
+ if(err < 0)
+ Kern::Printf(" InterruptUnbind KIntProfilerBase + 2 - 32 ret = %d", err );
+
+// Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase + 3 - 32=%d", KIntProfilerBase + 3 - 32 );
+ err = NKern::InterruptUnbind(KIntProfilerBase + 3 - 32);
+ if(err < 0)
+ Kern::Printf(" InterruptUnbind KIntProfilerBase + 3 - 32 ret = %d", err );
+
+ }
+#endif
+
+inline TInt DGeneralsDriver::ProcessStreamReadRequest(TBapBuf* aBuf,TRequestStatus* aStatus)
+ {
+ LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest - entry");
+
+ // a new sample buffer has been received from the client
+ iSampleStream.AddSampleBuffer(aBuf,aStatus);
+
+ // check if we are waiting for the last data to be written to the client
+ if(iState == EStopped)
+ {
+ LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest state = EStopped");
+
+ // sampling has stopped and stream read cancel is pending
+ // try to perform the end sampling procedure again
+ TBool releaseBuffer(false);
+ for(TInt i(0);i<KSamplerAmount;i++)
+ {
+ // only for all enabled samplers that have stream output mode
+ if(iSamplers[i]->iEnabled /*&& samplers[i]->outputMode == 2*/)
+ {
+ //TInt pending = 0;
+ // stream mode samplers may be pending, if they
+ // are still waiting for another client buffer,
+ // in that case, the request should be completed already
+ if(iSamplers[i]->EndSampling() == KErrNotReady)
+ {
+ LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest - still data pending");
+ releaseBuffer = true;
+ }
+ else
+ {
+ LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest - no data pending");
+ releaseBuffer = true;
+ }
+ }
+ }
+ // At the end, once all the samplers are gone through, the buffer should be released
+ if (true == releaseBuffer)
+ {
+ LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest - all data copied, release the buffer");
+ iSampleStream.ReleaseIfPending();
+ }
+ }
+ LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest - exit");
+
+ return KErrNone;
+ }
+
+
+/*
+ * Mark traces active or inactive, this can be done
+ * only if sampling is not running
+ */
+
+inline TInt DGeneralsDriver::MarkTraceActive(TInt samplerIdToActivate)
+ {
+ LOGSTRING2("DGeneralsDriver::MarkTraceActive %d",samplerIdToActivate);
+
+ TInt cpus(0);
+#ifdef __SMP__
+ cpus = NKern::NumberOfCpus();
+ if( samplerIdToActivate == PROFILER_GPP_SAMPLER_ID )
+ {
+ for(TInt cpu(0);cpu<cpus;cpu++)
+ {
+ Kern::Printf("DGeneralsDriver::MarkTraceActive - activating CPU %d",cpu);
+ iSamplers[cpu]->SetEnabledFlag(true);
+ }
+ return KErrNone;
+ }
+#endif
+ for(TInt i(cpus);i<KSamplerAmount;i++)
+ {
+ if(iSamplers[i]->iSamplerId == samplerIdToActivate)
+ {
+ iSamplers[i]->SetEnabledFlag(true);
+ return KErrNone;
+ }
+ }
+
+ LOGSTRING2("DGeneralsDriver::MarkTraceActive - %d not supported",samplerIdToActivate);
+ return KErrNotSupported;
+ }
+
+inline TInt DGeneralsDriver::MarkTraceInactive(TInt samplerIdToDisable)
+ {
+ LOGSTRING2("DGeneralsDriver::MarkTraceInactive %d",samplerIdToDisable);
+
+ TInt cpus(0);
+#ifdef __SMP__
+ cpus = NKern::NumberOfCpus();
+ if( samplerIdToDisable == PROFILER_GPP_SAMPLER_ID )
+ {
+ for(TInt cpu(0);cpu<cpus;cpu++)
+ {
+ iSamplers[cpu]->SetEnabledFlag(false);
+ }
+ return KErrNone;
+ }
+#endif
+ for(TInt i(cpus);i<KSamplerAmount;i++)
+ {
+ if(iSamplers[i]->iSamplerId == samplerIdToDisable)
+ {
+ iSamplers[i]->SetEnabledFlag(false);
+ return KErrNone;
+ }
+ }
+
+ LOGSTRING2("DGeneralsDriver::MarkTraceInactive - %d not supported",samplerIdToDisable);
+ return KErrNotSupported;
+ }
+
+/*
+ * Set output settings for a trace
+ */
+
+inline TInt DGeneralsDriver::OutputSettingsForTrace(TInt samplerId,TInt settings)
+ {
+ LOGSTRING3("DGeneralsDriver::OutputSettingsForTrace id:%d set:%d",samplerId,settings);
+
+ TInt cpus(0);
+#ifdef __SMP__
+ cpus = NKern::NumberOfCpus();
+ if( samplerId == PROFILER_GPP_SAMPLER_ID )
+ {
+ for(TInt cpu(0);cpu<cpus;cpu++)
+ {
+ iSamplers[cpu]->SetOutputCombination(settings);
+ }
+ return KErrNone;
+ }
+#endif
+ for(TInt i(cpus);i<KSamplerAmount;i++)
+ {
+ if(iSamplers[i]->iSamplerId == samplerId)
+ {
+ iSamplers[i]->SetOutputCombination(settings);
+ return KErrNone;
+ }
+ }
+
+ return KErrNotSupported;
+ }
+
+/*
+ * Set additional settings for a trace
+ */
+
+inline TInt DGeneralsDriver::AdditionalTraceSettings(TInt samplerId,TInt settings)
+ {
+ LOGSTRING3("DGeneralsDriver::SetAdditionalTraceSettings id:%d set:%d",samplerId,settings);
+
+ TInt cpus(0);
+#ifdef __SMP__
+ cpus = NKern::NumberOfCpus();
+ if( samplerId == PROFILER_GPP_SAMPLER_ID )
+ {
+ for(TInt cpu(0);cpu<cpus;cpu++)
+ {
+ iSamplers[cpu]->SetAdditionalSettings(settings);
+ }
+ return KErrNone;
+ }
+#endif
+ for(TInt i(cpus);i<KSamplerAmount;i++)
+ {
+ if(iSamplers[i]->iSamplerId == samplerId)
+ {
+ iSamplers[i]->SetAdditionalSettings(settings);
+ return KErrNone;
+ }
+ }
+
+ return KErrNotSupported;
+ }
+
+inline TInt DGeneralsDriver::AdditionalTraceSettings2(TInt samplerId,TInt settings)
+ {
+ LOGSTRING3("DGeneralsDriver::SetAdditionalTraceSettings id:%d set:%d",samplerId,settings);
+
+ TInt cpus(0);
+#ifdef __SMP__
+ cpus = NKern::NumberOfCpus();
+ if( samplerId == PROFILER_GPP_SAMPLER_ID )
+ {
+ for(TInt cpu(0);cpu<cpus;cpu++)
+ {
+ iSamplers[cpu]->SetAdditionalSettings2(settings);
+ }
+ return KErrNone;
+ }
+#endif
+ for(TInt i(cpus);i<KSamplerAmount;i++)
+ {
+ if(iSamplers[i]->iSamplerId == samplerId)
+ {
+ iSamplers[i]->SetAdditionalSettings2(settings);
+ return KErrNone;
+ }
+ }
+
+ return KErrNotSupported;
+ }
+
+inline TInt DGeneralsDriver::SetSamplingPeriod(TInt samplerId,TInt settings)
+ {
+ LOGSTRING2("DGeneralsDriver::SetSamplingPeriod - set:%d",settings);
+
+ TInt cpus(0);
+#ifdef __SMP__
+ cpus = NKern::NumberOfCpus();
+ if( samplerId == PROFILER_GPP_SAMPLER_ID )
+ {
+ for(TInt cpu(0);cpu<cpus;cpu++)
+ {
+ iSamplers[cpu]->SetSamplingPeriod(settings);
+ }
+ return KErrNone;
+ }
+#endif
+ for(TInt i(cpus);i<KSamplerAmount;i++)
+ {
+ if(iSamplers[i]->iSamplerId == samplerId)
+ {
+ iSamplers[i]->SetSamplingPeriod(settings);
+ return KErrNone;
+ }
+ }
+
+ return KErrNotSupported;
+ }
+
+/*
+ * Mark traces active or inactive, this can be done
+ * only if sampling is not running
+ */
+
+TInt DGeneralsDriver::StartSampling()
+ {
+ LOGSTRING("DGeneralsDriver::StartSampling");
+
+ if(iState == EStopped)
+ {
+ // reset iSampleStartTimeProp property value
+ iSampleStartTime = NKern::TickCount(); // get the system tick value for sync purposes
+#ifdef __SMP__
+ iStartTime = (iSampleStartTime & 0xfffffff0);
+#endif
+ TInt r(iSampleStartTimeProp.Set(iSampleStartTime));
+
+ Kern::Printf(("PIPROF SAMPLE TICK, #0")); // for remote profiling with Profiler Activator
+
+ // reset all enabled samplers
+ for(TInt i(0);i<KSamplerAmount;i++)
+ {
+ if(iSamplers[i]->iEnabled)
+ {
+ // reset with stream option
+#ifndef __SMP__
+ Kern::Printf(("DGeneralsDriver::StartSampling - stream reset for generals driver, sync offset %d"), 0);
+ iSamplers[i]->Reset(&iSampleStream, 0);
+#else
+ Kern::Printf(("DGeneralsDriver::StartSampling - stream reset for generals driver, start time %d"), iStartTime);
+ iSamplers[i]->Reset(&iSampleStream, iStartTime);
+#endif
+ }
+ }
+
+ NewStart(gppSampler.GetPeriod());
+ return KErrNone;
+ }
+ else
+ {
+ return KErrGeneral;
+ }
+ }
+
+/*
+ * Mark traces active or inactive, this can be done
+ * only if sampling is not running
+ */
+
+TInt DGeneralsDriver::StopSampling()
+ {
+ LOGSTRING("DGeneralsDriver::StopSampling");
+
+ if(iState == ERunning)
+ {
+ this->iState = EStopping;
+ // reset all enabled samplers
+ for(TInt i(0);i<KSamplerAmount;i++)
+ {
+ // do the reset only for memory sampler
+ if(iSamplers[i]->iEnabled && iSamplers[i]->iSamplerId == 4)
+ {
+ // reset with stream option
+ LOGTEXT(("DGeneralsDriver::StopSampling - stream reset for samplers"));
+ iSamplers[i]->Reset(&iSampleStream, 999999);
+ }
+ }
+
+ return KErrNone;
+ }
+ else
+ {
+ return KErrGeneral;
+ }
+ }
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/src/GeneralsPlugin.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,577 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include "GeneralsPlugin.h"
+//#include <piprofiler/EngineUIDs.h>
+#include <piprofiler/ProfilerTraces.h>
+
+const TInt KMaxSamplerAmount = 20;
+
+// LITERALS
+_LIT8(KSamplingPeriod, "sampling_period_ms");
+
+// CONSTANTS
+// GeneralsPlugin UID:
+const TUid KSamplerGeneralsPluginUid = { 0x2001E5B2 };
+
+// Gpp sub-sampler UID:
+const TUid KSamplerGppPluginUid = { 0x2001E570 };
+
+// Gfc sub-sampler UID:
+const TUid KSamplerGfcPluginUid = { 0x2001E571 };
+
+// Itt sub-sampler UID:
+const TUid KSamplerIttPluginUid = { 0x2001E572 };
+
+// Mem sub-sampler UID:
+const TUid KSamplerMemPluginUid = { 0x2001E573 };
+
+// Pri sub-sampler UID:
+const TUid KSamplerPriPluginUid = { 0x2001E574 };
+
+/*
+ *
+ * class CGeneralsPlugin implementation
+ *
+ */
+
+CGeneralsPlugin* CGeneralsPlugin::NewL(const TUid aImplementationUid, TAny* /*aInitParams*/)
+ {
+ LOGTEXT(_L("CGeneralsPlugin::NewL() - entry"));
+ CGeneralsPlugin* self = new (ELeave) CGeneralsPlugin();
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+ LOGTEXT(_L("CGeneralsPlugin::NewL() - exit"));
+ return self;
+ }
+
+CGeneralsPlugin::CGeneralsPlugin() :
+ iVersionDescriptor(&(this->iVersion[1]),0,19)
+ {
+ iSamplerType = PROFILER_KERNEL_MODE_SAMPLER;
+ iSamplerId = PROFILER_GENERALS_SAMPLER_ID;
+ iBufferHandler = NULL;
+ iEnabled = EFalse;
+ LOGTEXT(_L("CGeneralsPlugin::CGeneralsPlugin() - constructor"));
+ }
+
+void CGeneralsPlugin::ConstructL()
+ {
+ LOGTEXT(_L("CGeneralsPlugin::ConstructL() - entry"));
+
+ // create attribute array
+ iSamplerAttributes = new(ELeave) CArrayFixFlat<TSamplerAttributes>(KSubSamplerCount);
+
+ TInt err = InitiateSamplerL();
+ if( err != KErrNone )
+ {
+ LOGTEXT(_L("CGeneralsPlugin::ConstructL - LEAVING, failed to load open sampler device"));
+ User::Leave(err);
+ }
+
+ // initiate sampler attributes, i.e. settings for modification
+ InitiateSamplerAttributesL();
+
+ LOGTEXT(_L("CGeneralsPlugin::ConstructL() - exit"));
+ }
+
+
+CGeneralsPlugin::~CGeneralsPlugin()
+ {
+ // clean all the members
+ CleanSampler(); // clean the created sampler
+ }
+
+TInt CGeneralsPlugin::InitiateSamplerL()
+ {
+ RThread me;
+
+ LOGTEXT(_L("CGeneralsPlugin::InitiateSamplerL - #1"));
+
+ me.SetPriority(EPriorityRealTime);
+
+ LOGTEXT(_L("CGeneralsPlugin::InitiateSamplerL - #2"));
+
+ // create
+ User::FreeLogicalDevice(KPluginSamplerName);
+ TInt err(KErrGeneral);
+
+ LOGTEXT(_L("CGeneralsPlugin::InitiateSamplerL - #3"));
+
+ err = User::LoadLogicalDevice(KPluginSamplerName);
+ if(err != KErrNone)
+ {
+ User::Leave(err);
+ }
+
+ LOGTEXT(_L("CGeneralsPlugin::InitiateSamplerL - #4"));
+
+ err = KErrGeneral;
+
+ err = iGeneralsSampler.Open();
+ if(err != KErrNone)
+ {
+ LOGSTRING2("CGeneralsPlugin::InitiateSamplerL - Could not open sampler device - waiting and trying again: %d", err);
+ User::Leave(err);
+ }
+
+ LOGTEXT(_L("CGeneralsPlugin::InitiateSamplerL - #5"));
+
+ return err;
+ }
+
+/*
+ *
+ * Default sampler attributes
+ *
+ */
+void CGeneralsPlugin::InitiateSamplerAttributesL()
+ {
+
+ //
+ for(TInt i(0);i<KMaxSamplerAmount;i++)
+ {
+ switch(i)
+ {
+// Usage:
+// TSamplerAttributes(TUint32 aUid,
+// const TDesC8& aShortName,
+// const TDesC& aName,
+// const TDesC& aDescription,
+// TInt aSampleRate,
+// TBool aEnabled,
+// TBool aHidden,
+// TUint32 aItemCount);
+ case PROFILER_GPP_SAMPLER_ID:
+ {
+ TSamplerAttributes attr(KSamplerGppPluginUid.iUid,
+ KGPPShortName(),
+ KGPPLongName(),
+ KGPPDescription(),
+ 1,
+ ETrue,
+ ETrue,
+ 0);
+ iSamplerAttributes->AppendL(attr);
+ break;
+ }
+ case PROFILER_GFC_SAMPLER_ID:
+ {
+ TSamplerAttributes attr2(KSamplerGfcPluginUid.iUid,
+ KGFCShortName(),
+ KGFCLongName(),
+ KGFCDescription(),
+ -1,
+ EFalse,
+ EFalse,
+ 0);
+ this->iSamplerAttributes->AppendL(attr2);
+ break;
+ }
+ case PROFILER_ITT_SAMPLER_ID:
+ {
+ TSamplerAttributes attr3(KSamplerIttPluginUid.iUid,
+ KITTShortName(),
+ KITTLongName(),
+ KITTDescription(),
+ -1,
+ ETrue,
+ EFalse,
+ 0);
+ this->iSamplerAttributes->AppendL(attr3);
+ break;
+ }
+ case PROFILER_MEM_SAMPLER_ID:
+ {
+ TSamplerAttributes attr4(KSamplerMemPluginUid.iUid,
+ KMEMShortName(),
+ KMEMLongName(),
+ KMEMDescription(),
+ -1,
+ EFalse,
+ EFalse,
+ 0);
+// // select event or sampling based
+// attr4.iSettingItem1.iSettingDescription.Copy(KMEM1Desc);
+// attr4.iSettingItem1.iType = TSettingItem::ESettingItemTypeBool;
+// attr4.iSettingItem1.iValue.AppendNum(0, EDecimal);
+// attr4.iSettingItem1.iUIText.Copy(KMEM1UIText);
+// attr4.iSettingItem1.iSettingText.Copy(KMemCounter1);
+
+ this->iSamplerAttributes->AppendL(attr4);
+ break;
+ }
+ case PROFILER_PRI_SAMPLER_ID:
+ {
+ TSamplerAttributes attr5(KSamplerPriPluginUid.iUid,
+ KPRIShortName(),
+ KPRILongName(),
+ KPRIDescription(),
+ 3000,
+ EFalse,
+ EFalse,
+ 0);
+ this->iSamplerAttributes->AppendL(attr5);
+ break;
+ }
+ }
+ }
+ }
+
+TInt CGeneralsPlugin::CleanSampler()
+ {
+ LOGTEXT(_L("CGeneralsPlugin::CleanSampler() - deleting buffer handler"));
+ // release the buffer handler
+ if(iBufferHandler)
+ {
+ iBufferHandler->Cancel();
+ delete iBufferHandler;
+ iBufferHandler = NULL;
+ }
+
+ LOGTEXT(_L("CGeneralsPlugin::CleanSampler() - closing sampler"));
+ iGeneralsSampler.Close();
+
+ LOGTEXT(_L("CGeneralsPlugin::CleanSampler() - Freeing sampler device"));
+ User::FreeLogicalDevice(KPluginSamplerName);
+
+ // release attribute array
+ if(iSamplerAttributes)
+ {
+ iSamplerAttributes->Reset();
+ }
+ delete iSamplerAttributes;
+ iSamplerAttributes = NULL;
+
+ LOGTEXT(_L("CGeneralsPlugin::CleanSampler() - exit"));
+
+ return KErrNone;
+ }
+
+// returns setting array
+void CGeneralsPlugin::GetAttributesL(CArrayFixFlat<TSamplerAttributes>* aAttributes)
+ {
+ TInt count(iSamplerAttributes->Count());
+ // append all sampler attributes to aAttributes array
+ for(TInt i(0);i<count;i++)
+ {
+ aAttributes->AppendL(iSamplerAttributes->At(i));
+ }
+ }
+
+TInt CGeneralsPlugin::SetAttributesL(TSamplerAttributes aAttributes)
+ {
+ TSamplerAttributes attr;
+
+ TInt count(iSamplerAttributes->Count());
+ // loop the sub sampler attributes (by UID)
+ for(TInt i(0);i<count;i++)
+ {
+ attr = iSamplerAttributes->At(i);
+ // if UIDs match replace the old
+ if(attr.iUid == aAttributes.iUid)
+ {
+ // replace the old attribute container
+ iSamplerAttributes->Delete(i);
+ iSamplerAttributes->InsertL(i, aAttributes);
+ return KErrNone;
+ }
+ }
+ return KErrNotFound;
+ }
+
+/*
+ * Method for parsing and transforming text array settings into TSamplerAttributes (per each sub sampler),
+ * called by CSamplerController class
+ *
+ * @param array of raw text setting lines, e.g. [gpp]\nenabled=true\nsampling_period_ms=1\n
+ */
+TInt CGeneralsPlugin::ConvertRawSettingsToAttributes(CDesC8ArrayFlat* aAllSettingsArray)
+ {
+ // local literals
+ _LIT8(KGPPShort, "gpp");
+ _LIT8(KGFCShort, "gfc");
+ _LIT8(KITTShort, "itt");
+ _LIT8(KMEMShort, "mem");
+ _LIT8(KPRIShort, "pri");
+
+ TInt err(KErrNone);
+
+ TBuf8<16> samplerSearchName;
+
+ // loop previous settings, update value if changed
+ for(TInt i(0);i<KSubSamplerCount;i++)
+ {
+ // go through all the sub samplers
+ switch (i)
+ {
+ case 0:
+ samplerSearchName.Copy(KGPPShort);
+ break;
+ case 1:
+ samplerSearchName.Copy(KGFCShort);
+ break;
+ case 2:
+ samplerSearchName.Copy(KITTShort);
+ break;
+ case 3:
+ samplerSearchName.Copy(KMEMShort);
+ break;
+ case 4:
+ samplerSearchName.Copy(KPRIShort);
+ break;
+ }
+
+ // get sampler specific settings
+ err = DoSetSamplerSettings(aAllSettingsArray, samplerSearchName, i);
+ }
+
+ // returns KErrNone if settings found, otherwise KErrNotFound
+ return err;
+ }
+
+/**
+ * Method for searching sampler specific settings among all settings (raw setting lines read from settings file)
+ *
+ * @param aAllSettings array of all settings from settings file
+ * @param aSamplerName short name of sampler to be searched among the settings
+ * @param aIndex index number of sampler specific sampler attributes (TSamplerAttributes)
+ * @return KErrNone if settings found ok else KErrNotFound
+ */
+TInt CGeneralsPlugin::DoSetSamplerSettings(CDesC8ArrayFlat* aAllSettings, TDesC8& aSamplerName, TInt aIndex)
+ {
+ // sampler name to be searched among the all settings
+ TBuf8<16> samplerSearch;
+ samplerSearch.Copy(KBracketOpen);
+ samplerSearch.Append(aSamplerName);
+ samplerSearch.Append(KBracketClose);
+
+ // read a line from ALL settings array
+ for (TInt i(0); i<aAllSettings->MdcaCount(); i++)
+ {
+ // check if this line has a setting block start, i.e. contains [xxx] in it
+ if (aAllSettings->MdcaPoint(i).CompareF(samplerSearch) == 0)
+ {
+ // right settings block found, now loop until the next block is found
+ for(TInt j(i+1);j<aAllSettings->MdcaCount();j++)
+ {
+ // check if the next settings block was found
+ if(aAllSettings->MdcaPoint(j).Left(1).CompareF(KBracketOpen) != 0)
+ {
+ // save found setting value directly to its owners attributes
+ SaveSettingToAttributes(aAllSettings->MdcaPoint(j), aIndex);
+ }
+ else
+ {
+ // next block found, return KErrNone
+ return KErrNone;
+ }
+ }
+ }
+ }
+ // no settings found for specific sampler
+ return KErrNotFound;
+ }
+
+/**
+ * Method for setting a specific descriptor (from settings file) to attribute structure
+ *
+ * @param aSetting
+ * @param aName
+ */
+void CGeneralsPlugin::SaveSettingToAttributes(const TDesC8& aSetting, TInt aIndex)
+ {
+ // local literals
+ _LIT8(KSettingItemSeparator, "=");
+
+ // find the equal mark from the setting line
+ TInt sepPos = aSetting.Find(KSettingItemSeparator);
+ // check that '=' is found
+ if (sepPos > 0)
+ {
+ // check that the element matches
+ if (aSetting.Left(sepPos).CompareF(KEnabled) == 0)
+ {
+ TBool en;
+ CSamplerPluginInterface::Str2Bool(aSetting.Right(aSetting.Length()-sepPos-1), en);
+ if(en != iSamplerAttributes->At(aIndex).iEnabled)
+ {
+ iSamplerAttributes->At(aIndex).iEnabled = en;
+ }
+ }
+ else if (aSetting.Left(sepPos).CompareF(KSamplingPeriod) == 0)
+ {
+ TInt sr;
+ CSamplerPluginInterface::Str2Int(aSetting.Right(aSetting.Length()-sepPos-1), sr);
+ if(sr != iSamplerAttributes->At(aIndex).iSampleRate)
+ {
+ iSamplerAttributes->At(aIndex).iSampleRate = sr;
+ }
+ }
+ }
+ }
+
+
+TUid CGeneralsPlugin::Id(TInt aSubId) const
+ {
+ if(aSubId == PROFILER_GPP_SAMPLER_ID)
+ return KSamplerGppPluginUid;
+ else if (aSubId == PROFILER_GFC_SAMPLER_ID)
+ return KSamplerGfcPluginUid;
+ else if (aSubId == PROFILER_ITT_SAMPLER_ID)
+ return KSamplerIttPluginUid;
+ else if (aSubId == PROFILER_MEM_SAMPLER_ID)
+ return KSamplerMemPluginUid;
+ else if (aSubId == PROFILER_PRI_SAMPLER_ID)
+ return KSamplerPriPluginUid;
+ else
+ return KSamplerGeneralsPluginUid;
+ }
+
+TInt CGeneralsPlugin::SubId(TUid aId) const
+ {
+/* definitions from ProfilerConfig.h:
+ * #define PROFILER_GPP_SAMPLER_ID 1
+ #define PROFILER_GFC_SAMPLER_ID 2
+ #define PROFILER_ITT_SAMPLER_ID 3
+ #define PROFILER_MEM_SAMPLER_ID 4
+ #define PROFILER_PRI_SAMPLER_ID 5
+ */
+
+ if(aId == KSamplerGppPluginUid)
+ return PROFILER_GPP_SAMPLER_ID;
+ else if (aId == KSamplerGfcPluginUid)
+ return PROFILER_GFC_SAMPLER_ID;
+ else if (aId == KSamplerIttPluginUid)
+ return PROFILER_ITT_SAMPLER_ID;
+ else if (aId == KSamplerMemPluginUid)
+ return PROFILER_MEM_SAMPLER_ID;
+ else if (aId == KSamplerPriPluginUid)
+ return PROFILER_PRI_SAMPLER_ID;
+ else
+ return KErrNotFound;
+ }
+
+TInt CGeneralsPlugin::GetSamplerType()
+ {
+ return iSamplerType;
+ }
+
+
+void CGeneralsPlugin::InstallStreamForActiveTraces(RGeneralsSampler& sampler, CProfilerSampleStream& aStream)
+ {
+ // output mode for this trace is stream
+ if(!iBufferHandler)
+ {
+ // stream object has not been created yet
+ LOGTEXT(_L("CGeneralsPlugin::InstallStreamForActiveTraces - creating stream for trace"));
+
+ // use a 32KB buffer to transfer data from sampler to client
+ // commonStream = new RProfilerSampleStream(sampler,totalPrefix,32768);
+ TRAPD(err, iBufferHandler = CProfilerBufferHandler::NewL(aStream, sampler));
+ if(err != KErrNone)
+ {
+ LOGTEXT(_L("CGeneralsPlugin::InstallStreamForActiveTraces() - No memory"));
+ return;
+ }
+ }
+
+ // initiate receiving of data from the sampler device driver
+ if(iBufferHandler)
+ {
+ iBufferHandler->StartReceivingData();
+ }
+}
+
+void CGeneralsPlugin::SetSettingsToSamplers()
+ {
+ TSamplerAttributes attr;
+
+ // loop through the setting attributes
+ for(TInt i(0);i<iSamplerAttributes->Count();i++)
+ {
+ // get the attribute container
+ attr = iSamplerAttributes->At(i);
+
+ // make changes according to right sampler, NOTE! The old IDs of sub samplers (i+1)!
+ if(attr.iEnabled)
+ {
+ iGeneralsSampler.MarkTraceActive(i+1);
+
+ // set enabled
+ iEnabled = ETrue;
+ }
+ else
+ {
+ iGeneralsSampler.MarkTraceInactive(i+1);
+ }
+ // set sampling period if available
+ if(attr.iSampleRate != KErrNotFound)
+ {
+ iGeneralsSampler.SetSamplingPeriod(i+1, attr.iSampleRate);
+ }
+ }
+ }
+
+TInt CGeneralsPlugin::ResetAndActivateL(CProfilerSampleStream& aStream)
+ {
+ // the sampler starting functionality
+ LOGTEXT(_L("CGeneralsPlugin::ResetAndActivate() - entry"));
+
+ // now before starting the latest settings must be set to samplers itself
+ SetSettingsToSamplers();
+
+ if(Enabled())
+ {
+ LOGTEXT(_L("CGeneralsPlugin::ResetAndActivate() - starting sampling..."));
+ // start sampling process of enabled sub samplers
+ iGeneralsSampler.StartSampling();
+ LOGTEXT(_L("CGeneralsPlugin::ResetAndActivate() - installing stream for an active trace..."));
+
+ // install the trace for enabled samplers
+ InstallStreamForActiveTraces(iGeneralsSampler, aStream);
+ LOGSTRING2("CGeneralsPlugin::ResetAndActivate() - stream installed: 0x%x", aStream);
+ }
+
+ LOGTEXT(_L("CGeneralsPlugin::ResetAndActivate() - exit"));
+ return KErrNone;
+ }
+
+TInt CGeneralsPlugin::StopSampling()
+ {
+ // RDebug::Print(_L("CGeneralsPlugin::StopSampling() - Stopping sampler LDD"));
+ iGeneralsSampler.StopSampling();
+ // RDebug::Print(_L("CGeneralsPlugin::StopSampling() - Sampler LDD stopped"));
+
+ // check if bufferhandler has died
+ if(iBufferHandler)
+ {
+ // RDebug::Print(_L("CGeneralsPlugin::StopSampling() - Canceling the buffer handler"));
+ iBufferHandler->Cancel();
+ delete iBufferHandler;
+ iBufferHandler = NULL;
+ }
+ // set enabled
+ iEnabled = EFalse;
+ // RDebug::Print(_L("CGeneralsPlugin::StopSampling() - exit"));
+ return KErrNone;
+ }
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/src/GeneralsPluginImplementationTable.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,39 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+// INCLUDE FILES
+#include <e32std.h>
+#include <ecom/implementationproxy.h>
+
+#include "GeneralsPlugin.h"
+
+
+// Provides a key value pair table, this is used to identify
+// the correct construction function for the requested interface.
+const TImplementationProxy ImplementationTable[] =
+{
+ IMPLEMENTATION_PROXY_ENTRY(0x2001E5B2, CGeneralsPlugin::NewL)
+};
+
+// Function used to return an instance of the proxy table.
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+{
+ aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
+ return ImplementationTable;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/src/GeneralsSampler.cia Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,91 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <platform.h>
+
+#include "GeneralsDriver.h"
+#include <kern_priv.h> //temporary
+
+#ifdef __SMP__
+#include <e32cia.h>
+#include <arm.h>
+#include <arm_gic.h>
+#include <arm_tmr.h>
+#endif
+
+#if defined(__GCC32__)
+// CIA symbol macros for Gcc98r2
+#define CSM__ZN5NKern14CurrentContextEv " CurrentContext__5NKern"
+#elif defined(__ARMCC__)
+// CIA symbol macros for RVCT
+#define CSM__ZN5NKern14CurrentContextEv " __cpp(NKern::CurrentContext)"
+#else
+// CIA symbol macros for EABI assemblers
+#define CSM__ZN5NKern14CurrentContextEv " _ZN5NKern14CurrentContextEv"
+#endif
+
+#ifdef __WINS__
+__NAKED__ TUint* IntStackPtr()
+{
+ return 0;
+}
+
+__NAKED__ TUint32 SPSR()
+{
+ return 0;
+}
+__NAKED__ void UsrModLr(TUint32* a)
+{
+ *a = 0;
+}
+#else
+
+__NAKED__ TUint* IntStackPtr()
+{
+#ifdef __SMP__
+ asm("stmfd sp!, {r0-r12,lr} ");
+#endif
+ asm("mrs r1, cpsr "); // copy current program status register (cpsr) to R1
+ asm("bic r3, r1, #0x1f "); // compare to 0x1f, i.e. make sure that spsr is available?
+#ifdef __SMP__
+ __ASM_CLI_MODE(MODE_IRQ); // disable all interrupts and set to irq mode (we are in NTimer interrupt)
+#else
+ asm("orr r3, r3, #0xd2 "); // mode_irq, all interrupts off
+ asm("msr cpsr, r3 "); // write result on R3 back to cpsr, irqs disabled
+#endif
+ asm("mov r0, sp "); // read stack pointer to R0, mode r0=sp_irq
+ asm("msr cpsr, r1 "); // restore interrupts
+#ifdef __SMP__
+ asm("ldmfd sp!, {r0-r12,pc} ");
+#endif
+ __JUMP(,lr);
+}
+
+__NAKED__ TUint32 SPSR()
+{
+ asm("mrs r0, spsr ");
+ __JUMP(,lr);
+}
+__NAKED__ void UsrModLr(TUint32*)
+{
+ // r0 = address to store
+ asm ("stmia r0,{lr}^");
+ __JUMP(,lr);
+}
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/src/GppSamplerImpl.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,572 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <piprofiler/ProfilerVersion.h>
+#include <piprofiler/ProfilerTraces.h>
+#include <kern_priv.h>
+#include <arm.h>
+
+#include "GppSamplerImpl.h"
+
+extern TUint* IntStackPtr();
+#define TAG(obj) (*(TUint32*)&(obj.iAsyncDeleteNext))
+
+// properties for ISA task parsing
+const TUid KIsaPropertyCat={0x2001E5AD};
+enum TIsaPropertyKeys
+ {
+ EIsaPropertyIsaTaskParserStatus = 1,
+ EIsaPropertyIsaTaskAddressStart,
+ EIsaPropertyIsaTaskAddressEnd,
+ EIsaPropertyIsaTaskAddress,
+ EIsaPropertyIsaOsTaskRunningAddress,
+ EIsaPropertyIsaTaskParsedName
+ };
+
+
+DGppSamplerImpl::DGppSamplerImpl()
+ {
+ LOGTEXT("GppSamplerImpl::GppSamplerImpl");
+ iInterruptStack = (TUint*)IntStackPtr();
+
+ LOGTEXT("GppSamplerImpl::GppSamplerImpl - attaching to properties");
+
+ TInt err = iIsaStartAddr.Attach(KIsaPropertyCat, EIsaPropertyIsaTaskAddressStart);
+ if(err != KErrNone)
+ LOGTEXT("GppSamplerImpl::GppSamplerImpl() - Property EIsaPropertyIsaTaskAddressStart not available");
+ err = iIsaEndAddr.Attach(KIsaPropertyCat, EIsaPropertyIsaTaskAddressEnd);
+ if(err != KErrNone)
+ LOGTEXT("GppSamplerImpl::GppSamplerImpl() - Property EIsaPropertyIsaTaskAddressEnd not available");
+ err = iIsaPluginStatus.Attach(KIsaPropertyCat, EIsaPropertyIsaTaskParserStatus);
+ if(err != KErrNone)
+ LOGTEXT("GppSamplerImpl::GppSamplerImpl() - Property EIsaPropertyIsaTaskParserStatus not available");
+ err = iIsaOsTaskRunning.Attach(KIsaPropertyCat, EIsaPropertyIsaOsTaskRunningAddress);
+ if(err != KErrNone)
+ LOGTEXT("GppSamplerImpl::GppSamplerImpl() - Property EIsaPropertyIsaOsTaskRunningAddress not available");
+
+ PROFILER_ISA_TASK_NAMES
+
+ Reset();
+ }
+
+DGppSamplerImpl::~DGppSamplerImpl()
+ {
+ iIsaStartAddr.Close();
+ iIsaEndAddr.Close();
+ iIsaPluginStatus.Close();
+ iIsaOsTaskRunning.Close();
+ }
+
+void DGppSamplerImpl::Reset()
+ {
+ LOGTEXT("GppSamplerImpl::Reset");
+ iLastPc = 0;
+ iLastThread = 0;
+ iRepeat = 0;
+ iIsaStatus = 0;
+ iIsaStart = 0;
+ iIsaEnd = 0;
+// isaOsTaskRunningAddr = 0;
+
+ // in SMP start time common with all CPUs, provided by DGeneralsDriver class
+#ifndef __SMP__
+ iStartTime = ( NKern::TickCount() & 0xfffffffc );
+#endif
+
+ TPropertyStatus status;
+ TInt osAddr = 0;
+
+ LOGTEXT("GppSamplerImpl::Reset - getting status");
+
+ // get status of ISA plug-in
+ if(iIsaPluginStatus.GetStatus(status))
+ {
+ iIsaPluginStatus.Get(iIsaStatus);
+ LOGSTRING2("GppSamplerImpl::Reset - ISA plug-in status %d", iIsaStatus);
+ }
+
+ if(iIsaStatus > 0)
+ {
+ LOGTEXT("GppSamplerImpl::Reset - get isa start address");
+ iIsaStartAddr.Get(iIsaStart);
+ LOGTEXT("GppSamplerImpl::Reset - get isa end address");
+ iIsaEndAddr.Get(iIsaEnd);
+ LOGTEXT("GppSamplerImpl::Reset - get isa os_task_running address");
+ iIsaOsTaskRunning.Get(osAddr);
+ isaOsTaskRunningAddr = reinterpret_cast<TInt*>(osAddr);
+ LOGSTRING2("GppSamplerImpl::Reset - got isa os_task_running address 0x%X", osAddr);
+ }
+
+ LOGTEXT("GppSamplerImpl::Reset - initializing isa task list");
+
+ iIsaSample = false;
+
+ for(TInt i=0;i<256;i++)
+ knownIsaTasks[i] = -1;
+
+ knownIsaTaskCount = 0;
+
+ iCpuSelector = 0x3;
+#ifndef __SMP__
+ iMask = 0xfffffffc;
+#else
+ iMask = 0xfffffff0;
+ switch(iCpuNumber)
+ {
+ case 0:
+ iCpuSelector = 0x1;
+ break;
+ case 1:
+ iCpuSelector = 0x2;
+ break;
+ case 2:
+ iCpuSelector = 0x4;
+ break;
+ case 3:
+ iCpuSelector = 0x8;
+ break;
+ }
+#endif
+ }
+
+TUint8* DGppSamplerImpl::EncodeTag(TUint8* aPtr)
+//
+// Encode a tag and version to the trace data. This allows the offline analyser to
+// identify the sample data.
+//
+{
+ _LIT(KGppSamplerVersion,"Bappea_GPP_V");
+ _LIT(KProfilerVersion,"#Prof#");
+ _LIT(KSamplerVersion,"#Samp#");
+#ifdef __SMP__
+ _LIT(KCPUNumberText,"#CPU#");
+#endif
+
+ TBuf<64> buf;
+ buf.Zero();
+ buf.Append(KGppSamplerVersion);
+ buf.Append(PROFILER_GPP_SAMPLER_VERSION);
+ buf.Append(KProfilerVersion);
+ buf.Append(PROFILER_VERSION_SHORT);
+ buf.Append(KSamplerVersion);
+ buf.Append(PROFILER_SAMPLER_VERSION);
+#ifdef __SMP__
+ buf.Append(KCPUNumberText);
+ buf.AppendNum(iCpuNumber);
+#endif
+ aPtr = EncodeText(aPtr, buf);
+ return aPtr;
+}
+
+TUint8* DGppSamplerImpl::EncodeInt(TUint8* aPtr,TInt aValue)
+{
+ LOGSTRING2("Encoding int 0x%x",aPtr);
+
+ LOGSTRING2("TIint = 0x%x",aValue);
+
+ TUint byte;
+ for (;;)
+ {
+ byte = aValue & 0x7f;
+ if ((aValue >> 6) == (aValue >> 7))
+ break;
+ aValue >>= 7;
+ *aPtr++ = byte;
+ }
+ *aPtr++ = byte | 0x80;
+
+ LOGSTRING2("Encoded int 0x%x",aPtr);
+
+ return aPtr;
+}
+
+TUint8* DGppSamplerImpl::EncodeUint(TUint8* aPtr,TUint aValue)
+{
+ LOGSTRING2("Encoding Uint 0x%x",aPtr);
+
+ LOGSTRING2("TUint = 0x%x",aValue);
+
+
+ TUint byte;
+ for (;;)
+ {
+ byte = aValue & 0x7f;
+ aValue >>= 7;
+ if (aValue == 0)
+ break;
+ *aPtr++ = byte;
+ }
+ *aPtr++ = byte | 0x80;
+
+ LOGSTRING2("Encoded Uint 0x%x",aPtr);
+
+ return aPtr;
+}
+
+TUint8* DGppSamplerImpl::EncodeText(TUint8* aPtr, const TDesC& aDes)
+//
+// Encode a descriptor into the data stream
+// This is currently limited to a descriptor that is up to 255 characters in length,
+// and Unicode characters are truncated to 8 bits
+//
+{
+ LOGSTRING2("Encoding text 0x%x",aPtr);
+ TInt len=aDes.Length();
+ *aPtr++ = TUint8(len);
+ const TText* p = aDes.Ptr();
+ while (--len >= 0)
+ {
+ *aPtr++ = TUint8(*p++);
+ }
+
+ LOGSTRING2("Encoded text 0x%x",aPtr);
+ return aPtr;
+}
+
+
+TUint8* DGppSamplerImpl::EncodeName(TUint8* aPtr, DObject& aObject,TUint32 id)
+//
+// Encode the name of a kernel object
+//
+{
+ LOGSTRING2("Encoding name 0x%x",aPtr);
+ TBuf8<0x5f> name;
+ aObject.TraceAppendName(name,false);
+
+ if(id != 0xffffffff)
+ {
+ name.Append('[');
+ name.AppendNum(id,EHex);
+ name.Append(']');
+ }
+ else
+ {
+ name.Append('[');
+ name.AppendNum((TUint32)((void*)&(((DThread*)&aObject)->iNThread)),EHex);
+ name.Append(']');
+ }
+
+ aPtr = EncodeText(aPtr,name);
+ LOGSTRING2("Encoded name 0x%x",aPtr);
+ return aPtr;
+}
+
+TUint8* DGppSamplerImpl::EncodeThread(TUint8* aPtr, DThread& aThread)
+//
+// Encode a thread name in the data stream.
+// The thread is identified by its name, and the identity of its owning process.
+// If the process has not been identified in the data stream already, it's name is
+// also encoded.
+//
+{
+ LOGSTRING2("Encoding thread 0x%x",aPtr);
+
+ DProcess& p = *aThread.iOwningProcess;
+
+ aPtr = EncodeUint(aPtr, p.iId);
+
+#ifdef __SMP__
+ // check if first time founding
+ if ((TAG(p) & iMask) != iStartTime)
+ {
+ // mark tagged for this CPU
+ TAG(p) = (iStartTime | iCpuSelector);
+
+ // The thread is 'unknown' to this sample, so encode the thread name
+ aPtr = EncodeName(aPtr, p, p.iId);
+ }
+ // check if thread appeared already on this CPU
+ else if((TAG(p) & iCpuSelector) != iCpuSelector)
+ {
+ TAG(p) = (TAG(p) | iCpuSelector);
+ // The thread is 'unknown' to this sample, so encode the thread name
+ aPtr = EncodeName(aPtr, p, p.iId);
+ }
+#else
+ if (TAG(p) != iStartTime)
+ {
+ TAG(p) = iStartTime;
+ // Provide the name matching this process ID
+ aPtr = EncodeName(aPtr, p, p.iId);
+ }
+#endif
+ aPtr = EncodeName(aPtr, aThread,0xffffffff);
+
+ LOGSTRING2("Encoded thread 0x%x",aPtr);
+
+ return aPtr;
+ }
+
+TUint8* DGppSamplerImpl::EncodeRepeat(TUint8* aPtr)
+//
+// Encode a repeated sequence of samples
+//
+{
+ LOGSTRING2("Encoding repeat, 0x%x",iRepeat);
+
+ aPtr = EncodeInt(aPtr, 0);
+ aPtr = EncodeUint(aPtr, iRepeat);
+ iRepeat = 0;
+
+ LOGSTRING2("Encoded repeat, 0x%x",iRepeat);
+
+ return aPtr;
+}
+
+TInt DGppSamplerImpl::CreateFirstSample()
+{
+ LOGTEXT("GppSamplerImpl::CreateFirstSample");
+ Reset();
+
+ TUint8* w = this->tempBuf;
+ w = EncodeTag(w);
+
+ TInt length = w-tempBuf;
+
+ LOGSTRING2("TAG encoded, length %d",length);
+ return length;
+}
+
+TBool DGppSamplerImpl::IsaTaskKnown(TUint8 task)
+{
+ for(TInt i=0;i<256;i++)
+ {
+ if(knownIsaTasks[i] == -1)
+ {
+ knownIsaTasks[i] = task;
+ knownIsaTaskCount++;
+ return false;
+ }
+ else if(knownIsaTasks[i] == task)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+TUint8* DGppSamplerImpl::EncodeIsaTask(TUint8* aPtr, TUint task)
+
+{
+ LOGSTRING2("Encoding ISA task 0x%x",aPtr);
+
+ aPtr = EncodeUint(aPtr,task);
+ // use the task name as the process name
+ aPtr = EncodeIsaName(aPtr,task,true);
+ // then encode the task name
+ aPtr = EncodeIsaName(aPtr,task,false);
+
+ LOGSTRING2("Encoded ISA task 0x%x",aPtr);
+
+ return aPtr;
+}
+
+TUint8* DGppSamplerImpl::EncodeIsaName(TUint8* aPtr, TUint task,TBool process)
+//
+// Encode a descriptor into the data stream
+// This is currently limited to a descriptor that is up to 255 characters in length,
+// and Unicode characters are truncated to 8 bits
+//
+{
+ TBuf8<256> aDes;
+
+// #ifdef NCP_COMMON_PROFILER_ISA_TASKS
+ if(iIsaStatus > 0)
+ {
+ // resolve the isa task name from the task name array
+ if((task-100000) < PROFILER_ISA_OS_TASK_AMOUNT && process == false)
+ {
+ aDes.Append(isaTaskNames[(task-100000)]);
+ }
+ else
+ {
+ aDes.Append(_L8("NativeOS_Task"));
+ }
+ }
+ else
+ {
+ aDes.Append(_L8("NativeOS_Task"));
+ }
+
+ aDes.Append('[');
+ aDes.AppendNum((task-100000),EHex);
+ aDes.Append(']');
+
+ LOGSTRING2("Encoding ISA name 0x%x",aPtr);
+ TInt len=aDes.Length();
+ *aPtr++ = TUint8(len);
+ const TText* p = aDes.Ptr();
+ while (--len >= 0)
+ {
+ *aPtr++ = TUint8(*p++);
+ }
+
+ LOGSTRING2("Encoded ISA name 0x%x",aPtr);
+ return aPtr;
+}
+
+
+TInt DGppSamplerImpl::SampleImpl()
+//
+// ISR for the profile timer
+// This extracts the thread and PC that was current when the interrupt went off and
+// encodes it into the sample data buffer. If enough data has been generated, the
+// DFC is triggered to complete a read request
+//
+ {
+ TUint8* w(this->tempBuf);
+
+// Kern::Printf(("Got thread 0x%08x"), &t);
+#ifdef __SMP__
+ // get the program counter of irq mode
+ TUint32 pc = (TUint32)Arm::IrqReturnAddress();
+#else
+ // get program counter of irq mode
+ TUint32 pc = iInterruptStack[-1];
+#endif
+ //LOGSTRING3("pc value 0x%x sp 0x%x",pc,iInterruptStack);
+
+ // ignore the low bit being set for THUMB mode - we use for something else
+ pc &= ~1;
+ TInt diff = pc - iLastPc;
+ iLastPc = pc;
+
+ if(iIsaStatus > 0)
+ {
+ if((TUint32)pc > (TUint32)iIsaStart && (TUint32)pc < (TUint32)iIsaEnd)
+ {
+ LOGSTRING2("Identified ISA execution at 0x%x",pc);
+ iIsaSample = true;
+ }
+ else
+ {
+ LOGSTRING2("Normal sample at 0x%x",pc);
+ iIsaSample = false;
+ }
+ }
+
+ // request for current thread from kernel
+ DThread& t = ((DThread&)*Kern::NThreadToDThread(NKern::CurrentThread()));
+
+ TUint tid;
+ TUint8 isaTask = 0;
+ if(iIsaSample)
+ {
+ LOGSTRING2("Reading ISA task number from 0x%x",isaOsTaskRunningAddr);
+
+ // if we don't get reasonable ISA address to read, skip ISA task handling
+ if(isaOsTaskRunningAddr == 0)
+ {
+ tid = 100000; // to tell the difference from SOS threads
+ iIsaSample = false;
+ }
+ else // normal ISA task parsing process
+ {
+ isaTask = *isaOsTaskRunningAddr;
+ LOGSTRING2("ISA task = %d",isaTask);
+ tid = isaTask;
+ // this will make sure we don't mix ISA tasks and normal tasks
+ tid += 100000;
+ }
+
+ }
+ else
+ {
+ tid = t.iId;
+ }
+
+ if (tid != iLastThread)
+ {
+ // Change of thread is marked in the low bit of the PC difference
+ diff |= 1;
+ }
+ TUint rp = iRepeat;
+ if (diff == 0)
+ {
+ // Identical sample, bump up the repeat count
+ iRepeat = rp + 1;
+ }
+ else
+ {
+ if (rp)
+ {
+ // Encode the repeat data
+ w = EncodeRepeat(w);
+ }
+ // Encode the PC difference
+ w = EncodeInt(w, diff);
+ if (diff & 1)
+ {
+ // Encode the new thread ID
+ if(iIsaSample)
+ {
+ iLastThread = tid;
+ w = EncodeUint(w,tid);
+
+ if(!this->IsaTaskKnown(isaTask))
+ {
+ w = EncodeIsaTask(w,iLastThread);
+ }
+ //LOGSTRING2("Sample total length: %d",w-tempBuf);
+ TInt length = w-tempBuf;
+ // encoded isa task, return here
+ return length;
+ }
+
+ iLastThread = tid;
+ w = EncodeUint(w, tid);
+
+#ifdef __SMP__
+ // iStartTime format: 0xXXXXXXX0, the last byte set to zero
+ // iMask = 0xfffffff0(0b111....1110000)
+ // iCpuSelector = 0x1(0b0001), 0x2(0b0010), 0x4(0b0100) or 0x8(0b1000)
+
+ // check first time founding
+ if ((TAG(t) & iMask) != iStartTime)
+ {
+ // mark tagged for this CPU
+ TAG(t) = (iStartTime | iCpuSelector);
+
+ // The thread is 'unknown' to this sample, so encode the thread name
+ w = EncodeThread(w, t);
+ }
+ // check if thread appeared on this CPU
+ else if((TAG(t) & iCpuSelector) != iCpuSelector)
+ {
+ TAG(t) = (TAG(t) | iCpuSelector);
+ // The thread is 'unknown' to this sample, so encode the thread name
+ w = EncodeThread(w, t);
+ }
+#else
+ // check if tag has not been set, neither original nor
+ if ((TAG(t) & 0xfffffffc) != iStartTime)
+ {
+ TAG(t) = ((TAG(t) & 0x3) | iStartTime);
+ // The thread is 'unknown' to this sample, so encode the thread name
+ w = EncodeThread(w, t);
+ }
+#endif
+ }
+ }
+ LOGSTRING2("Sample total length: %d",w-tempBuf);
+ TInt length = w-tempBuf;
+
+ return length;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/src/IttEventHandler.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,174 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Event based ITT sampler skeleton copypasted from MemoryEventHandler.cpp
+*
+*/
+
+#include <e32def.h>
+#include <e32cmn.h>
+#include <arm.h>
+#include <kernel.h>
+#include <kern_priv.h>
+#include <nk_trace.h>
+
+#include "IttEventHandler.h"
+
+/*
+ * Constructor
+ *
+ * @param DProfilerSampleBuffer* pointer to sample buffer
+ */
+DIttEventHandler::DIttEventHandler(DProfilerSampleBuffer* aSampleBuffer, TProfilerGppSamplerData* aGppSamplerDataIn)
+ : DKernelEventHandler(EventHandler, this),
+ iSampleBuffer(aSampleBuffer),
+ iSampleDescriptor(&(this->iSample[1]),0,KITTBufferSize),
+ gppSamplerData(aGppSamplerDataIn)
+ {
+ //Kern::Printf("DIttEventHandler::DIttEventHandler()");
+
+ }
+
+/*
+ * DIttEventHandler::Create()
+ */
+TInt DIttEventHandler::Create()
+ {
+ Kern::Printf("DIttEventHandler::Create()");
+
+ TInt err(Kern::MutexCreate(iLock, _L("IttEventHandlerLock"), KMutexOrdDebug));
+ if (err != KErrNone)
+ return err;
+
+ return Add();
+ }
+
+/*
+ * Destructor
+ */
+DIttEventHandler::~DIttEventHandler()
+ {
+ //Kern::Printf("DIttEventHandler::~DIttEventHandler()");
+
+ if (iLock)
+ iLock->Close(NULL);
+ }
+
+
+TInt DIttEventHandler::Start()
+ {
+ //Kern::Printf("DIttEventHandler::Start()");
+
+ iTracking = ETrue;
+ return KErrNone;
+ }
+
+
+TInt DIttEventHandler::Stop()
+ {
+ //Kern::Printf("DIttEventHandler::Stop()");
+
+ iTracking = EFalse;
+ return KErrNone;
+ }
+
+TBool DIttEventHandler::SampleNeeded()
+ {
+ LOGTEXT("DIttEventHandler::SampleNeeded()");
+
+ // increase the counter by one on each round
+ iCount++;
+
+ // check if event handler was not running
+ if(!iTracking)
+ return false;
+
+ return true;
+ }
+
+
+TUint DIttEventHandler::EventHandler(TKernelEvent aType, TAny* a1, TAny* a2, TAny* aThis)
+ {
+ //Kern::Printf("DIttEventHandler::EventHandler()");
+ return ((DIttEventHandler*)aThis)->HandleEvent(aType, a1, a2);
+ }
+
+
+
+TUint DIttEventHandler::HandleEvent(TKernelEvent aType, TAny* a1, TAny* a2)
+ {
+ //Kern::Printf("DIttEventHandler::HandleEvent()");
+ //Kern::Printf("New kernel event received, %d", aType);
+
+ if (iTracking/* && iCount != iPreviousCount*/)
+ {
+ switch (aType)
+ {
+
+ case EEventAddCodeSeg:
+ //Kern::Printf("DCodeSeg added: 0x%08x", (DCodeSeg*)a1);
+ HandleAddCodeSeg((DCodeSeg*)a1);
+ break;
+
+ case EEventRemoveCodeSeg:
+ //Kern::Printf("DCodeSeg deleted: 0x%08x", (DCodeSeg*)a1);
+ HandleRemoveCodeSeg((DCodeSeg*)a1);
+ break;
+
+ default:
+ break;
+ }
+ }
+// else if(iTracking && iCount == iPreviousCount)
+// {
+// // if time stamp is not updated profiling has stopped
+// Stop();
+// }
+ return DKernelEventHandler::ERunNext;
+ }
+
+/*
+ *
+ */
+TBool DIttEventHandler::HandleAddCodeSeg(DCodeSeg* aSeg)
+ {
+ iSampleDescriptor.Zero();
+ //Kern::Printf("DLL ADD: NM %S : RA:0x%x SZ:0x%x SN:0x%x",aSeg->iFileName,aSeg->iRunAddress,aSeg->iSize, this->gppSamplerData->sampleNumber);
+
+ iSample[0] = aSeg->iFileName->Length();
+ iSampleDescriptor.Append(*aSeg->iFileName);
+ iSampleDescriptor.Append((TUint8*)&(aSeg->iRunAddress),4);
+ iSampleDescriptor.Append((TUint8*)&(aSeg->iSize),4);
+ iSampleDescriptor.Append((TUint8*)&(this->gppSamplerData->sampleNumber),4);
+ iSample[0] = iSampleDescriptor.Size();
+
+ iSampleBuffer->AddSample(iSample,iSampleDescriptor.Size()+1);
+ return ETrue;
+ }
+
+TBool DIttEventHandler::HandleRemoveCodeSeg(DCodeSeg* aSeg)
+ {
+ iSampleDescriptor.Zero();
+ //Kern::Printf("DLL REM: NM %S : RA:0x%x SZ:0x%x SN:0x%x",aSeg->iFileName,aSeg->iRunAddress,aSeg->iSize, this->gppSamplerData->sampleNumber);
+
+ iSample[0] = aSeg->iFileName->Length();
+ iSampleDescriptor.Append(*aSeg->iFileName);
+ iSampleDescriptor.Append((TUint8*)&(aSeg->iRunAddress),4);
+ iSampleDescriptor.Append((TUint8*)&(aSeg->iSize),4);
+ iSampleDescriptor.Append((TUint8*)&(this->gppSamplerData->sampleNumber),4);
+ iSample[0] = iSampleDescriptor.Size();
+
+ iSampleBuffer->AddSample(iSample,iSampleDescriptor.Size()+1);
+ return ETrue;
+ }
+// end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/src/IttSamplerImpl.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,244 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <piprofiler/ProfilerVersion.h>
+
+#include <kern_priv.h>
+#include <plat_priv.h>
+
+#include "IttSamplerImpl.h"
+
+#ifdef ITT_EVENT_HANDLER
+_LIT8(KIttVersion, "2.00");
+#else
+_LIT8(KIttVersion, "1.22");
+#endif
+
+/*
+ * ITT sampler definition
+ *
+ */
+IttSamplerImpl::IttSamplerImpl():
+ sampleDescriptor(&(this->sample[1]),0,KITTSampleBufferSize)
+{
+ this->currentLibCount = 0;
+ iTimeToSample = EFalse;
+ this->Reset();
+}
+
+/*
+ * destructor
+ */
+IttSamplerImpl::~IttSamplerImpl()
+{
+
+}
+
+/*
+ * IttSamplerImpl::CreateFirstSample()
+ *
+ * Function for creating the first sample to the log file
+ */
+TInt IttSamplerImpl::CreateFirstSample()
+{
+ Kern::Printf("ittSamplerImpl::createFirstSample\n");
+ this->iVersionData.Zero();
+ this->iVersionData.Append(_L8("Bappea_ITT_V"));
+ this->iVersionData.Append(KIttVersion);
+ this->itt_sample = (TUint8*)iVersionData.Ptr();
+ return iVersionData.Length();
+}
+
+/*
+ * IttSamplerImpl::SampleNeeded(TUint32 sampleNum)
+ *
+ * @param TUint32 Sample number
+ *
+ */
+TBool IttSamplerImpl::SampleNeeded(TUint32 sampleNum)
+{
+#ifdef ITT_EVENT_HANDLER
+ iCount++;
+ if (iCount <= iIttSamplingPeriod && ((iCount % iIttSamplingPeriod) == 0 || (iCount % iIttSamplingPeriodDiv2) == 0))
+ {
+ LOGSTRING2("IttSamplerImpl::SampleNeeded - time: %d", iCount);
+ iTimeToSample = true;
+#else
+ // no need to do anything, always a good time to sample.
+ // Sample time filtering is done in IttSamplerImpl:SampleImpl() function
+#endif
+ return true;
+#ifdef ITT_EVENT_HANDLER
+ }
+ else
+ {
+ return false;
+ }
+#endif
+}
+
+/*
+ * IttSamplerImpl::SampleImpl(TUint32 pc, TUint32 sampleNum)
+ *
+ * @param TUint32 program counter
+ * @param TUint32 sample number
+ */
+TInt IttSamplerImpl::SampleImpl(TUint32 pc,TUint32 sampleNum)
+{
+ // in order to avoid overloading the interrupt
+ // only one dynamic file in each 50ms is added to the stream
+ // with the application of the tool in mind, this is
+ // a reasonable measure
+
+ // encode a process binary
+ sampleDescriptor.Zero();
+ // original
+ if((sampleNum % 20) != 0) return 0;
+ if((sampleNum % 40) == 0)
+ {
+ // encode a library binary
+ sampleDescriptor.Zero();
+ DObjectCon* libs = Kern::Containers()[ELibrary];
+ TInt libCount = libs->Count();
+
+ // go 20 binaries through at a time
+ for(TInt i=0;i<20;i++)
+ {
+ if(currentLibCount >= libCount)
+ {
+ currentLibCount = 0;
+ }
+
+ DLibrary* lib = (DLibrary*)(*libs)[currentLibCount];
+ currentLibCount++;
+
+ DCodeSeg* seg = lib->iCodeSeg;
+ if(seg != 0)
+ {
+ if( (seg->iMark & 0x80) == 0)
+ {
+ this->sample[0] = seg->iFileName->Length();
+ sampleDescriptor.Append(*(seg->iFileName));
+ sampleDescriptor.Append((TUint8*)&(seg->iRunAddress),4);
+ sampleDescriptor.Append((TUint8*)&(seg->iSize),4);
+#ifdef ITT_EVENT_HANDLER
+ sampleDescriptor.Append((TUint8*)&(sampleNum),4);
+ //Kern::Printf("DLL: NM %S : RA:0x%x SZ:0x%x, SN:0x%x",seg->iFileName,seg->iRunAddress,seg->iSize, sampleNum);
+ this->iFirstSampleTaken = ETrue;
+#else
+ //Kern::Printf("DLL: NM %S : RA:0x%x SZ:0x%x",seg->iFileName,seg->iRunAddress,seg->iSize);
+#endif
+ seg->iMark = (seg->iMark | 0x80);
+
+ this->sample[0] = sampleDescriptor.Size();
+ return sampleDescriptor.Size()+1;
+ }
+ }
+ }
+ } else
+ {
+ SDblQue* codeSegList = Kern::CodeSegList();
+ //Kern::Printf("PI");
+ //TUint c = 0;
+ // the global list
+ for (SDblQueLink* codeseg= codeSegList->First(); codeseg!=(SDblQueLink*) codeSegList; codeseg=codeseg->iNext)
+ {
+ DCodeSeg* seg = _LOFF(codeseg, DCodeSeg, iLink);
+ if(seg != 0)
+ {
+ if( (seg->iMark & 0x80) == 0)
+ {
+ this->sample[0] = seg->iFileName->Length();
+ sampleDescriptor.Append(*(seg->iFileName));
+ sampleDescriptor.Append((TUint8*)&(seg->iRunAddress),4);
+ sampleDescriptor.Append((TUint8*)&(seg->iSize),4);
+#ifdef ITT_EVENT_HANDLER
+ sampleDescriptor.Append((TUint8*)&(sampleNum),4);
+ //Kern::Printf("EXE2: NM %S : RA:0x%x SZ:0x%x, time: %d",seg->iFileName,seg->iRunAddress,seg->iSize, sampleNum);
+ this->iFirstSampleTaken = ETrue;
+#else
+ //Kern::Printf("EXE2: NM %S : RA:0x%x SZ:0x%x, time: %d",seg->iFileName,seg->iRunAddress,seg->iSize, sampleNum);
+#endif
+ seg->iMark = (seg->iMark | 0x80);
+
+ this->sample[0] = sampleDescriptor.Size();
+ return sampleDescriptor.Size()+1;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+/*
+ * IttSamplerImpl::Reset()
+ */
+void IttSamplerImpl::Reset()
+{
+ iTimeToSample = EFalse;
+#ifdef ITT_EVENT_HANDLER
+ iFirstSampleTaken = EFalse;
+#endif
+ this->currentLibCount = 0;
+ this->itt_sample = (TUint8*)&(this->sample[0]);
+ sampleDescriptor.Zero();
+
+// #ifdef ITT_TEST
+ SDblQue* codeSegList = Kern::CodeSegList();
+ // the global list
+ for (SDblQueLink* codeseg= codeSegList->First(); codeseg!=(SDblQueLink*) codeSegList; codeseg=codeseg->iNext)
+ {
+ DCodeSeg* seg = _LOFF(codeseg,DCodeSeg, iLink);
+ //if(seg != 0)
+ {
+ if( (seg->iMark & 0x80) > 0)
+ {
+ seg->iMark = (seg->iMark & ~0x80);
+ }
+ }
+ }
+ // the garbage list
+ DObjectCon* libs = Kern::Containers()[ELibrary];
+ TInt libCount = libs->Count();
+ for(TInt i=0;i<libCount;i++)
+ {
+ DLibrary* lib = (DLibrary*)(*libs)[i];
+ DCodeSeg* seg = lib->iCodeSeg;
+ if( (seg->iMark & 0x80) > 0)
+ {
+ seg->iMark = (seg->iMark & ~0x80);
+ }
+ }
+
+ DObjectCon* procs = Kern::Containers()[EProcess];
+ TInt procCount = procs->Count();
+ for(TInt i=0;i<procCount;i++)
+ {
+ DProcess* pro = (DProcess*)(*procs)[i];
+ DCodeSeg* seg = pro->iCodeSeg;
+ if(seg != 0)
+ {
+ if( (seg->iMark & 0x80) > 0)
+ {
+ seg->iMark = (seg->iMark & ~0x80);
+ }
+ }
+ }
+ //#endif //ITT_TEST
+}
+// end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/src/MemSamplerImpl.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,976 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <piprofiler/ProfilerVersion.h>
+#include <piprofiler/ProfilerTraces.h>
+
+#include <kern_priv.h>
+#include <plat_priv.h>
+
+#include "MemSamplerImpl.h"
+
+// for testing precise stack utilization tracing...
+// crashes at the moment
+
+#include <nk_cpu.h>
+
+#if !defined(__NKERN_H__)
+#include <nkern.h>
+#endif
+
+#define TAG(obj) (*(TUint32*)&(obj->iAsyncDeleteNext))
+#define PROFILER_CHUNK_MARK ((TUint32)0x00001000)
+#define PROFILER_MEM_THREAD_MARK ((TUint32)0x00000001)
+#define PROFILER_LIBRARY_MARK ((TUint32)0x10000000)
+#define PROFILER_MEM_THREAD_UNMARK ~PROFILER_MEM_THREAD_MARK
+
+#ifdef MEM_EVENT_HANDLER
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+_LIT8(KMemVersion,"2.03");
+#else
+_LIT8(KMemVersion, "2.02");
+#endif
+#else
+_LIT8(KMemVersion, "1.56");
+#endif
+
+DMemSamplerImpl::DMemSamplerImpl() :
+ sampleDescriptor(&(this->sample[1]),0,256)
+ {
+ LOGSTRING("MemSamplerImpl::MemSamplerImpl() - konstruktori");
+
+ iCount = 0;
+
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+ iSampleType = ESampleThreads;
+#else
+ iSampleThreads = true;
+#endif
+ iTimeToSample = false;
+
+ iTotalMemoryOk = false;
+ iTotalMemoryNameOk = false;
+
+ iNewChunkCount = 0;
+ iChunkCount = 0;
+ iChunksProcessing = ENothingToProcess;
+ iThreadsProcessing = ENothingToProcess;
+
+ iNewThreadCount = 0;
+ iThreadCount = 0;
+
+ // reset data structures
+ for(TInt i(0);i<KProfilerMaxChunksAmount;i++)
+ {
+ // heap chunks
+ this->heapChunksToSample[i] = 0;
+ this->heapChunkNamesToReport[i] = 0;
+ }
+
+ for(TInt i(0);i<KProfilerMaxThreadsAmount;i++)
+ {
+ // threads
+ this->threadsToSample[i] = 0;
+ this->threadNamesToReport[i] = 0;
+ }
+
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+ iLibrariesProcessing = ENothingToProcess;
+ iNewLibraryCount = 0;
+ iLibraryCount = 0;
+
+ for(TInt i(0); i<KProfilerMaxLibrariesAmount; i++)
+ {
+ // libraries
+ this->librariesToSample[i] = 0;
+ this->libraryNamesToReport[i] = 0;
+ }
+#endif
+
+ }
+
+DMemSamplerImpl::~DMemSamplerImpl()
+ {
+
+ }
+
+TInt DMemSamplerImpl::CreateFirstSample()
+ {
+ LOGSTRING("MemSamplerImpl::CreateFirstSample - entry");
+
+ this->sampleDescriptor.Zero();
+ this->sampleDescriptor.Append(_L8("Bappea_V"));
+ this->sampleDescriptor.Append(KMemVersion);
+ this->sampleDescriptor.Append(_L8("_MEM"));
+
+ sample[0] = this->sampleDescriptor.Size();
+
+ LOGSTRING("MemSamplerImpl::CreateFirstSample - exit");
+
+ return (TInt)(sample[0]+1);
+ }
+
+TBool DMemSamplerImpl::SampleNeeded()
+ {
+ iCount++;
+#ifdef MEM_EVENT_HANDLER
+ // make the collection of chunks/threads only once, rest will be collected with mem event handler
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+ if (iCount <= iMemSamplingPeriod && ((iCount % iMemSamplingPeriod) == 0 || (iCount % iMemSamplingPeriodDiv3) == 0))
+#else
+ if (iCount <= iMemSamplingPeriod && ((iCount % iMemSamplingPeriod) == 0 || (iCount % iMemSamplingPeriodDiv2) == 0))
+#endif
+#else
+ if ((iCount % iMemSamplingPeriod) == 0 || (iCount % iMemSamplingPeriodDiv2) == 0)
+#endif
+ {
+ LOGSTRING2("MemSamplerImpl::SampleNeeded - time: %d", iCount);
+ iTimeToSample = true;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+
+ }
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+TInt DMemSamplerImpl::SampleImpl()
+ {
+ // Sample threads:
+ if( iSampleType == ESampleThreads )
+ {
+ if(this->iThreadsProcessing == ENothingToProcess )
+ {
+ if(!iTimeToSample)
+ {
+ return 0;
+ }
+ else
+ {
+ iTimeToSample = false;
+ // gather first all thread stacks
+ return GatherThreads();
+ }
+ }
+ else
+ {
+ // process now thread stack list
+ TInt length = this->ProcessThreads();
+
+ if(length == 0)
+ {
+ this->iThreadsProcessing = ENothingToProcess;
+ // switch to collect chunk data
+ iSampleType = ESampleChunks;
+ }
+ return length;
+ }
+ }
+
+ // Sample chunks:
+ if( iSampleType == ESampleChunks )
+ {
+ if(this->iChunksProcessing == ENothingToProcess)
+ {
+ if(!iTimeToSample)
+ {
+ return 0;
+ }
+ else
+ {
+ iTimeToSample = false;
+ // gather first all chunks
+ return GatherChunks();
+ }
+ }
+ else
+ {
+ // still something to go through in lists
+ TInt length = this->ProcessChunks();
+
+ if(length == 0)
+ {
+ this->iChunksProcessing = ENothingToProcess;
+ // switch to collect library data
+ iSampleType = ESampleLibraries;
+ //iSampleThreads = true;
+ }
+ return length;
+ }
+ }
+
+ // Sample libraries:
+ if( iSampleType == ESampleLibraries )
+ {
+ if(this->iLibrariesProcessing == ENothingToProcess )
+ {
+ if(!iTimeToSample)
+ {
+ return 0;
+ }
+ else
+ {
+ iTimeToSample = false;
+ // gather libraries
+ return GatherLibraries();
+ }
+ }
+ else
+ {
+ // process now thread stack list
+ TInt length = this->ProcessLibraries();
+ if(length == 0)
+ {
+ this->iLibrariesProcessing = ENothingToProcess;
+ // switch to collect chunk data
+ iSampleType = ESampleThreads;
+ }
+ return length;
+ }
+ }
+
+ // should not reach this point...
+ return 0;
+ }
+#else
+TInt DMemSamplerImpl::SampleImpl()
+ {
+ // check if either chunk or thread lists have unprocessed items
+ if(this->iChunksProcessing == ENothingToProcess && !iSampleThreads)
+ {
+ if(!iTimeToSample)
+ {
+ return 0;
+ }
+ else
+ {
+ iTimeToSample = false;
+ // gather first all chunks
+ return GatherChunks();
+ }
+ }
+ else if(!iSampleThreads)
+ {
+ // still something to go through in lists
+ TInt length = this->ProcessChunks();
+
+ if(length == 0)
+ {
+ this->iChunksProcessing = ENothingToProcess;
+ // switch to collect thread data
+ iSampleThreads = true;
+ }
+ return length;
+ }
+
+ if(this->iThreadsProcessing == ENothingToProcess && iSampleThreads)
+ {
+ if(!iTimeToSample)
+ {
+ return 0;
+ }
+ else
+ {
+ iTimeToSample = false;
+ // gather first all thread stacks
+ return GatherThreads();
+ }
+ }
+
+ else if(iSampleThreads)
+ {
+ // process now thread stack list
+ TInt length = this->ProcessThreads();
+
+ if(length == 0)
+ {
+ this->iThreadsProcessing = ENothingToProcess;
+ // switch to collect chunk data
+ iSampleThreads = false;
+ }
+ return length;
+ }
+
+ // should not reach this point...
+ return 0;
+ }
+#endif
+
+inline TInt DMemSamplerImpl::GatherChunks()
+ {
+ // encode a process binary
+ name.Zero();
+
+ NKern::ThreadEnterCS(); // Prevent us from dying or suspending whilst holding a DMutex
+ DObjectCon& chunks = *Kern::Containers()[EChunk];
+ chunks.Wait(); // Obtain the container mutex so the list does get changed under us
+
+ this->iChunkCount = 0;
+ this->iNewChunkCount = 0;
+ this->iTotalMemoryOk = false;
+ TInt totalChunkCount(chunks.Count());
+ DChunk* c;
+
+ for(TInt i(0);i<totalChunkCount;i++)
+ {
+ c = (DChunk*)(chunks)[i];
+
+ LOGSTRING3("Processing chunk %d, tag: 0x%x",i,TAG(c));
+
+ if( (TAG(c) & 0x0000ffff) != PROFILER_CHUNK_MARK)
+ {
+ LOGSTRING4("Marking chunk %d/%d, old tag 0x%x",i,(totalChunkCount-1), TAG(c));
+ // this chunk has not been tagged yet
+ name.Zero();
+ c->TraceAppendName(name,false);
+ const TUint8* ptr = name.Ptr();
+
+ TAG(c) = (PROFILER_CHUNK_MARK);
+ this->heapChunkNamesToReport[iNewChunkCount] = c;
+ iNewChunkCount++;
+ }
+
+ // the chunk has been tagged, add heap chunks to the list
+ this->heapChunksToSample[this->iChunkCount] = c;
+ this->iChunkCount++;
+ LOGSTRING2("Added chunk %d to Chunks",i);
+ }
+
+ if(this->iChunkCount > 0 || this->iNewChunkCount > 0)
+ {
+ this->iChunksProcessing = EStartingToProcess;
+
+ // process the first sample
+ TInt length = this->ProcessChunks();
+
+ if(length == 0)
+ {
+ this->iChunksProcessing = ENothingToProcess;
+ }
+
+ chunks.Signal(); // Release the container mutex
+ NKern::ThreadLeaveCS(); // End of critical section
+ return length;
+ }
+
+ LOGTEXT("MemSamplerImpl::SampleImpl - Error, no threads");
+ chunks.Signal(); // Release the container mutex
+ NKern::ThreadLeaveCS(); // End of critical section
+ return 0;
+ }
+
+inline TInt DMemSamplerImpl::GatherThreads()
+ {
+ // The thread memory consumption
+
+ NKern::ThreadEnterCS(); // Prevent us from dying or suspending whilst holding a DMutex
+ DObjectCon& threads = *Kern::Containers()[EThread];
+ threads.Wait(); // Obtain the container mutex so the list does get changed under us
+
+ this->iThreadCount = 0;
+ this->iNewThreadCount = 0;
+ this->iTotalMemoryOk = false;
+
+ TInt totalThreadCount = threads.Count();
+
+ for(TInt i(0);i<totalThreadCount;i++)
+ {
+ DThread* t = (DThread*)(threads)[i];
+
+ LOGSTRING3("Processing thread %d, tag: 0x%x",i,TAG(t));
+
+ if( (TAG(t) & PROFILER_MEM_THREAD_MARK) == 0)
+ {
+ LOGSTRING4("Marking thread %d/%d, old tag 0x%x",i,(totalThreadCount-1), TAG(t));
+ // this thread's chunk has not been reported yet
+ this->threadNamesToReport[iNewThreadCount] = t;
+ iNewThreadCount++;
+ // tag the thread
+ TAG(t) |= PROFILER_MEM_THREAD_MARK;
+ }
+
+ // the chunk has been tagged, add heap chunks to the list
+ this->threadsToSample[this->iThreadCount] = t;
+ this->iThreadCount++;
+ LOGSTRING2("Added thread %d to threads to sample",i);
+ }
+
+ if(this->iThreadCount > 0 || this->iNewThreadCount > 0)
+ {
+ this->iThreadsProcessing = EStartingToProcess;
+
+ // process the first sample
+ TInt length = this->ProcessThreads();
+
+ if(length == 0)
+ {
+ this->iThreadsProcessing = ENothingToProcess;
+ }
+ threads.Signal(); // Release the container mutex
+ NKern::ThreadLeaveCS(); // End of critical section
+ return length;
+ }
+
+ LOGTEXT("MemSamplerImpl::SampleImpl - Error, no threads");
+ threads.Signal(); // Release the container mutex
+ NKern::ThreadLeaveCS(); // End of critical section
+ return 0;
+ }
+
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+
+inline TInt DMemSamplerImpl::GatherLibraries()
+ {
+ LOGTEXT("MemSamplerImpl::GatherLibraries() - entry");
+ // encode a process binary
+ name.Zero();
+
+ NKern::ThreadEnterCS(); // Prevent us from dying or suspending whilst holding a DMutex
+ DObjectCon& libs = *Kern::Containers()[ELibrary];
+ libs.Wait(); // Obtain the container mutex so the list does get changed under us
+
+ this->iLibraryCount = 0;
+ this->iNewLibraryCount = 0;
+ this->iTotalMemoryOk = false;
+ TInt totalLibCount(libs.Count());
+ DLibrary* l;
+
+ for(TInt i(0);i<totalLibCount;i++)
+ {
+ l = (DLibrary*)(libs)[i];
+
+ LOGSTRING3("Processing library %d, tag: 0x%x",i,TAG(l));
+
+ if( (TAG(l) & 0xffffffff) != PROFILER_LIBRARY_MARK)
+ {
+ LOGSTRING4("Marking library %d/%d, old tag 0x%x",i,(totalLibCount-1), TAG(l));
+ // this library has not been tagged yet
+ name.Zero();
+ l->TraceAppendName(name,false);
+ const TUint8* ptr = name.Ptr();
+
+ TAG(l) = (PROFILER_LIBRARY_MARK);
+ this->libraryNamesToReport[iNewLibraryCount] = l;
+ iNewLibraryCount++;
+ }
+
+ // the library has been tagged, add library to the list
+ this->librariesToSample[this->iLibraryCount] = l;
+ this->iLibraryCount++;
+ LOGSTRING2("Added library %d to Libraries",i);
+ }
+
+ if(this->iLibraryCount > 0 || this->iNewLibraryCount > 0)
+ {
+ this->iLibrariesProcessing = EStartingToProcess;
+
+ // process the first sample
+ TInt length = this->ProcessLibraries();
+
+ if(length == 0)
+ {
+ this->iLibrariesProcessing = ENothingToProcess;
+ }
+
+ libs.Signal(); // Release the container mutex
+ NKern::ThreadLeaveCS(); // End of critical section
+ return length;
+ }
+
+ LOGTEXT("MemSamplerImpl::SampleImpl - Error, no libraries");
+ libs.Signal(); // Release the container mutex
+ NKern::ThreadLeaveCS(); // End of critical section
+ return 0;
+ }
+#endif
+
+inline TInt DMemSamplerImpl::ProcessChunks()
+ {
+ if(iNewChunkCount > 0)
+ {
+ if(this->iChunksProcessing == EStartingToProcess)
+ {
+ // this is the first sample, encode a code for names
+ this->iChunksProcessing = EProcessingNames;
+ return EncodeNameCode();
+ }
+
+ if(iTotalMemoryNameOk == false)
+ {
+ return EncodeTotalMemoryName();
+ }
+
+ // there are new chunk names to report
+ iNewChunkCount--;
+ DChunk* c = this->heapChunkNamesToReport[iNewChunkCount];
+ return EncodeChunkName(*c);
+
+ }
+ else if(iChunkCount > 0)
+ {
+ if(this->iChunksProcessing == EProcessingNames || this->iChunksProcessing == EStartingToProcess)
+ {
+ // this is the first data sample, encode a code for data
+ this->iChunksProcessing = EProcessingData;
+ return EncodeDataCode();
+ }
+
+ if(this->iTotalMemoryOk == false)
+ {
+ return EncodeTotalMemory();
+ }
+
+ // there are no new chunks to report
+ // thus generate the real report
+ iChunkCount--;
+ DChunk* c = this->heapChunksToSample[iChunkCount];
+ return EncodeChunkData(*c);
+ }
+ else
+ {
+ // everything is processed
+ LOGSTRING2(" Chunks processed! Chunk count = %d", iChunkCount);
+#ifdef MEM_EVENT_HANDLER
+ this->iChunksGathered = true;
+ Kern::Printf("MemSamplerImpl::ProcessChunks() - chunks gathered! Time: %d",iCount);
+#endif
+ return 0;
+ }
+ }
+
+inline TInt DMemSamplerImpl::ProcessThreads()
+ {
+
+ if(iNewThreadCount > 0)
+ {
+ if(this->iThreadsProcessing == EStartingToProcess)
+ {
+ // this is the first sample, encode a code for names
+ this->iThreadsProcessing = EProcessingNames;
+ return EncodeNameCode();
+ }
+
+ if(iTotalMemoryNameOk == false)
+ {
+ return EncodeTotalMemoryName();
+ }
+
+ iNewThreadCount--;
+ DThread* t = this->threadNamesToReport[iNewThreadCount];
+ return EncodeChunkName(*t);
+ }
+ else if(iThreadCount > 0)
+ {
+ if(this->iThreadsProcessing == EProcessingNames || this->iThreadsProcessing == EStartingToProcess)
+ {
+ // this is the first data sample, encode a code for data
+ this->iThreadsProcessing = EProcessingData;
+ return EncodeDataCode();
+ }
+
+ if(this->iTotalMemoryOk == false)
+ {
+ return EncodeTotalMemory();
+ }
+
+ // there are no new threads to report
+ // thus generate the real report
+ iThreadCount--;
+ DThread* t = this->threadsToSample[iThreadCount];
+ return EncodeChunkData(*t);
+ }
+ else
+ {
+ // everything is processed
+ LOGSTRING2(" Threads processed! Thread count = %d", iThreadCount);
+#ifdef MEM_EVENT_HANDLER
+ this->iThreadsGathered = true;
+ Kern::Printf("MemSamplerImpl::ProcessThreads() - threads gathered! Time: %d", iCount);
+#endif
+ return 0;
+ }
+ }
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+inline TInt DMemSamplerImpl::ProcessLibraries()
+ {
+ LOGTEXT("ProcessLibraries - entry");
+ if(iNewLibraryCount > 0)
+ {
+ if(this->iLibrariesProcessing == EStartingToProcess)
+ {
+ // this is the first sample, encode a code for names
+ this->iLibrariesProcessing = EProcessingNames;
+ return EncodeNameCode();
+ }
+
+ if(iTotalMemoryNameOk == false)
+ {
+ return EncodeTotalMemoryName();
+ }
+
+ // there are new library names to report
+ iNewLibraryCount--;
+ DLibrary* l = this->libraryNamesToReport[iNewLibraryCount];
+ return EncodeChunkName(*l);
+
+ }
+ else if(iLibraryCount > 0)
+ {
+ if(this->iLibrariesProcessing == EProcessingNames || this->iLibrariesProcessing == EStartingToProcess)
+ {
+ // this is the first data sample, encode a code for data
+ this->iLibrariesProcessing = EProcessingData;
+ return EncodeDataCode();
+ }
+
+ if(this->iTotalMemoryOk == false)
+ {
+ return EncodeTotalMemory();
+ }
+
+ // there are no new libraries to report
+ // thus generate the real report
+ iLibraryCount--;
+ DLibrary* l = this->librariesToSample[iLibraryCount];
+ return EncodeChunkData(*l);
+ }
+ else
+ {
+ // everything is processed
+ LOGSTRING2(" Libraries processed! Library count = %d", iLibraryCount);
+
+ this->iLibrariesGathered = true;
+ Kern::Printf("MemSamplerImpl::ProcessLibraries() - libraries gathered! Time: %d",iCount);
+
+ return 0;
+ }
+ }
+#endif
+inline TInt DMemSamplerImpl::EncodeNameCode()
+ {
+ sample[0] = 1;
+ sample[1] = 0xaa;
+ return 2;
+ }
+
+inline TInt DMemSamplerImpl::EncodeDataCode()
+ {
+ sample[0] = 1;
+ sample[1] = 0xdd;
+ return 2;
+ }
+
+inline TInt DMemSamplerImpl::EncodeTotalMemoryName()
+ {
+ this->iTotalMemoryNameOk = true;
+
+ TUint8* size = &sample[0];
+ *size = 0;
+
+ // encode name
+ this->sampleDescriptor.Zero();
+ this->sampleDescriptor.Append(_L("TOTAL_MEMORY"));
+ *size += this->sampleDescriptor.Size();
+
+ // add id here
+ TUint32 id(0xbabbeaaa);
+ this->sampleDescriptor.Append((TUint8*)&(id),sizeof(TUint32));
+ *size += sizeof(TUint32);
+
+ // the size is the descriptor length + the size field
+ return ((TInt)(*size))+1;
+ }
+
+inline TInt DMemSamplerImpl::EncodeTotalMemory()
+ {
+
+ TUint8* size = &sample[0];
+ *size = 0;
+
+ NKern::LockSystem();
+ TInt freeRam = Kern::FreeRamInBytes();
+ TInt totalRam = Kern::SuperPage().iTotalRamSize;
+ NKern::UnlockSystem();
+
+ this->sampleDescriptor.Zero();
+
+ TUint32 id(0xbabbeaaa);
+ TInt zero(0);
+
+ this->sampleDescriptor.Append((TUint8*)&(id),sizeof(TUint32));
+ *size += sizeof(TUint);
+
+ this->sampleDescriptor.Append((TUint8*)&(totalRam),sizeof(TInt));
+ *size += sizeof(TInt);
+
+ // append the cell amount allocated
+ this->sampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt));
+ *size += sizeof(TInt);
+
+ // append the chunk size
+ this->sampleDescriptor.Append((TUint8*)&(freeRam),sizeof(TInt));
+ *size += sizeof(TInt);
+
+ // append the thread user stack size
+ this->sampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt));
+ *size += sizeof(TInt);
+
+ this->iTotalMemoryOk = true;
+
+ return ((TInt)(*size))+1;
+ }
+
+inline TInt DMemSamplerImpl::EncodeChunkName(DChunk& c)
+ {
+ // the size of the following name is in the first byte
+ TUint8* size = &sample[0];
+ *size = 0;
+
+ // encode chunk name
+ this->sampleDescriptor.Zero();
+ this->sampleDescriptor.Append(_L("C_"));
+ c.TraceAppendFullName(this->sampleDescriptor,false);
+ *size += this->sampleDescriptor.Size();
+
+ // add chunk object address here
+ TUint32 chunkAddr((TUint32)&c);
+ this->sampleDescriptor.Append((TUint8*)&(chunkAddr),sizeof(TUint32));
+ *size += sizeof(TUint32);
+
+ // the size is the descriptor length + the size field
+ LOGSTRING2("Non-Heap Chunk Name - %d",*size);
+ return ((TInt)(*size))+1;
+ }
+
+inline TInt DMemSamplerImpl::EncodeChunkName(DThread& t)
+ {
+ // the size of the following name is in the first byte
+ TUint8* size = &sample[0];
+ *size = 0;
+ this->sampleDescriptor.Zero();
+
+ this->sampleDescriptor.Append(_L("T_"));
+ t.TraceAppendFullName(this->sampleDescriptor,false);
+ *size += this->sampleDescriptor.Size();
+
+ // copy the 4 bytes from the thread id field
+ this->sampleDescriptor.Append((TUint8*)&(t.iId),sizeof(TUint));
+ *size += sizeof(TUint);
+
+ // the size is the descriptor length + the size field
+ LOGSTRING2("Name - %d",*size);
+ return ((TInt)(*size))+1;
+ }
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+inline TInt DMemSamplerImpl::EncodeChunkName(DLibrary& l)
+ {
+ // the size of the following name is in the first byte
+ TUint8* size = &sample[0];
+ *size = 0;
+
+ // encode library name
+ this->sampleDescriptor.Zero();
+ this->sampleDescriptor.Append(_L("L_"));
+ l.TraceAppendFullName(this->sampleDescriptor,false);
+ *size += this->sampleDescriptor.Size();
+
+ // add chunk object address here
+ TUint32 libAddr((TUint32)&l);
+ this->sampleDescriptor.Append((TUint8*)&(libAddr),sizeof(TUint32));
+ *size += sizeof(TUint32);
+
+ // the size is the descriptor length + the size field
+ LOGSTRING2("Name - %d",*size);
+ return ((TInt)(*size))+1;
+ }
+#endif
+inline TInt DMemSamplerImpl::EncodeChunkData(DChunk& c)
+ {
+ // the size of the following name is in the first byte
+ TUint8* size = &sample[0];
+ *size = 0;
+ this->sampleDescriptor.Zero();
+ TInt zero(0);
+
+ TUint32 address((TUint32)&c);
+
+ this->sampleDescriptor.Append((TUint8*)&address,sizeof(TUint32));
+ *size += sizeof(TUint);
+
+ // copy the total amount of memory allocated
+ this->sampleDescriptor.Append((TUint8*)&(c.iSize),sizeof(TInt));
+ *size += sizeof(TInt);
+
+ // append the cell amount allocated
+ this->sampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt));
+ *size += sizeof(TInt);
+
+ // append the chunk size
+ this->sampleDescriptor.Append((TUint8*)&(c.iSize),sizeof(TUint));
+ *size += sizeof(TUint);
+
+ // append the thread user stack size
+ this->sampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt));
+ *size += sizeof(TInt);
+
+ LOGSTRING2("Data - %d",*size);
+ return ((TInt)(*size))+1;
+
+ }
+
+inline TInt DMemSamplerImpl::EncodeChunkData(DThread& t)
+ {
+ LOGTEXT("MemSamplerImpl::EncodeChunkData - entry");
+ //LOGSTRING2("MemSamplerImpl::EncodeChunkData - processing thread 0x%x ",&t);
+
+ // the size of the following name is in the first byte
+ TUint8* size = &sample[0];
+ *size = 0;
+ this->sampleDescriptor.Zero();
+
+ LOGTEXT("MemSamplerImpl::EncodeChunkData - cleared");
+
+ this->sampleDescriptor.Append((TUint8*)&(t.iId),sizeof(TUint));
+ *size += sizeof(TUint);
+
+ // copy the total amount of memory allocated for user side stack
+ this->sampleDescriptor.Append((TUint8*)&(t.iUserStackSize),sizeof(TInt));
+ *size += sizeof(TInt);
+
+ TInt zero(0);
+ // append the cell amount allocated (zero, not in use here)
+ this->sampleDescriptor.Append((TUint8*)&zero,sizeof(TInt));
+ *size += sizeof(TInt);
+
+ // append the chunk size (this is not a chunk)
+ this->sampleDescriptor.Append((TUint8*)&(zero),sizeof(TUint));
+ *size += sizeof(TUint);
+
+ // append user stack (max) size
+ this->sampleDescriptor.Append((TUint8*)&(t.iUserStackSize),sizeof(TInt));
+ *size += sizeof(TInt);
+
+ LOGSTRING2("Data -> %d",*size);
+ return ((TInt)(*size))+1;
+ }
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+inline TInt DMemSamplerImpl::EncodeChunkData(DLibrary& l)
+ {
+ LOGTEXT("MemSamplerImpl::EncodeChunkData (Library) - entry");
+ // the size of the following name is in the first byte
+ TUint8* size = &sample[0];
+ *size = 0;
+ this->sampleDescriptor.Zero();
+
+ TUint32 address((TUint32)&l);
+
+ this->sampleDescriptor.Append((TUint8*)&address,sizeof(TUint32));
+ *size += sizeof(TUint);
+
+ this->sampleDescriptor.Append((TUint8*)&(l.iCodeSeg->iSize),sizeof(TUint32));
+ *size += sizeof(TInt);
+
+ this->sampleDescriptor.Append((TUint8*)&(l.iMapCount),sizeof(TInt));
+ *size += sizeof(TInt);
+
+ TInt zero(0);
+ this->sampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt));
+ *size += sizeof(TInt);
+
+ this->sampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt));
+ *size += sizeof(TInt);
+
+ LOGSTRING2("LData - %d",*size);
+ return ((TInt)(*size))+1;
+
+ }
+#endif
+void DMemSamplerImpl::Reset()
+ {
+ Kern::Printf("MemSamplerImpl::Reset");
+ iCount = 0; // sample threads 1 cycle after actual MEM sample time...
+ this->iTimeToSample = false;
+ this->iChunkCount = 0;
+ this->iNewChunkCount = 0;
+
+ this->iTotalMemoryOk = false;
+ this->iTotalMemoryNameOk = false;
+
+ this->iChunksProcessing = ENothingToProcess;
+ this->iThreadsProcessing = ENothingToProcess;
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+ this->iLibrariesProcessing = ENothingToProcess;
+ this->iSampleType = ESampleThreads;
+#else
+ this->iSampleThreads = true;
+#endif
+
+ this->sampleDescriptor.Zero();
+
+ // clear all chunk tags
+ NKern::ThreadEnterCS(); // Prevent us from dying or suspending whilst holding a DMutex
+ DObjectCon* chunks = Kern::Containers()[EChunk];
+ chunks->Wait(); // Obtain the container mutex so the list does get changed under us
+
+ TInt totalChunkCount = chunks->Count();
+ for(TInt i=0;i<totalChunkCount;i++)
+ {
+ DChunk* c = (DChunk*)(*chunks)[i];
+ TAG(c) = 0;
+ }
+ chunks->Signal(); // Release the container mutex
+
+ Kern::Printf("MemSamplerImpl::Reset");
+ this->iThreadCount = 0;
+ this->iNewThreadCount = 0;
+ this->sampleDescriptor.Zero();
+
+ // clear all chunk tags
+ DObjectCon* threads = Kern::Containers()[EThread];
+ threads->Wait(); // Obtain the container mutex so the list does get changed under us
+
+ TInt totalThreadCount = threads->Count();
+ for(TInt i=0;i<totalThreadCount;i++)
+ {
+ DThread* t = (DThread*)(*threads)[i];
+ TAG(t) = (TAG(t) & 0xfffffffe);
+ }
+ threads->Signal(); // Release the container mutex
+
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+ this->iLibraryCount = 0;
+ this->iNewLibraryCount = 0;
+ this->sampleDescriptor.Zero();
+
+ // clear all library tags
+ DObjectCon* libs = Kern::Containers()[ELibrary];
+ libs->Wait(); // Obtain the container mutex so the list does get changed under us
+
+ TInt totalLibraryCount = libs->Count();
+ for(TInt i=0; i<totalLibraryCount; i++)
+ {
+ DLibrary* l = (DLibrary*)(*libs)[i];
+ TAG(l) = (TAG(l) & 0xefffffff);
+ }
+ libs->Signal(); // Release the container mutex
+#endif
+
+ NKern::ThreadLeaveCS(); // End of critical section
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/src/MemoryEventHandler.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,724 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include <e32def.h>
+#include <e32cmn.h>
+#include <arm.h>
+#include <kernel.h>
+#include <kern_priv.h>
+#include <nk_trace.h>
+
+#include "MemoryEventHandler.h"
+
+
+DMemoryEventHandler::DMemoryEventHandler(DProfilerSampleBuffer* aSampleBuffer)
+ : DKernelEventHandler(EventHandler, this),
+ iSampleBuffer(aSampleBuffer),
+ iSampleDescriptor(&(this->iSample[1]),0,256)
+ {
+// Kern::Printf("DMemoryEventHandler::DMemoryEventHandler()");
+ iCount = 0;
+ iPreviousCount = 0;
+ }
+
+
+TInt DMemoryEventHandler::Create()
+ {
+// Kern::Printf("DMemoryEventHandler::Create()");
+
+ TInt err(Kern::MutexCreate(iLock, _L("MemoryEventHandlerLock"), KMutexOrdGeneral0));
+ if (err != KErrNone)
+ return err;
+
+ return Add();
+ }
+
+
+DMemoryEventHandler::~DMemoryEventHandler()
+ {
+// Kern::Printf("DMemoryEventHandler::~DMemoryEventHandler()");
+
+ if (iLock)
+ iLock->Close(NULL);
+
+ }
+
+
+TInt DMemoryEventHandler::Start()
+ {
+// Kern::Printf("DMemoryEventHandler::Start()");
+
+ iTracking = ETrue;
+ return KErrNone;
+ }
+
+
+TInt DMemoryEventHandler::Stop()
+ {
+// Kern::Printf("DMemoryEventHandler::Stop()");
+
+ iTracking = EFalse;
+ return KErrNone;
+ }
+
+TBool DMemoryEventHandler::SampleNeeded()
+ {
+ LOGTEXT("DMemoryEventHandler::SampleNeeded()");
+
+ // increase the coutner by one on each round
+ iCount++;
+
+ // check if event handler was not running
+// if(!iTracking)
+// return false; // return false
+
+ return true;
+ }
+
+
+TUint DMemoryEventHandler::EventHandler(TKernelEvent aType, TAny* a1, TAny* a2, TAny* aThis)
+ {
+ return ((DMemoryEventHandler*)aThis)->HandleEvent(aType, a1, a2);
+ }
+
+
+
+TUint DMemoryEventHandler::HandleEvent(TKernelEvent aType, TAny* a1, TAny* a2)
+ {
+ // debug
+// Kern::Printf("New kernel event received, %d", aType);
+
+ if (iTracking/* && iCount != iPreviousCount*/)
+ {
+// iPreviousCount = iCount;
+ iCounters[aType]++;
+ switch (aType)
+ {
+ // capture only chunk creation, updates and destroyal
+ case EEventNewChunk:
+ {
+ DChunk* chunk = (DChunk*)a1;
+ HandleAddChunk(chunk);
+ break;
+ }
+ case EEventUpdateChunk:
+ HandleUpdateChunk((DChunk*)a1);
+ break;
+ case EEventDeleteChunk:
+ HandleDeleteChunk((DChunk*)a1);
+ break;
+// case EEventAddProcess:
+// Kern::Printf("Process added: 0x%08x", (DProcess*)a1);
+// break;
+// case EEventUpdateProcess:
+// Kern::Printf("DProcess updated: 0x%08x", (DProcess*)a1);
+// break;
+// case EEventRemoveProcess:
+// Kern::Printf("DProcess removed: 0x%08x", (DProcess*)a1);
+// break;
+// case EEventAddCodeSeg:
+// Kern::Printf("DCodeSeg added: 0x%08x", (DCodeSeg*)a1);
+// break;
+// case EEventRemoveCodeSeg:
+// Kern::Printf("DCodeSeg deleted: 0x%08x", (DCodeSeg*)a1);
+// break;
+ case EEventAddThread:
+ HandleAddThread((DThread*)a1);
+ break;
+ case EEventUpdateThread: // thread renaming
+ HandleUpdateThread((DThread*)a1);
+ break;
+// case EEventKillThread:
+ case EEventRemoveThread:
+ HandleDeleteThread((DThread*)a1);
+ break;
+#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
+ case EEventAddLibrary:
+ HandleAddLibrary((DLibrary*)a1, (DThread*)a2);
+ break;
+ case EEventRemoveLibrary:
+ HandleDeleteLibrary((DLibrary*)a1);
+ break;
+#endif
+
+ // ignore exception events
+ case EEventSwExc:
+ case EEventHwExc:
+
+ default:
+ break;
+ }
+ }
+// else if(iTracking && iCount == iPreviousCount)
+// {
+// // if time stamp is not updated profiling has stopped
+// Stop();
+// }
+ return DKernelEventHandler::ERunNext;
+ }
+
+TInt DMemoryEventHandler::EncodeNameCode()
+ {
+ iSample[0] = 1;
+ iSample[1] = 0xaa;
+ return 2;
+ }
+
+// encode mark for new chunk or thread
+TInt DMemoryEventHandler::EncodeNewCode()
+ {
+ iSample[0] = 1;
+ iSample[1] = 0xda;
+ return 2;
+ }
+
+// encode mark for update of chunk or thread
+TInt DMemoryEventHandler::EncodeUpdateCode()
+ {
+ iSample[0] = 1;
+ iSample[1] = 0xdb;
+ return 2;
+ }
+
+// encode mark for removal of chunk or thread
+TInt DMemoryEventHandler::EncodeRemoveCode()
+ {
+ iSample[0] = 1;
+ iSample[1] = 0xdc;
+ return 2;
+ }
+
+// encode the memory sample header in all memory changes
+TInt DMemoryEventHandler::AddHeader()
+ {
+ TInt err(KErrNone);
+
+ TUint8 number(4); // mem sampler id
+
+ // check if iCount bigger than previous, i.e. at least 1 ms has passed from the previous sample
+ if(iCount > iPreviousCount)
+ {
+ err = this->iSampleBuffer->AddSample(&number,1);
+ err = this->iSampleBuffer->AddSample((TUint8*)&(iCount),4);
+
+ // add data chunk header
+ TInt length(EncodeUpdateCode());
+ err = iSampleBuffer->AddSample(iSample, length);
+
+ // add total memory sample in the beginning of each sample
+ length = EncodeTotalMemory();
+ err = iSampleBuffer->AddSample(iSample, length);
+ AddFooter(); // end mark for total memory sample
+ }
+ iPreviousCount = iCount;
+
+ // add actual sample
+ err = this->iSampleBuffer->AddSample(&number,1);
+ err = this->iSampleBuffer->AddSample((TUint8*)&(iCount),4);
+
+ return err;
+ }
+
+// encode the memory sample header in all memory changes
+TInt DMemoryEventHandler::AddFooter()
+ {
+ TInt err(KErrNone);
+
+ TUint8 number(0); // end mark
+ err = this->iSampleBuffer->AddSample(&number,1);
+
+ return err;
+ }
+
+TInt DMemoryEventHandler::EncodeTotalMemory()
+ {
+
+ TUint8* size(&iSample[0]);
+ *size = 0;
+
+ NKern::LockSystem();
+ TInt freeRam(Kern::FreeRamInBytes());
+ TInt totalRam(Kern::SuperPage().iTotalRamSize);
+ NKern::UnlockSystem();
+
+ iSampleDescriptor.Zero();
+
+ TUint32 id(0xbabbeaaa);
+ TInt zero(0);
+
+ iSampleDescriptor.Append((TUint8*)&(id),sizeof(TUint32));
+ *size += sizeof(TUint);
+
+ iSampleDescriptor.Append((TUint8*)&(totalRam),sizeof(TInt));
+ *size += sizeof(TInt);
+
+ // append the cell amount allocated
+ iSampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt));
+ *size += sizeof(TInt);
+
+ // append the chunk size
+ iSampleDescriptor.Append((TUint8*)&(freeRam),sizeof(TInt));
+ *size += sizeof(TInt);
+
+ // append the thread user stack size
+ iSampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt));
+ *size += sizeof(TInt);
+
+ return ((TInt)(*size))+1;
+ }
+
+// handle chunk activity
+TBool DMemoryEventHandler::HandleAddChunk(DChunk* aChunk)
+ {
+// Kern::Printf("New DChunk created: 0x%08x, time: %d", aChunk, iCount);
+
+ NKern::ThreadEnterCS();
+ Kern::MutexWait(*iLock);
+ // add header first
+ TInt err(AddHeader());
+
+ if(err != KErrNone)
+ {
+ return EFalse;
+ }
+
+ // new chunk, add name of it
+ TInt length(EncodeNameCode());
+ iSampleBuffer->AddSample(iSample, length);
+
+ // new chunk, add name of it
+ length = EncodeChunkName(*aChunk);
+ iSampleBuffer->AddSample(iSample, length);
+
+ // add new chunk tag
+ length = EncodeNewCode();
+ iSampleBuffer->AddSample(iSample, length);
+
+ length = EncodeChunkData(*aChunk);
+ iSampleBuffer->AddSample(iSample, length);
+
+ // add end mark
+ AddFooter();
+ Kern::MutexSignal(*iLock);
+ NKern::ThreadLeaveCS();
+ return ETrue;
+ }
+
+TBool DMemoryEventHandler::HandleUpdateChunk(DChunk* aChunk)
+ {
+// Kern::Printf("DChunk updated: 0x%08x, time: %d", aChunk, iCount);
+
+ NKern::ThreadEnterCS();
+ Kern::MutexWait(*iLock);
+ // add header first
+ TInt err(AddHeader());
+
+ if(err != KErrNone)
+ {
+ return EFalse;
+ }
+
+ // add new chunk tag
+ TInt length(EncodeUpdateCode());
+ iSampleBuffer->AddSample(iSample, length);
+
+ length = EncodeChunkData(*aChunk);
+ iSampleBuffer->AddSample(iSample, length);
+
+ // add end mark
+ AddFooter();
+ Kern::MutexSignal(*iLock);
+ NKern::ThreadLeaveCS();
+ return ETrue;
+ }
+
+TBool DMemoryEventHandler::HandleDeleteChunk(DChunk* aChunk)
+ {
+// Kern::Printf("DChunk deleted: 0x%08x, time: %d", aChunk, iCount);
+ NKern::ThreadEnterCS();
+ Kern::MutexWait(*iLock);
+ // add header first
+ TInt err(AddHeader());
+
+ if(err != KErrNone)
+ {
+ return EFalse;
+ }
+
+ // add new chunk tag
+ TInt length(EncodeRemoveCode());
+ iSampleBuffer->AddSample(iSample, length);
+
+ length = EncodeChunkData(*aChunk);
+ iSampleBuffer->AddSample(iSample, length);
+
+ // add end mark
+ AddFooter();
+ Kern::MutexSignal(*iLock);
+ NKern::ThreadLeaveCS();
+ return ETrue;
+ }
+
+// handle process activity
+TBool DMemoryEventHandler::HandleAddProcess(DProcess *aProcess)
+ {
+ return ETrue;
+ }
+
+TBool DMemoryEventHandler::HandleUpdateProcess(DProcess *aProcess)
+ {
+ return ETrue;
+ }
+
+TBool DMemoryEventHandler::HandleDeleteProcess(DProcess *aProcess)
+ {
+ return ETrue;
+ }
+
+// handle thread activity
+TBool DMemoryEventHandler::HandleAddThread(DThread* aThread)
+ {
+// Kern::Printf("DThread added: 0x%08x, time: %d", aThread->iId, iCount);
+ NKern::ThreadEnterCS();
+ Kern::MutexWait(*iLock);
+ // add header first
+ TInt err(AddHeader());
+
+ if(err != KErrNone)
+ {
+ return EFalse;
+ }
+
+ // new thread, add name of it
+ TInt length(EncodeNameCode());
+ iSampleBuffer->AddSample(iSample, length);
+
+ // new chunk, add name of it
+ length = EncodeChunkName(*aThread);
+ iSampleBuffer->AddSample(iSample, length);
+
+ // add new chunk tag
+ length = EncodeNewCode();
+ iSampleBuffer->AddSample(iSample, length);
+
+ length = EncodeChunkData(*aThread);
+ iSampleBuffer->AddSample(iSample, length);
+
+ // add end mark
+ AddFooter();
+ Kern::MutexSignal(*iLock);
+ NKern::ThreadLeaveCS();
+ return ETrue;
+ }
+
+TBool DMemoryEventHandler::HandleUpdateThread(DThread* aThread)
+ {
+// Kern::Printf("DThread updated: 0x%08x, time: %d", aThread->iId, iCount);
+ NKern::ThreadEnterCS();
+ Kern::MutexWait(*iLock);
+ // add header first
+ TInt err(AddHeader());
+
+ if(err != KErrNone)
+ {
+ return EFalse;
+ }
+
+ // add new chunk tag
+ TInt length(EncodeUpdateCode());
+ iSampleBuffer->AddSample(iSample, length);
+
+ length = EncodeChunkData(*aThread);
+ iSampleBuffer->AddSample(iSample, length);
+
+ // add end mark
+ AddFooter();
+ Kern::MutexSignal(*iLock);
+ NKern::ThreadLeaveCS();
+ return ETrue;
+ }
+
+TBool DMemoryEventHandler::HandleDeleteThread(DThread* aThread)
+ {
+// Kern::Printf("DThread deleted: 0x%08x, time: %d", aThread->iId, iCount);
+ NKern::ThreadEnterCS();
+ Kern::MutexWait(*iLock);
+ // add header first
+ TInt err(AddHeader());
+
+ if(err != KErrNone)
+ {
+ return EFalse;
+ }
+
+ // add new chunk tag
+ TInt length(EncodeRemoveCode());
+ iSampleBuffer->AddSample(iSample, length);
+
+ length = EncodeChunkData(*aThread);
+ iSampleBuffer->AddSample(iSample, length);
+
+ // add end mark
+ AddFooter();
+ Kern::MutexSignal(*iLock);
+ NKern::ThreadLeaveCS();
+ return ETrue;
+ }
+
+TBool DMemoryEventHandler::HandleAddLibrary(DLibrary* aLibrary, DThread* aThread)
+ {
+ LOGTEXT("DMemoryEventHandler::HandleAddLibrary");
+ Kern::Printf("DLibrary added: 0x%08x, time: %d", aLibrary, iCount);
+ // add header first
+ NKern::ThreadEnterCS();
+ Kern::MutexWait(*iLock);
+ TInt err(AddHeader());
+
+ if(err != KErrNone)
+ {
+ return EFalse;
+ }
+
+ // new library, add name of it
+ TInt length(EncodeNameCode());
+ iSampleBuffer->AddSample(iSample, length);
+
+ // new chunk, add name of it
+ length = EncodeChunkName(*aLibrary);
+ iSampleBuffer->AddSample(iSample, length);
+
+ // add new chunk tag
+ length = EncodeNewCode();
+ iSampleBuffer->AddSample(iSample, length);
+
+ length = EncodeChunkData(*aLibrary, *aThread);
+ iSampleBuffer->AddSample(iSample, length);
+
+ // add end mark
+ AddFooter();
+ Kern::MutexSignal(*iLock);
+ NKern::ThreadLeaveCS();
+ return ETrue;
+ }
+
+TBool DMemoryEventHandler::HandleDeleteLibrary(DLibrary* aLibrary)
+ {
+ Kern::Printf("DLibrary deleted: 0x%08x, time: %d", aLibrary, iCount);
+ NKern::ThreadEnterCS();
+ Kern::MutexWait(*iLock);
+ // add header first
+ TInt err(AddHeader());
+
+ if(err != KErrNone)
+ {
+ return EFalse;
+ }
+
+ // add new chunk tag
+ TInt length(EncodeRemoveCode());
+ iSampleBuffer->AddSample(iSample, length);
+
+ DThread* nullPointer = NULL;
+ length = EncodeChunkData(*aLibrary, *nullPointer);
+ iSampleBuffer->AddSample(iSample, length);
+
+ // add end mark
+ AddFooter();
+ Kern::MutexSignal(*iLock);
+ NKern::ThreadLeaveCS();
+ return ETrue;
+ }
+
+// encode chunk name
+TInt DMemoryEventHandler::EncodeChunkName(DChunk& c)
+ {
+ // the size of the following name is in the first byte
+ TUint8* size(&iSample[0]);
+ *size = 0;
+
+ // encode chunk name
+ iSampleDescriptor.Zero();
+ iSampleDescriptor.Append(_L("C_"));
+ c.TraceAppendFullName(iSampleDescriptor,false);
+ *size += iSampleDescriptor.Size();
+
+ // add chunk object address here
+ TUint32 chunkAddr((TUint32)&c);
+ iSampleDescriptor.Append((TUint8*)&(chunkAddr),sizeof(TUint32));
+ *size += sizeof(TUint32);
+
+ // the size is the descriptor length + the size field
+ LOGSTRING2("Non-Heap Chunk Name - %d",*size);
+ return ((TInt)(*size))+1;
+ }
+
+// encode chunk name
+TInt DMemoryEventHandler::EncodeChunkName(DThread& t)
+ {
+ // the size of the following name is in the first byte
+ TUint8* size(&iSample[0]);
+ *size = 0;
+ iSampleDescriptor.Zero();
+
+ iSampleDescriptor.Append(_L("T_"));
+ t.TraceAppendFullName(iSampleDescriptor,false);
+ *size += iSampleDescriptor.Size();
+
+ // copy the 4 bytes from the thread id field
+ iSampleDescriptor.Append((TUint8*)&(t.iId),sizeof(TUint));
+ *size += sizeof(TUint);
+
+ // the size is the descriptor length + the size field
+ LOGSTRING2("Name - %d",*size);
+ return ((TInt)(*size))+1;
+ }
+
+// encode chunk name
+TInt DMemoryEventHandler::EncodeChunkName(DLibrary& l)
+ {
+ LOGTEXT("DMemoryEventHandler::EncodeChunkName (LIBRARY)");
+ // the size of the following name is in the first byte
+ TUint8* size(&iSample[0]);
+ *size = 0;
+ iSampleDescriptor.Zero();
+
+ iSampleDescriptor.Append(_L("L_"));
+ l.TraceAppendFullName(iSampleDescriptor,false);
+ *size += iSampleDescriptor.Size();
+
+ // copy the library address here
+ TUint32 libAddr((TUint32)&l);
+ iSampleDescriptor.Append((TUint8*) &libAddr,sizeof(TUint32));
+ *size += sizeof(TUint32);
+
+ // the size is the descriptor length + the size field
+ LOGSTRING2("Name - %d",*size);
+ return ((TInt)(*size))+1;
+ }
+
+// record thread stack changes
+TInt DMemoryEventHandler::EncodeChunkData(DThread& t)
+ {
+ LOGSTRING("DMemoryEventHandler::EncodeChunkDataT - entry");
+
+ // the size of the following name is in the first byte
+ TUint8* size(&iSample[0]);
+ *size = 0;
+ iSampleDescriptor.Zero();
+
+ iSampleDescriptor.Append((TUint8*)&(t.iId),sizeof(TUint));
+ *size += sizeof(TUint);
+
+ // copy the total amount of memory allocated for user side stack
+ iSampleDescriptor.Append((TUint8*)&(t.iUserStackSize),sizeof(TInt));
+ *size += sizeof(TInt);
+
+ TInt zero(0);
+ // append the cell amount allocated (zero, not in use here)
+ iSampleDescriptor.Append((TUint8*)&zero,sizeof(TInt));
+ *size += sizeof(TInt);
+
+ // append the chunk size (this is not a chunk)
+ iSampleDescriptor.Append((TUint8*)&(zero),sizeof(TUint));
+ *size += sizeof(TUint);
+
+ // append user stack (max) size
+ iSampleDescriptor.Append((TUint8*)&(t.iUserStackSize),sizeof(TInt));
+ *size += sizeof(TInt);
+
+// Kern::Printf("TData -> %d",*size);
+ return ((TInt)(*size))+1;
+ }
+
+// record chunk changes
+TInt DMemoryEventHandler::EncodeChunkData(DChunk& c)
+ {
+ LOGSTRING("DMemoryEventHandler::EncodeChunkDataC - entry");
+
+ // the size of the following name is in the first byte
+ TUint8* size(&iSample[0]);
+ *size = 0;
+ iSampleDescriptor.Zero();
+ TInt zero(0);
+
+ TUint32 address((TUint32)&c);
+
+ iSampleDescriptor.Append((TUint8*)&address,sizeof(TUint32));
+ *size += sizeof(TUint);
+
+ // copy the total amount of memory allocated
+ iSampleDescriptor.Append((TUint8*)&(c.iSize),sizeof(TInt));
+ *size += sizeof(TInt);
+
+ // append the cell amount allocated
+ iSampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt));
+ *size += sizeof(TInt);
+
+ // append the chunk size
+ iSampleDescriptor.Append((TUint8*)&(c.iSize),sizeof(TUint));
+ *size += sizeof(TUint);
+
+ // append the thread user stack size
+ iSampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt));
+ *size += sizeof(TInt);
+
+// Kern::Printf("CData - %d",*size);
+ return ((TInt)(*size))+1;
+ }
+
+// record loaded libraries changes
+TInt DMemoryEventHandler::EncodeChunkData(DLibrary& l, DThread& t)
+ {
+ LOGSTRING("DMemoryEventHandler::EncodeChunkDataL - entry");
+
+ // the size of the following name is in the first byte
+ TUint8* size(&iSample[0]);
+ *size = 0;
+ iSampleDescriptor.Zero();
+ TInt zero(0);
+
+ TUint32 address((TUint32)&l);
+
+ iSampleDescriptor.Append((TUint8*)&address,sizeof(TUint32));
+ *size += sizeof(TUint);
+
+ // append amount of memory that library is allocated
+ iSampleDescriptor.Append((TUint8*)&(l.iCodeSeg->iSize),sizeof(TUint32));
+ *size += sizeof(TInt);
+
+ // append count of how many times librarys is allocated
+ iSampleDescriptor.Append((TUint8*)&(l.iMapCount),sizeof(TInt));
+ *size += sizeof(TInt);
+
+ if(&t != NULL)
+ {
+ // created by thread
+ iSampleDescriptor.Append((TUint8*)&(t),sizeof(TUint32));
+ }
+ else
+ {
+ // removed
+ iSampleDescriptor.Append((TUint8*)&(zero),sizeof(TUint32));
+ }
+ *size += sizeof(TUint);
+
+ // append the thread user stack size
+ iSampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt));
+ *size += sizeof(TInt);
+ return ((TInt)(*size))+1;
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/src/PriSamplerImpl.cpp Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,312 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <piprofiler/ProfilerVersion.h>
+#include <piprofiler/ProfilerTraces.h>
+
+#include <kern_priv.h>
+#include <plat_priv.h>
+
+#include "PriSamplerImpl.h"
+
+#if !defined(__NKERN_H__)
+#include <nkern.h>
+#endif
+
+#define TAG(obj) (*(TUint32*)&(obj->iAsyncDeleteNext))
+#define PROFILER_THREAD_MARK ((TUint32)0x00000002)
+
+
+DPriSamplerImpl::DPriSamplerImpl() :
+ sampleDescriptor(&(this->sample[1]),0,256)
+ {
+ LOGTEXT("PriSamplerImpl::PriSamplerImpl() - konstruktori");
+
+ iCountti = 50; // sample threads 16 cycles before actual MEM and PRI sample time...
+ iNewThreadCount = 0;
+ iThreadCount = 0;
+ iProcessing = ENothingToProcess;
+
+ for(TInt i=0;i<KProfilerMaxThreadAmount;i++)
+ {
+ this->threadsToSample[i] = 0;
+ this->threadNamesToReport[i] = 0;
+ }
+
+ }
+
+DPriSamplerImpl::~DPriSamplerImpl()
+ {
+
+ }
+
+TInt DPriSamplerImpl::CreateFirstSample()
+ {
+ LOGTEXT("PriSamplerImpl::CreateFirstSample - entry");
+
+ this->sampleDescriptor.Zero();
+ this->sampleDescriptor.Append(_L8("Bappea_V"));
+ this->sampleDescriptor.Append(PROFILER_PRI_SAMPLER_VERSION);
+ this->sampleDescriptor.Append(_L8("_PRI"));
+
+ sample[0] = this->sampleDescriptor.Size();
+
+ LOGTEXT("PriSamplerImpl::CreateFirstSample - exit");
+
+ return (TInt)(sample[0]+1);
+ }
+
+TBool DPriSamplerImpl::SampleNeeded()
+ {
+ iCountti++;
+ if(iCountti % (iPriSamplingPeriod) == 0)
+ {
+ LOGTEXT("PriSamplerImpl::SampleNeeded - true");
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+
+TInt DPriSamplerImpl::SampleImpl()
+ {
+ /*
+ *
+ * EKA-2 implementation of PRI trace
+ *
+ */
+ if(this->iProcessing == ENothingToProcess)
+ {
+ if((iCountti % iPriSamplingPeriod) != 0 ) return 0;
+
+ LOGTEXT("Processing threads...");
+
+ DObjectCon& threads = *Kern::Containers()[EThread];
+
+ // PRI trace variables
+ this->iThreadCount = 0;
+ this->iNewThreadCount = 0;
+ TInt totalThreadCount = threads.Count();
+
+ for(TInt i=0;i<totalThreadCount;i++)
+ {
+ DThread* t = (DThread*)(threads)[i];
+ LOGSTRING3("Processing thread %d, tag: 0x%x",i,TAG(t));
+
+ if( (TAG(t) & PROFILER_THREAD_MARK) == 0)
+ {
+ LOGSTRING2("Marking thread %d",i);
+ // this thread's chunk has not been reported yet
+ this->threadNamesToReport[iNewThreadCount] = t;
+ iNewThreadCount++;
+ // tag the thread
+ TAG(t) |= PROFILER_THREAD_MARK;
+ LOGSTRING2("New Thread %d",i);
+ }
+ else
+ {
+ LOGSTRING3("Thread %d marked already - 0x%x",i,TAG(t));
+ }
+
+ // the thread has been tagged, add heap chunks to the list
+ this->threadsToSample[this->iThreadCount] = t;
+ this->iThreadCount++;
+ LOGSTRING2("Added thread %d to threads to sample",i);
+ }
+
+ if(this->iThreadCount > 0 || this->iNewThreadCount > 0)
+ {
+ this->iProcessing = EStartingToProcess;
+
+ // process the first sample
+ TInt length = this->ProcessChunks();
+
+ if(length == 0)
+ {
+ this->iProcessing = ENothingToProcess;
+ }
+
+ return length;
+ }
+ else
+ {
+ // there were no threads, should not take place
+ LOGTEXT("PriSamplerImpl::SampleImpl - Error, no threads");
+ return 0;
+ }
+ }
+ else
+ {
+ TInt length = this->ProcessChunks();
+ if(length == 0)
+ {
+ this->iProcessing = ENothingToProcess;
+ }
+ return length;
+ }
+ }
+
+inline TInt DPriSamplerImpl::ProcessChunks()
+ {
+ /*
+ *
+ * EKA-2 implementation of PRI trace
+ *
+ */
+
+ if(iNewThreadCount > 0)
+ {
+ if(this->iProcessing == EStartingToProcess)
+ {
+ // this is the first sample, encode a code for names
+ this->iProcessing = EProcessingNames;
+ return EncodeNameCode();
+ }
+
+ // there are new thread names to report
+ iNewThreadCount--;
+ DThread* t = this->threadNamesToReport[iNewThreadCount];
+ return EncodeChunkName(*t);
+ }
+ else if(iThreadCount > 0)
+ {
+ if(this->iProcessing == EProcessingNames || this->iProcessing == EStartingToProcess)
+ {
+ // this is the first data sample, encode a code for data
+ this->iProcessing = EProcessingData;
+ return EncodeDataCode();
+ }
+
+ // there are no new chunks to report
+ // thus generate the real report
+ iThreadCount--;
+ DThread* t = this->threadsToSample[iThreadCount];
+ LOGSTRING2("PriSamplerImpl::ProcessChunks - starting to process thread 0x%x",t);
+ return EncodeChunkData(*t);
+ }
+ else
+ {
+ // everything is processed
+ return 0;
+ }
+ }
+
+inline TInt DPriSamplerImpl::EncodeNameCode()
+ {
+ sample[0] = 1;
+ sample[1] = 0xbb; // pri trace name code
+ return 2;
+ }
+
+inline TInt DPriSamplerImpl::EncodeDataCode()
+ {
+ sample[0] = 1;
+ sample[1] = 0xee; // pri trace data code
+ return 2;
+ }
+
+
+inline TInt DPriSamplerImpl::EncodeChunkName(DThread& t)
+ {
+ // the size of the following name is in the first byte
+ TUint8* size = &sample[0];
+ *size = 0;
+ this->sampleDescriptor.Zero();
+
+ t.TraceAppendFullName(this->sampleDescriptor,false);
+ *size += this->sampleDescriptor.Size();
+
+ // copy the 4 bytes from the thread id field
+ this->sampleDescriptor.Append((TUint8*)&(t.iId),sizeof(TUint));
+ *size += sizeof(TUint);
+
+ // the size is the descriptor length + the size field
+ LOGSTRING2("Name size - %d",*size);
+ return ((TInt)(*size))+1;
+ }
+
+
+inline TInt DPriSamplerImpl::EncodeChunkData(DThread& t)
+ {
+ LOGTEXT("PriSamplerImpl::EncodeChunkData - entry");
+ LOGSTRING2("PriSamplerImpl::EncodeChunkData - processing thread 0x%x ",&t);
+
+ // the size of the following name is in the first byte
+ TUint8* size = &sample[0];
+ *size = 0;
+ this->sampleDescriptor.Zero();
+
+ LOGTEXT("PriSamplerImpl::EncodeChunkData - cleared");
+
+ // append the thread id
+ this->sampleDescriptor.Append((TUint8*)&(t.iId),sizeof(TUint));
+ *size += sizeof(TUint);
+
+// NKern::LockSystem();
+// TInt priority(-1);
+// if(&t && t.Open()== KErrNone)
+// {
+// priority = t.iDefaultPriority;
+// }
+// NKern::UnlockSystem();
+
+ // append the priority of the nanokernel fast semaphore
+// this->sampleDescriptor.Append((TUint8*)&priority,sizeof(TUint8));
+ // append the priority of the nanokernel fast semaphore
+ this->sampleDescriptor.Append((TUint8*)&(t.iNThread.iPriority),sizeof(TUint8));
+ // add space because EKA-1 implementation needs it
+ this->sampleDescriptor.Append((TUint8)0x0);
+ *size += 2*sizeof(TUint8);
+
+ LOGTEXT("PriSamplerImpl::EncodeChunkData - appended priority");
+
+
+ LOGSTRING2("Data size - %d",*size);
+ return ((TInt)(*size))+1;
+ }
+
+
+void DPriSamplerImpl::Reset()
+ {
+ /*
+ *
+ * EKA-2 implementation of PRI trace
+ *
+ */
+
+ LOGTEXT("PriSamplerImpl::Reset");
+ iCountti = 50; // sample threads 16 cycles before actual MEM and PRI sample time...
+ this->iThreadCount = 0;
+ this->iNewThreadCount = 0;
+ this->iProcessing = ENothingToProcess;
+ this->sampleDescriptor.Zero();
+
+
+ // clear all thread tags
+ DObjectCon* threads = Kern::Containers()[EThread];
+ TInt totalThreadCount = threads->Count();
+ for(TInt i=0;i<totalThreadCount;i++)
+ {
+ DThread* t = (DThread*)(*threads)[i];
+ TAG(t) = (TAG(t) & 0xfffffffd);
+ }
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/rom/piprofiler.iby Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,38 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef __PIPROFILER__
+#define __PIPROFILER__
+
+// PI Profiler Engine itself
+file=ABI_DIR\BUILD_DIR\PIProfilerEngine.exe sys\bin\PIProfilerEngine.exe
+file=ABI_DIR\BUILD_DIR\PIProfiler.exe sys\bin\PIProfiler.exe
+data=ZSYSTEM\Install\PIProfiler_stub.sis system\install\PIProfiler_stub.sis
+
+// sampler plugins
+// NOTE: Mandatory kernel driver included in piprofiler_ldd.iby
+ECOM_PLUGIN(PIProfilerGenerals.dll, PIProfilerGenerals.rsc)
+
+ECOM_PLUGIN(PIProfilerBUP.dll, PIProfilerBUP.rsc)
+file=ABI_DIR\BUILD_DIR\PIProfilerTouchEventAnim.dll sys\bin\PIProfilerTouchEventAnim.dll
+
+// Writer plugins
+ECOM_PLUGIN(piprofilerdebugwriter.dll, piprofilerdebugwriter.rsc)
+ECOM_PLUGIN(piprofilerdiskwriter.dll, piprofilerdiskwriter.rsc)
+
+#endif //__PIPROFILER__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/rom/piprofiler_ldd.iby Thu May 13 23:59:27 2010 +0300
@@ -0,0 +1,25 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#ifndef __PIPROFILER_LDD__
+#define __PIPROFILER_LDD__
+
+// kernel side driver
+device[VARID]=KERNEL_DIR\BUILD_DIR\PIProfilerGeneralsSampler.ldd sys\bin\PIProfilerGeneralsSampler.ldd
+
+#endif //__PIPROFILER_LDD__
--- a/stif/Parser/src/StifParser.cpp Mon May 03 13:58:41 2010 +0300
+++ b/stif/Parser/src/StifParser.cpp Thu May 13 23:59:27 2010 +0300
@@ -845,7 +845,7 @@
//
// Method: HandleSpecialMarks
//
-// Description: Handles special marks.( '\/\/', '\/\*' and '*/\/' ). This
+// Description: Handles special marks.( '\/' and '\*' ). This
// is used when ECStyleComments comment type is used.
//
// Parameters: TPtr& aBuf: inout: section to parsed
@@ -862,68 +862,28 @@
{
TLex lex( aBuf );
TInt firstPos( 0 );
- TInt secondPos( 0 );
-
- // // => \/\/ => //
- // /* => \/\* => /*
- // */ => \*\/ => */
-
+
+ // Replace \/ with /
+ // Replace \* with *
+
do
{
+ //RDebug::Print( _L("Print : %S"), &aBuf );
firstPos = lex.Offset();
TChar get = lex.Get();
// Check is '\'
if( get == '\\' )
{
- // Peek next character( '/' )
- if( lex.Peek() == '/' )
+ firstPos = (lex.Offset()-1);
+ // Peek next character( '/' or '*' )
+ if( lex.Peek() == '/' || lex.Peek() == '*')
{
- lex.Inc();
- secondPos = lex.Offset();
- // Peek next character( '\' )
- if( lex.Peek() == '\\' )
- {
- lex.Inc();
- // Peek next character( '/' )
- if( lex.Peek() == '/' )
- {
- // Delete mark '\/\/' and replace this with '//'
- aBuf.Delete( secondPos, 1 );
- aBuf.Delete( firstPos, 1 );
- lex = aBuf;
- }
- // Peek next character( '/' )
- else if( lex.Peek() == '*' )
- {
- // Delete mark '\/\*' and replace this with '/*'
- aBuf.Delete( secondPos, 1 );
- aBuf.Delete( firstPos, 1 );
- lex = aBuf;
- }
- }
- }
- // Peek next character( '/' )
- else if( lex.Peek() == '*' )
- {
- lex.Inc();
- secondPos = lex.Offset();
- // Peek next character( '\' )
- if( lex.Peek() == '\\' )
- {
- lex.Inc();
- // Peek next character( '/' )
- if( lex.Peek() == '/' )
- {
- // Delete mark '\*\/' and replace this with '*\'
- aBuf.Delete( secondPos, 1 );
- aBuf.Delete( firstPos, 1 );
- lex = aBuf;
- }
- }
+ aBuf.Delete (firstPos,1);
+ lex = aBuf;
}
}
+
firstPos = 0;
- secondPos = 0;
} while ( !lex.Eos() );
}
--- a/stif/StifKernelTestClassBase/group/StifKernelTestClassBase.mmp Mon May 03 13:58:41 2010 +0300
+++ b/stif/StifKernelTestClassBase/group/StifKernelTestClassBase.mmp Thu May 13 23:59:27 2010 +0300
@@ -27,7 +27,6 @@
SECUREID 0x102073DD
EPOCALLOWDLLDATA
-
TARGET StifKernelTestClassBase.dll
TARGETTYPE kdll
UID 0x1000008D 0x101FB3E3
@@ -43,9 +42,4 @@
SOURCE StifKernelTestClassBase.cpp
-LIBRARY ekern.lib
-
-
-
LANG SC
-
--- a/stif/group/ReleaseNote.txt Mon May 03 13:58:41 2010 +0300
+++ b/stif/group/ReleaseNote.txt Thu May 13 23:59:27 2010 +0300
@@ -1,5 +1,5 @@
========================================================================
-RELEASE NOTE FOR STIF - STIF_201012 (7.3.29)
+RELEASE NOTE FOR STIF - STIF_201018 (7.3.32)
SUPPORTING SERIES 60 3.0 ->
========================================================================
--- a/stif/inc/version.h Mon May 03 13:58:41 2010 +0300
+++ b/stif/inc/version.h Thu May 13 23:59:27 2010 +0300
@@ -20,9 +20,9 @@
#define STIF_MAJOR_VERSION 7
#define STIF_MINOR_VERSION 3
-#define STIF_BUILD_VERSION 29
+#define STIF_BUILD_VERSION 32
-#define STIF_REL_DATE "23th Mar 2010"
+#define STIF_REL_DATE "04th May 2010"
#define TO_UNICODE(text) _L(text)
Binary file stif/sis/Stif_31.sis has changed