# COREinfo.ctl: Extracts Core Dump Information
# $Id: COREinfo.ctl,v 1.7 2013/12/16 07:51:45 RDA Exp $
# ARCS: $Header: /home/cvs/cvs/RDA_8/src/scripting/lib/collect/OS/COREinfo.ctl,v 1.7 2013/12/16 07:51:45 RDA Exp $
#
# Change History
# 20131212 KRA Fix spell.
=for stopwords COREinfo
=head1 NAME
OS:COREinfo - Extracts Core Dump Information
=head1 DESCRIPTION
This module extracts relevant information from a core dump file.
The following macros are available:
=cut
# Make the module persistent and share macros
keep $KEEP_BLOCK,@SHARE_MACROS
var @SHARE_MACROS = ('can_analyze_core','analyze_core','run_coreadm')
# Initialisation
keep $CORE_DEBUG,$CORE_INFO,$CORE_PFLAGS,$CORE_PLDD,$CORE_PMAP,$CORE_SEP,\
$CORE_TYPE,%CORE_OPT
if !$CORE_INFO
{var $CORE_INFO = true
# Define some variables that are shared between macros
var $CORE_DEBUG
var $CORE_PFLAGS
var $CORE_PLDD
var $CORE_PMAP
var $CORE_SEP = cond(match(getOsName(),'aix'),",\s*","'")
var $CORE_TYPE
var %CORE_OPT = ('gdb',' -quiet')
# Find a debugger
if or(isUnix(),isCygwin())
{macro find_command
{if ?findCommand($arg[0],true)
{var $pgm = last
if ?testFile('x',$pgm)
return quote($pgm)
}
return undef
}
if match(getOsName(),'solaris|sunos')
{if find_command('pstack')
{var $CORE_DEBUG = last
var $CORE_PFLAGS = find_command('pflags')
var $CORE_PLDD = find_command('pldd')
var $CORE_PMAP = find_command('pmap')
}
}
if !$CORE_DEBUG
{if and(match($osn,'aix'),compare('valid',first(command('oslevel')),'4.3'))
var @dbg = ('dbx','gdb','mdb','adb','sdb')
else
var @dbg = ('gdb','mdb','adb','sdb','dbx')
loop $CORE_TYPE (@dbg)
{if find_command($CORE_TYPE)
{var $CORE_DEBUG = last
break
}
}
}
}
}
=head2 can_analyze_core()
This macro indicates which command has been found to analyze core
dumps. Otherwise, it returns an undefined value.
=cut
macro can_analyze_core
{import $CORE_DEBUG
keep $CORE_DEBUG
return $CORE_DEBUG
}
=head2 analyze_core($dmp...)
This macro analyzes all core dumps specified as arguments. For each dump, it
determines the location of the corresponding executable first and then extracts
the stack information.
=cut
macro analyze_core
{import $CORE_DEBUG,$CORE_PFLAGS,$CORE_PLDD,$CORE_PMAP,$CORE_SEP,$CORE_TYPE,\
$TOP,%CORE_OPT
keep $CORE_DEBUG,$CORE_PFLAGS,$CORE_PLDD,$CORE_PMAP,$CORE_SEP,$CORE_TYPE,\
%CORE_OPT
# Abort when no debugger has been found
if !$CORE_DEBUG
return
# Initialize the debugger input file
if compare('eq',$CORE_TYPE,'gdb')
{var $inp = createTemp('debug')
call writeTemp('debug','echo \n\n---### Stack\n\n')
call writeTemp('debug','thread apply all where')
call writeTemp('debug','echo \n\n---### Registers\n\n')
call writeTemp('debug','info all-registers')
call writeTemp('debug','q')
call closeTemp('debug')
}
elsif compare('eq',$CORE_TYPE,'mdb')
{var $inp = createTemp('debug')
call writeTemp('debug','!echo ""')
call writeTemp('debug','!echo "---### Version and Status"')
call writeTemp('debug','!echo ""')
call writeTemp('debug','::version')
call writeTemp('debug','::status')
call writeTemp('debug','!echo ""')
call writeTemp('debug','!echo "---### Stack"')
call writeTemp('debug','!echo ""')
call writeTemp('debug','::walk thread | ::findstack')
call writeTemp('debug','!echo ""')
call writeTemp('debug','!echo "---### Registers"')
call writeTemp('debug','!echo ""')
call writeTemp('debug','::regs')
}
elsif compare('eq',$CORE_TYPE,'adb')
{var $inp = createTemp('debug')
call writeTemp('debug','!echo ""')
call writeTemp('debug','!echo "---### Stack"')
call writeTemp('debug','!echo ""')
call writeTemp('debug','$c')
call writeTemp('debug','!echo ""')
call writeTemp('debug','!echo "---### Registers"')
call writeTemp('debug','!echo ""')
call writeTemp('debug','$r')
call writeTemp('debug','$f')
call writeTemp('debug','!echo ""')
call writeTemp('debug','!echo "---### Memory Map"')
call writeTemp('debug','!echo ""')
call writeTemp('debug','$m')
call writeTemp('debug','!echo ""')
call writeTemp('debug','!echo "---### Variables"')
call writeTemp('debug','!echo ""')
call writeTemp('debug','$v')
call writeTemp('debug','$q')
call closeTemp('debug')
}
elsif compare('eq',$CORE_TYPE,'sdb')
{var $inp = createTemp('debug')
call writeTemp('debug','t')
call writeTemp('debug','quit')
call closeTemp('debug')
}
elsif compare('eq',$CORE_TYPE,'dbx')
{var $inp = createTemp('debug')
call writeTemp('debug','print ""')
call writeTemp('debug','print "---### Stack"')
call writeTemp('debug','print ""')
call writeTemp('debug','where')
call writeTemp('debug','print ""')
call writeTemp('debug','print "---### Registers"')
call writeTemp('debug','print ""')
call writeTemp('debug','registers')
call writeTemp('debug','quit')
call closeTemp('debug')
}
else
var $inp = undef
# Generate the report
loop $dmp (@arg)
{write '---+ ',$dmp
if ?testFile('r',$dmp)
{# Try to extract the program name that produced the core
var $pgm = field($CORE_SEP,1,command(concat('file ',quote($dmp))))
# List the environment, what we know so far
write '|*Core file*|',encode($dmp),' |'
write '|*Program *|',encode($pgm),' |'
# Extract information from the core file
if $CORE_TYPE
{# Extract possible executables from the corefile
var ($flg,%exe) = ()
loop $exe ($pgm,\
catFile(dirname($dmp),$pgm),\
grepCommand(concat('strings ',quote($dmp)),\
concat('^(.*\/)?',$pgm,'$')))
{var $exe = replace($exe,'^\.\/+')
if ?testFile('x',$exe)
{next ?testDir('d',$exe)
var $exe{$exe} = 1
var $flg = true
}
}
# Try them individually to extract a stack trace.
if $flg
{loop $exe (keys(%exe))
{prefix
write '---## Core extraction be attempted with ',encode($exe)
call writeCommand(concat($CORE_DEBUG,\
$CORE_OPT{$CORE_TYPE},' ',quote($exe),' ',\
quote($dmp),' <',$inp))
if hasOutput(true)
write $TOP
}
}
else
write '** Program not found.**%BR%',$TOP
}
else
{# If pstack is available, just call the code and be done with it.
prefix
write '---### pstack Output'
call writeCommand(concat($CORE_DEBUG,' ',quote($dmp)))
if hasOutput(true)
write $TOP
# If we found pmap, run it
if $CORE_PMAP
{prefix
write '---### pmap Output'
call writeCommand(concat($CORE_PMAP,' ',quote($dmp)))
if hasOutput(true)
write $TOP
}
# If we found pflags, run it
if $CORE_PFLAGS
{prefix
write '---### pflags Output'
call writeCommand(concat($CORE_PFLAGS,' -r ',quote($dmp)))
if hasOutput(true)
write $TOP
}
# If we found pldd, run it
if $CORE_PLDD
{prefix
write '---### pldd Output'
call writeCommand(concat($CORE_PLDD,' ',quote($dmp)))
if hasOutput(true)
write $TOP
}
}
}
else
{write '** Not readable.**%BR%'
call statFile('b',$dmp)
write $TOP
}
}
# Remove the temporary debug file
if $inp
call unlinkTemp('debug')
}
=for stopwords coreadm
=head2 S
This macro writes the global and per process F command output into the
current report. The processes for which the F command is to be run,
are selected based on a regular expression.
=cut
macro run_coreadm
{var ($pat) = @arg
import $TOP
if ?findCommand('coreadm')
{var $cmd = last
debug ' Inside run_coreadm, getting global coreadm pattern'
write '---+ Global Core Dump Pattern'
call writeCommand($cmd)
write $TOP
debug ' Inside run_coreadm, getting per-process coreadm pattern'
var $PS_EF
run OS:OSsunos('PS')
loop $lin (grepCommand(concat($PS_EF,' -o pid,args'),$pat))
{var ($pid,$val) = split('\s+',trim($lin),2)
if match($pid,'\d')
var $prc{$pid} = concat($pid,'-',$val)
}
loop $pid (keys(%prc))
{if loadCommand(concat($cmd,' ',$pid))
{loop $lin (getLines())
{var (undef, $pat) = split(':',$lin,2)
var $pat = trim($pat)
var $lst{$pat} = join('%BR%',$lst{$pat},$prc{$pid})
}
}
}
if %lst
{write '---+ Per Process Core Dump Pattern'
write '|*Core File Pattern*|*Processes*|'
loop $key (keys(%lst))
write '|',$key,'|',$lst{$key},'|'
write $TOP
}
}
}
=begin credits
=over 10
=item RDA 4.4: Roger Snowden.
=item RDA 4.12: Francois Lange.
=back
=end credits
=head1 COPYRIGHT NOTICE
Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
=head1 TRADEMARK NOTICE
Oracle and Java are registered trademarks of Oracle and/or its
affiliates. Other names may be trademarks of their respective owners.
=cut