#!/bin/ksh # javaLibsGrabber.sh # rev 1 # from the tool newLibsGrabber.sh By Roger Leuckie # modified to remove the -p and -f flags and accept parameters # from the command line. Also update usage message and other # cosmetic changes by Russ Cunningham # 02/22/06 # takes two parameters, the name of the core file and the directory # path to the executable that caused the core. # extracts the libraries and executable paths from the core file # and creates a compressed tar file called ARCHIVE_NAME # in the current directory containing these files # does some error checking to see if its a complete core file # the the error checking is not complete so a partial core may # slip through # 02/23/06 # made a change suggested by Wei Luo on the java team to fix a # major problem of the customer not knowing which java installed # on the machine was the one that created the core file. # The script now makes a pass through the core file looking for the # full path for the libjava.a library which is always in the same # directory as the java executable. It strips off the path and uses # that path to retrieve the correct java (( mask64 = 1 )) (( word_size = 4 )) (( bit_size = 32 )) (( is64bit = 0 )) (( loader_offset = 0 )) (( next_offset = 1 )) (( lib_offset = 0 )) (( path_max = 1024 + 9 )) ARCHIVE_NAME="core-libs.tar.Z" grep "#define[ ]*PATH_MAX[ ]*" /usr/include/sys/limits.h 2>/dev/null | \ head -1 | awk '{print $3}' | read path_max get_bitsize(){ od -tdL -j1276 -N4 ${1} 2>/dev/null | head -1 | awk '{print $2}' | read bit64_flag if [ -z "${bit64_flag}" ]; then echo "ERROR: unable to determine if 32/64 bit application. may be truncated." >&2 exit 1 fi if (( mask64 == ( bit64_flag & mask64 ) )); then (( bit_size = 64 )) (( word_size = 8 )) (( is64bit = 1 )) fi } get_loader_offset() { od -tdL -j16 -N8 ${1} | head -1 | awk '{print $3}' | read loader_offset if [ -z "${loader_offset}" ]; then echo "ERROR: unable to determine loader offset. may be truncated." >&2 exit 1 fi if (( loader_offset < 1 )) || (( loader_offset > 1000000 )); then echo "ERROR: loader offset out of range ( 1-100000 ). may be corrupted." >&2 exit 1 fi } get_next_offset() { od -tdI -j${2} -N4 ${1} | awk '{print $2}' | read next_offset if [ -z "${next_offset}" ]; then echo "ERROR: unable to determine next lib offset. may be corrupted." >&2 exit 1 fi } get_lib_offset() { (( lib_offset = ${1} + ( word_size * 6 ) )) } get_file() { od -S -j${2} -N${path_max} ${1} | head -1 | awk '{print $2}' } get_file_list() { get_bitsize ${1} get_loader_offset ${1} (( current_offset = loader_offset )) while (( next_offset != 0 )); do get_next_offset ${1} ${current_offset} get_lib_offset ${current_offset} get_file ${1} ${lib_offset} | read file_in_core if [ ! -f ${file_in_core} ]; then # this should only happen for the executable if [ -f "${EXEC_PATH}/${file_in_core}" ]; then path_and_file="${EXEC_PATH}/${file_in_core}" fi else path_and_file="${file_in_core}" fi # echo "INFO: file in core: ${file_in_core} full path: ${path_and_file}" >&2 echo "${path_and_file}" #echo "${is64bit} ${bit_size} ${word_size} ${loader_offset} ${next_offset} ${lib_offset}" (( current_offset = current_offset + next_offset )) done } usage() { echo echo "USAGE: ${0} core_file " >&2 echo "Like: ${0} core.001 " >&2 echo exit 1 } if [ $# != 1 ]; then usage fi echo "finding the path for the executable that caused the core file" >&2 EXEC_PATH=$(dirname "$( get_file_list ${1} | sort -u | grep libjava.a)") echo "the path is ${EXEC_PATH}" core_file=$1 if [ ! -f ${core_file} ]; then echo "ERROR: ${core_file} does not exist." >&2 exit 1 fi if [ -n "${EXEC_PATH}" ]; then if [ ! -d ${EXEC_PATH} ]; then echo "ERROR: ${EXEC_PATH} may not be a directory." >&2 exit 1 fi fi echo "INFO: processing AIX core ${core_file}" >&2 file_list="$( get_file_list ${core_file} | sort -u | sed "s|^/|./|g" )" # added 01/25/06 # to always pickup the two libs needed by the dbx prog dbxstring=" ./usr/lib/libpthdebug.a ./usr/lib/libdbx.a" file_list=${file_list}${dbxstring} #echo $file_list >file_list if [ -z "${file_list}" ]; then echo "ERROR: no files could be determined from ${core_file}." >&2 exit 1 fi echo "${file_list}" | wc -l | read file_count # added 01/25/06 # add 2 to file_count as the two extra files we added don't have # new lines but tar doesn't care, just the error routine (( file_count=file_count + 2)) echo "INFO: archiving ${file_count} files identifed from ${core_file}" >&2 cd / tar -chf - ${file_list} | compress -c > ${OLDPWD}/${ARCHIVE_NAME} cd ${OLDPWD} if [ ! -f ${ARCHIVE_NAME} ]; then echo "ERROR: unable to create archive of libraries." >&2 exit 1 fi uncompress -c < ${ARCHIVE_NAME} | tar -tvf - | wc -l | read tar_file_count if (( tar_file_count == 0 )); then echo "ERROR: unable to verify archive ${ARCHIVE_NAME}." >&2 exit 1 fi if (( file_count != tar_file_count )); then echo "ERROR: number of files in ${ARCHIVE_NAME} not valid." >&2 exit fi echo "INFO: ${ARCHIVE_NAME} created." >&2 exit 0