#!/bin/ksh LOGFILE="" CONTINUOUS_LOGGING=0 # variable used to stop the loop CONTINUOUS_LOGGING_PERIOD=5 # seconds OUTPUTDIR=$1 USECASE=$2 PARAM_CONTINUOUS=0 FOUND=0 SCRIPT_RUNNING=0 # enumeration of possible dump modes DUMP_BASIC=0 DUMP_FULL=1 if [[ $# > 0 ]] #path then OUTPUTDIR=$1 if [[ $# > 1 ]] #UseCase || -c then if [[ $2 == "-c" ]] then PARAM_CONTINUOUS=$2 # -c #echo "Continous logging enabled" else USECASE=$2 # usecase fi if [[ $# > 2 ]] # -c || logging period then if [[ $3 == "-c" ]] then PARAM_CONTINUOUS=$3 # -c #echo "Continous logging enabled" else CONTINUOUS_LOGGING_PERIOD=$3 # logging period #echo "Logging period set to $CONTINUOUS_LOGGING_PERIOD" fi if [[ $# > 3 ]] # ogging period then CONTINUOUS_LOGGING_PERIOD=$4 # logging period #echo "Logging period set to $CONTINUOUS_LOGGING_PERIOD" fi fi fi fi function PrintError # { MESSAGE=$* if [[ $LOGFILE == "" ]] then echo "FATAL ERROR: no logfile is set" exit 2 fi if [[ $MESSAGE == "" ]] then echo "FATAL ERROR: no message" exit 2 fi echo "Error: $MESSAGE" echo "Error: $MESSAGE" >> $LOGFILE } function PrintInfo # { MESSAGE=$* if [[ $LOGFILE == "" ]] then echo "FATAL ERROR: no logfile is set" exit 2 fi if [[ $MESSAGE == "" ]] then echo "FATAL ERROR: no message" exit 2 fi echo "Info : $MESSAGE" echo "Info : $MESSAGE" >> $LOGFILE } function ScriptAbort # { MESSAGE=$* PrintError $MESSAGE echo "Script aborted!" echo "Script aborted!" >> $LOGFILE exit 1 } # Check if srm has been started already, if not do solution # needed by: # - heapinfo function CheckAndRunSRM # { net_name=$1 if [[ $net_name == $HOSTNAME ]]; then if [[ ! -e /dev/srm/status ]]; then $path_to_srm 2> /dev/null if [[ $? -ne 0 ]] then PrintInfo "Unable to start $path_to_srm on local host" fi fi else if [[ ! -e /net/$net_name/dev/srm/status ]]; then on -f $net_name $path_to_srm 2> /dev/null if [[ $? -ne 0 ]] then PrintInfo "Unable to start $path_to_srm on $net_name" fi fi fi } function DumpData # { outputdir=$1 unittype=$2 hwtype=$3 processor=$4 usecase=$5 whattodump=$6 PrintInfo "......Dump processor $unittype, $processor, $usecase" BASEPATH=$outputdir/$hwtype/Logs NETNAME=$unittype-$processor if [[ ! -e /net/$NETNAME ]] then ScriptAbort "Unable to find host $unittype-$processor" fi mkdir -p $BASEPATH if [[ $? -ne 0 ]] then ScriptAbort "Unable to create target directory" fi path_to_srm="srm" path_to_showmem="showmem" CheckAndRunSRM $NETNAME # Dump pidins # -- args on -f $NETNAME pidin arg > $BASEPATH/pidin-arg-$processor-$usecase.txt if [[ $? -ne 0 ]] then ScriptAbort "Unable to execute pidin args" fi # -- Mem on -f $NETNAME pidin mem > $BASEPATH/pidin-mem-$processor-$usecase.txt if [[ $? -ne 0 ]] then ScriptAbort "Unable to execute pidin mem" fi # -- Aps (OMAP only) if [[ $processor == "omap" ]] then on -f $NETNAME pidin -F "%a|%30N|%b|%30h|%H" > $BASEPATH/pidin-aps-$processor-$usecase.txt if [[ $? -ne 0 ]] then ScriptAbort "Unable to execute pidin aps" fi fi # -- Info on -f $NETNAME pidin info > $BASEPATH/pidin-info-$processor-$usecase.txt if [[ $? -ne 0 ]] then ScriptAbort "Unable to execute pidin info" fi # Dump showmem on -f $NETNAME $path_to_showmem -Dlsh > $BASEPATH/mem-$processor-Dslh-$usecase.txt if [[ $? -ne 0 ]] then ScriptAbort "Unable to execute $path_to_showmem " fi # Append(!) /dev/shmem regular files into showmem output on -f $NETNAME ls -lad /net/$NETNAME/dev/shmem/* >> $BASEPATH/mem-$processor-Dslh-$usecase.txt servicebrokermode=Master if [[ $processor == "jacinto" ]] then servicebrokermode=Slave fi if [[ $processor == "omap" ]] then servicebrokermode=Master # -- software version if [[ -e /opt/sys/etc/nbt_version.txt ]] then cp -f -t /opt/sys/etc/nbt_version.txt $BASEPATH/ else PrintInfo "... nbt_version.txt not found" fi # -- VRAM pidin_g -n $NETNAME mapinfo > $BASEPATH/vram-$processor-$usecase.txt fi # if [[ $processor == "omap" ]] # Dump servicebroker.cfg cp -f -t /etc/servicebroker.cfg $BASEPATH/servicebroker_omap.cfg cp -f -t /net/$NETNAME/etc/servicebroker.cfg $BASEPATH/servicebroker_jacinto.cfg cat /net/$NETNAME/srv/servicebroker > $BASEPATH/servicebroker-$servicebrokermode-$usecase.txt if [[ $? -ne 0 ]] then ScriptAbort "Unable to execute cat on servicebroker" fi # copy text file which contains information about configured memory reserve if [[ -e /opt/sys/etc/memory_reserve.txt ]] then cp -f -t /opt/sys/etc/memory_reserve.txt $BASEPATH/ else PrintInfo "... memory_reserve.txt not found" fi # OMAP VRAM statistics (according to Dennis Fu, QNX, this is purely screen internal debug information) if [[ $processor == "omap" ]] then on -f $NETNAME cat /dev/screen/mem > $BASEPATH/dev-screen-mem-$processor-$usecase.txt if [[ $? -ne 0 ]] then PrintInfo "... error creating $processor VRAM statistics" fi fi # Files in shared memory /dev/shmem # R: Recursively list all subdirectories encountered # a: List all files, including hidden ones # g: List in long format, but don't show owner # o: List in long format, but don't show group # S: Don't sort the output (to make it faster) on -f $NETNAME ls -RagoS /dev/shmem > $BASEPATH/shmem-$processor-$usecase.txt 2> $BASEPATH/shmem-$processor-$usecase-err.txt if [[ $? -ne 0 ]] then PrintInfo "... error during dump of /dev/shmem on $processor" fi # OMAP only: heapinfo will be dumped into directory Logs/heapinfo # only in DUMP_FULL mode #if [[ $processor == "omap" && $whattodump == $DUMP_FULL ]] #then # PrintInfo "... Dump heapinfo on $processor" # HEAPINFOS_PATH=$BASEPATH/heapinfo # mkdir -p $HEAPINFOS_PATH # # # variable contains list of pids (process names may not be unique!) # pids=`on -f $NETNAME pidin -F "%a"` # # for pid in $pids # do # if [[ $pid != "pid" ]] # then # # $processname will contain strings like '/procnto-smp-instr', 'boot/bin/sysinit' so we need to find out the short process name # pidinprocessname=`on -f $NETNAME pidin -F "%30N" -p $pid` # for processname in $pidinprocessname # do # if [[ $processname != "name" ]] # then # shortprocessname=`echo "$processname" | sed 's/^\(\/*.*\)\/\(.*\.*\)$/\2/'` # 'name ' was generated by pidin # if [[ $shortprocessname != "(Zombie)" ]] # then # # echo "$NETNAME: '$processname' -> '$shortprocessname' ($pid)" # on -f $NETNAME heapinfo -p $pid > $HEAPINFOS_PATH/heapinfo-$processor-$usecase-$shortprocessname-$pid.txt # fi # fi # [[ $processname != "name" ]] # done # fi # [[ $pid != "pid" ]] # done #fi } # signal handler for CTRL-C (SIGINT) # used for stopping the loop of continous memory logging # we use this to avoid incomplete log files function signalHandlerINT { echo "\nPlease wait ..." # use echo (not PrintInfo) to not write to log file CONTINUOUS_LOGGING=0 FOUND=0 } # CAUTION: This function only returns on CTRL-C !!!! function DumpMemContinuous # { outputdir=$1 unittype=$2 hwtype=$3 processor=$4 usecase=$5 PrintInfo "Every $CONTINUOUS_LOGGING_PERIOD sec: reporting memory $unittype, $processor, $usecase ..." echo " Press CTRL-C to stop" BASEPATH=$outputdir/$hwtype/Logs/continuous NETNAME=$unittype-$processor if [[ ! -e /net/$NETNAME ]] then ScriptAbort "Unable to find host $unittype-$processor" fi mkdir -p $BASEPATH if [[ $? -ne 0 ]] then ScriptAbort "Unable to create target directory" fi path_to_srm="srm" path_to_showmem="showmem" # Not needed anymore to start srm because showmem is used from QNX delivery # CheckAndRunSRM $NETNAME typeset -i loopcnt # allow arithmetic calculations for loopcnt loopcnt=1 CONTINUOUS_LOGGING=1 trap signalHandlerINT INT # install the SIGINT handler while [ $CONTINUOUS_LOGGING -eq 1 ] # only CTRL-C (which generates SIGINT) can stop this loop do echo -n "\rloop: $loopcnt" # use echo (not PrintInfo) to not write to log file echo Creating Showmem mem-$processor-$usecase-$loopcnt.txt > /dev/console # showmem of all processes on -f $NETNAME $path_to_showmem -Dlsh > $BASEPATH/mem-$processor-$usecase-$loopcnt.txt # Free memory pidin -n $NETNAME info > $BASEPATH/pidin-info-$processor-$usecase-$loopcnt.txt # files in /dev/shmem on -f $NETNAME ls -lad /net/$NETNAME/dev/shmem/* >> $BASEPATH/mem-$processor-$usecase-$loopcnt.txt # VRAM pidin_g -n $NETNAME mapinfo > $BASEPATH/vram-$processor-$usecase-$loopcnt.txt loopcnt=$loopcnt+1 sleep $CONTINUOUS_LOGGING_PERIOD done # delete files from the last loop because very often they are incomplete loopcnt=$loopcnt-1 rm -f $BASEPATH/mem-$processor-$usecase-$loopcnt.txt rm -f $BASEPATH/vram-$processor-$usecase-$loopcnt.txt PrintInfo "... $loopcnt loops" echo "\n" } # end of function DumpMemContinuous function ShowUseCases { count=1; echo "######################################" if [[ $PARAM_CONTINUOUS == "-c" ]] then echo "# This script is running continously" echo "# every $CONTINUOUS_LOGGING_PERIOD seconds." echo "# " echo "# Press CTRL+C to interrupt." fi echo "# Availabe usecases, press" echo "# -----------------------------------" for usecaselement in ${VALID_USECASES[*]} do echo "# $count for $usecaselement " count=$(( $count + 1 )) done echo "# -----------------------------------" echo "# or press any other key to exit:" echo "> \c" } function checkForHU35UP { # detection of HU 35up is done by eval of Coding HMI.HMI_VERSION == ID5 echo "Detecting HU type (hu or hu35up)... please wait... " SYSETSHELL=sysetshellevo type $SYSETSHELL >/dev/null 2>&1 if [ $? -ne 0 ] ; then echo "\n ERROR: Could not find $SYSETSHELL\n" else SYSET_OUTPUT=$($SYSETSHELL) < [usecase] [-c]" echo " The usecase description is stored under 'https://confluence.harman.com/confluence/display/NBTEVO/Memory'." echo " Please visit the link for further information." echo " : This directory will be used as a target for all collected informations." echo " [usecase]: Leave usecase blank to get a list of all availabe use cases, else the usecase must be named to ensure the correct naming and later analyse " echo " -c: Optional: Enable periodic memory reporting every $CONTINUOUS_LOGGING_PERIOD seconds" exit 1 fi LOGFILE=$OUTPUTDIR/DumpInfo_$USECASE.log rm -f $LOGFILE PrintInfo "Dumping information for usecase $USECASE" PrintInfo "... Dump $UNITTYPE" if [[ $PARAM_CONTINUOUS == "-c" ]] then # make sure that basic data exists, even if target crashes during continuous measurement DumpData $OUTPUTDIR $UNITTYPE $HWTYPE omap $USECASE $DUMP_BASIC DumpData $OUTPUTDIR $UNITTYPE $HWTYPE jacinto $USECASE $DUMP_BASIC # continuous periodic reporting of memory usage # CAUTION: function DumpMemContinuous returns only if CTRL-C pressed !!! DumpMemContinuous $OUTPUTDIR $UNITTYPE $HWTYPE omap $USECASE # Overwrite the DumpData from before the continous measurement DumpData $OUTPUTDIR $UNITTYPE $HWTYPE omap $USECASE $DUMP_FULL DumpData $OUTPUTDIR $UNITTYPE $HWTYPE jacinto $USECASE $DUMP_FULL else DumpData $OUTPUTDIR $UNITTYPE $HWTYPE omap $USECASE $DUMP_FULL DumpData $OUTPUTDIR $UNITTYPE $HWTYPE jacinto $USECASE $DUMP_FULL fi } UNITTYPE=${HOSTNAME%%-*} HWTYPE=$UNITTYPE if [[ $UNITTYPE == "hu" ]]; then VALID_USECASES[0]=HU_Startup VALID_USECASES[1]=HU_Entertainment VALID_USECASES[2]=HU_Tuner VALID_USECASES[3]=HU_Navigation VALID_USECASES[4]=HU_Speech VALID_USECASES[5]=HU_Connectivity VALID_USECASES[6]=HU_Online VALID_USECASES[7]=HU_FullLoad SIZE_OF_USECASES=${#VALID_USECASES[*]} checkForHU35UP elif [[ $UNITTYPE == "rse" ]]; then VALID_USECASES[0]=RSE_Startup VALID_USECASES[1]=RSE_Entertainment VALID_USECASES[2]=RSE_Navigation VALID_USECASES[3]=RSE_Connectivity VALID_USECASES[4]=RSE_Online VALID_USECASES[5]=RSE_FullLoad SIZE_OF_USECASES=${#VALID_USECASES[*]} else echo "\n\n--> failed to detect unit type (hu or rse). Aborted.\n\n" exit 1 fi for usecaselement in ${VALID_USECASES[*]} do if [[ $USECASE == $usecaselement ]] then FOUND=1 fi done runScript while [ $SCRIPT_RUNNING -eq 1 ] do FOUND=0 runScript done PrintInfo "Done" exit 0