#!/bin/csh -f
#
# All Rights Reserved. Copyright (C) 2004, Hitachi, Ltd.
#

if ( ( $#argv != 2 ) && ( $#argv != 1 ) ) then
  echo "usage $0:t Process-ID [Output-file]"
  goto ERROR_END;
endif

if ( ! -x "/usr/bin/gdb" ) then
  echo "Error occurred in generating Stack Trace, gdb not found."
  goto ERROR_END
endif

set CantCreateWorkDir = "Cannot create working directory on /tmp : Permission denied"
set OUTPUT = $2
set PID = $1

set WorkDir = "/tmp/javacore_gcore.`date +%Y%m%d%H%M%S`"
while ( -e "$WorkDir" )
    set WorkDir = "/tmp/javacore_gcore.`date +%Y%m%d%H%M%S`"
end
mkdir "$WorkDir"
if( !( -e "$WorkDir" ) ) then
    echo "$CantCreateWorkDir"
    goto ERROR_END
endif
set CMDFILE = "$WorkDir/gdb_cmd.sh"
set TMP = "$WorkDir/tmpout.txt"
set MYDEVNULL = "$WorkDir/tmp_dev_null.txt"
onintr ERROR_RMDIR

if ( "$2" == "" ) then
  set OUTPUT = "javatrace_gdb$PID.`date +%Y%m%d%H%M%S`.log"
  while ( -e "$OUTPUT" )
    set OUTPUT = "javatrace_gdb$PID.`date +%Y%m%d%H%M%S`.log"
  end
  touch "$OUTPUT" >& $MYDEVNULL
  if ( $status != 0 ) then
    set OLD_OUTPUT = "$OUTPUT"
    set OUTPUT = "/tmp/$OLD_OUTPUT"
    while ( -e "$OUTPUT" )
      set OUTPUT = "/tmp/javatrace_gdb$PID.`date +%Y%m%d%H%M%S`.log"
    end
    echo "Cannot generate $OLD_OUTPUT file on current directory."
    echo "Change directory/file name : $OLD_OUTPUT -> $OUTPUT"
  endif
  rm -f "$OUTPUT" >& $MYDEVNULL
endif  

echo "Now generating stack trace file ($OUTPUT)..."
echo "extract thread information..."

/usr/bin/gdb -quiet -n > $TMP << EOF
  set confirm off
  set height 0
  set width 0
  attach $PID
  info threads
  detach
  quit
EOF

if ( $status != 0 ) then
  echo "Error occurred in generating Stack Trace (gdb), VM killed."
  kill -KILL $PID
  goto ERROR_RMDIR
else
  echo "done"
endif

awk 'BEGIN { printf("\#\!/bin/csh -f \n /usr/bin/gdb -quiet -n > \$2 << EOF \n set confirm off \n set height 0 \n set width 0 \n define reg \n printf \"\\n    gr0  = 0x%016llx, 0x%016llx, 0x%016llx, 0x%016llx\\n\",\\$r0,\\$r1,\\$r2,\\$r3 \n printf \"    gr4  = 0x%016llx, 0x%016llx, 0x%016llx, 0x%016llx \\n\",\\$r4,\\$r5,\\$r6,\\$r7 \n printf \"    gr8  = 0x%016llx, 0x%016llx, 0x%016llx, 0x%016llx  \\n\",\\$r8,\\$r9,\\$r10,\\$r11 \n printf \"    gr12 = 0x%016llx, 0x%016llx, 0x%016llx, 0x%016llx \\n\",\\$r12,\\$r13,\\$r14,\\$r15 \n printf \"    gr16 = 0x%016llx, 0x%016llx, 0x%016llx, 0x%016llx \\n\",\\$r16,\\$r17,\\$r18,\\$r19 \n printf \"    gr20 = 0x%016llx, 0x%016llx, 0x%016llx, 0x%016llx \\n\",\\$r20,\\$r21,\\$r22,\\$r23 \n printf \"    gr24 = 0x%016llx, 0x%016llx, 0x%016llx, 0x%016llx \\n\",\\$r24,\\$r25,\\$r26,\\$r27 \n printf \"    gr28 = 0x%016llx, 0x%016llx, 0x%016llx, 0x%016llx \\n\",\\$r28,\\$r29,\\$r30,\\$r31 \n printf \"    gr32 = 0x%016llx, 0x%016llx, 0x%016llx, 0x%016llx \\n\",\\$r32,\\$r33,\\$r34,\\$r35 \n printf \"    gr36 = 0x%016llx, 0x%016llx, 0x%016llx, 0x%016llx \\n\",\\$r36,\\$r37,\\$r38,\\$r39 \n printf \"    gr40 = 0x%016llx, 0x%016llx, 0x%016llx, 0x%016llx \\n\",\\$r40,\\$r41,\\$r42,\\$r43 \n printf \"    gr44 = 0x%016llx, 0x%016llx, 0x%016llx, 0x%016llx \\n\",\\$r44,\\$r45,\\$r46,\\$r47 \n printf \"    gr48 = 0x%016llx, 0x%016llx, 0x%016llx, 0x%016llx \\n\",\\$r48,\\$r49,\\$r50,\\$r51 \n printf \"    gr52 = 0x%016llx, 0x%016llx, 0x%016llx, 0x%016llx \\n\",\\$r52,\\$r53,\\$r54,\\$r55 \n printf \"    gr56 = 0x%016llx, 0x%016llx, 0x%016llx, 0x%016llx \\n\",\\$r56,\\$r57,\\$r58,\\$r59 \n printf \"    gr60 = 0x%016llx, 0x%016llx, 0x%016llx, 0x%016llx \\n\",\\$r60,\\$r61,\\$r62,\\$r63 \n printf \"    pr   = 0x%016llx \\n \",\\$pr \n printf \"   b0   = 0x%016llx, 0x%016llx, 0x%016llx, 0x%016llx \\n\",\\$b0,\\$b1,\\$b2,\\$b3 \n printf \"    b4   = 0x%016llx, 0x%016llx, 0x%016llx, 0x%016llx \\n\",\\$b4,\\$b5,\\$b6,\\$b7 \n printf \"    ip   = 0x%016llx               cfm =  0x%016llx\\n\",\\$ip,\\$cfm \n printf \"    bsp  = 0x%016llx          bspstore =  0x%016llx\\n\",\\$bsp,\\$bspstore \n printf \"    rsc  = 0x%016llx              rnat =  0x%016llx\\n\",\\$rsc,\\$rnat \n printf \"    ccv  = 0x%016llx              unat =  0x%016llx\\n\",\\$ccv,\\$unat \n printf \"    fpsr = 0x%016llx               pfs =  0x%016llx\\n\",\\$fpsr,\\$pfs \n printf \"    lc   = 0x%016llx                ec =  0x%016llx\\n\",\\$lc,\\$ec \n end \n attach \$1 \n"); } /^  [0-9]+ (process|Thread) [0-9]+/ { printf("thread apply %d reg \n thread apply %d bt\n",$1,$1); } /^* [0-9]+ (process|Thread) [0-9]+/ { printf("thread apply %d reg \nthread apply %d bt\n",$2,$2); } END { printf("detach \n quit \nEOF\n \n if \( \$status \!= 0 ) then \n  echo \"Error occurred in generating Stack Trace (gdb), VM killed.\" \n  kill -KILL \$1 \n  exit -1 \n endif \n"); }' $TMP >& $CMDFILE

if ( -e $CMDFILE ) then
  chmod +x $CMDFILE
  if ( -e $MYDEVNULL ) then
    rm -f $MYDEVNULL
  endif
  echo "extract stack trace..."
  $CMDFILE $PID $TMP >& $MYDEVNULL
  set ERROR_LOG = `grep "Error occurred in generating Stack Trace" $MYDEVNULL`
  if ( "$ERROR_LOG" != "" ) then
    echo "Error occurred in generating Stack Trace (gdb), VM killed."
    goto ERROR_RMDIR
  else
    echo "done"
  endif
endif

awk '/\[New Thread.*\]/ { next } /^\(.*\)/ { printf("\n"); next; } { print $0 }' $TMP >& $OUTPUT

if ( -e $MYDEVNULL ) then
  rm -f $MYDEVNULL
endif
if ( -e $TMP ) then
  rm -f $TMP
endif
if ( -e $CMDFILE ) then
  rm -f $CMDFILE
endif
if ( -e $WorkDir ) then
  rmdir $WorkDir
endif

echo "stack trace file generated"

exit 0

ERROR_END:
    exit -1

ERROR_RMDIR:
    if ( -e $MYDEVNULL ) then
      rm -f $MYDEVNULL
    endif
    if ( -e $TMP ) then
      rm -f $TMP
    endif
    if ( -e $CMDFILE ) then
      rm -f $CMDFILE
    endif
    if ( -e $WorkDir ) then
      rmdir $WorkDir
    endif
    exit -1

