#! /bin/sh
#set -x
#=========================================================================
# Copyright (C) GemTalk Systems 1986-2020.  All Rights Reserved.
#
# Name - gemnetdebug
#
# Purpose - Script to set environment and start a RPC gem for debugging.
#
#  This script is provided for debugging applications, such as
#  for debugging OutOfMemory situations.  This script can be edited
#  to set the debugging options below, without disturbing the
#  $GEMSTONE/sys/gemnetobject file.  
#  Then in GBS or topaz -r ,  use the gemnetdebug network
#  resource to login a debugging session, and the gemnetobject
#  resource to login a normal session.
#
#  If using a topaz -l, you can set any of the enviroment variables
#  discussed below interactively before invoking topaz -l , to
#  have them take effect in the linked session .
#=========================================================================

if [ "a$GEMSTONE" = "a" ]; then
  echo "ERROR: GemStone scripts require a GEMSTONE environment variable."
  echo "       Please set it to the directory where GemStone resides."
  exit 1
fi

if [ "x$PATH" = "x" ]; then PATH=:/bin:/usr/bin:/usr/ucb; export PATH; fi 

# error control - do not allow hup
trap '' 1

comid="gemnetobject"			# this script's name
Syntax="Usage: ${comid} -h 
       ${comid} TCP <socketFd> [ -T tocSizeKB] [-N nativeCodeArg]   
                        [-e exeConfPath] [-C configParamsString] [-U ignoredArg] [applicationArgs]"
HelpText="
    socketFD        - file descriptor of client socket inherited from fork
    tocSizeKB       - a command line option, overrides GEM_TEMPOBJ_CACHE_SIZE values
    nativeCodeArg   - integer value 0, 1, 2, overrides GEM_NATIVE_CODE_ENABLED values
    exeConfPath     - path to an executable file used to configure the gem
    configParamsString - a string containing individual configuration parameter
         settings in the form 'PARAM1=value;PARAM2=value'.
    ignoredArg      - any argument (gem ignores this argument)
    applicationArgs - any arguments or tokens other than the above anywhere on the command line 
                     from the NRS are also ignored by the gem.  

    The 'TCP <socketFd>' portion of the gem command line is generated by netldi.
    The -h option should only be used interactively to print this usage.
    The remaining arguments (-T, -N, -e, -C, -U ) may appear in any
    order and come from the #task portion of the gemnetobject NRS specified by
    the remote GCI client.

    If any of the -T -N -e -C occurs more than once, the value of the last occurrance
    is used.

    All arguments, including ignoredArg and applicationArgs, are passed to the Gem and 
    available to the application via System class >> commandLineArguments.

  The Gem configuration parameters to be used by the Gem are determined in the
   following precedence order.
       values in -T argument , -N argument
       values in -C  argument
       values in the executable config file.
       values in the system config file.

       The executable configuration file is the first one found when searching:
             path from \$GEMSTONE_SYS_CONF environment variable
             \$GEMSTONE/data/system.conf

        The system configuration file is the first one found when searching:
             path from -e argument
             path from \$GEMSTONE_EXE_CONF environment variable
             'gem.conf' in current directory of the gem process (the current directory
                    set from #dir in gemnetobject NRS, else from netldi defaults)

    The higher precedence setting is used and lower precedence settings are ignored.
    If there are multiple settings for a specific parameter at the same level, that
    is in the same executable or system configuration file, or within the -C argument,
    the last one that is found applies and earlier settings for that parameter
    within the file or string are ignored.
"
Descript="
This shell script is invoked by a netldi to start a GemStone 
session process with extra debugging output, in response 
to a request of the netldi for a GemStone session.  
By default, the file \$GEMSTONE/bin/services.dat translates the GemStone service 
name gemnetdebug to a command that executes this script.  If no such translation 
is found, a command \$HOME/gemnetdebug is executed instead.

A copy of this script may be edited to change the default gemname and/or gemdir
for custom gem executables.

Examples of using arguments:

topaz> set gemnetid 'gemnetdebug -T 500000 -e devStoneMonitor.conf'

topaz> set gemnetid '!@fiji!#netldi:54321!gemnetdebug -C GEM_TEMPOBJ_OOMSTATS_CSV=TRUE;GEM_ABORT_MAX_CRS=2; -N 1 devStoneMonitor'

"

# give a little help
if [ "x$1" = "xhelp" ] || [ "x$1" = "x-h" ] || [ "x$1" = "x-H" ]; then
  echo "$Syntax"; echo "$HelpText"; echo "$Descript"; exit
fi

###########################################################################
################# User-definable symbols 
###########################################################################
gemname="gem"                   # name of the gem to execute
gemdir=""                       # directory where the gem lives
# GEMSTONE_SYS_CONF=""  # default is $GEMSTONE/data/system.conf
# GEMSTONE_EXE_CONF=""  # default is `pwd`/gem.conf
###########################################################################
#netldiSpec not set
#runpgsvrSpec not set
appName="$gemname"		# application name, for configuration

# determine gemname's location
if [ "$gemdir" = "" ]; then
  gemdir="$GEMSTONE/sys"
fi
if [ ! -f "$gemdir/$gemname" ]; then
  echo "${comid}[Error]:   cannot execute file $gemdir/$gemname"
  exit 1
fi

# show what we have

echo "${comId}[Info]:    the hostname is:  $hName"
echo "   GEMSTONE is:      \"${GEMSTONE}\""
echo "   ${gemname}'s location is: $gemdir"
echo "   system config file is:     $GEMSTONE_SYS_CONF"
echo "   GEMSTONE_EXE_CONF = $GEMSTONE_EXE_CONF"
echo "   ${gemname}'s arguments are: $@ "

# unset this, in case it was set in the parent process and we inherited it.
unset GEMSTONE_KEEP_LOG

# The default behaviour is to keep this process's log file if it exits
# normally. If you want to keep this process's log file even on normal exit
# then comment out the following
GEMSTONE_KEEP_LOG=1 ; export GEMSTONE_KEEP_LOG

# By default a gem will raise its number of descriptors to whatever the
# hard limit is. By setting GEMSTONE_MAX_FD to a positive number the
# gem will only raise its descriptors to that number.
# If GEMSTONE_MAX_FD is set to 0 then the gem will not modify its descriptor
# limit
# GEMSTONE_MAX_FD=? ; export GEMSTONE_MAX_FD

# Optional environment variables to increase the send and receive buffer sizes
# for the socket connecting the gem to its client.  The maximum values allowed
# are determined by the operating system.  Values that attempt to reduce the size
# of the buffers below the operating system defaults are ignored.
#
# GS_SOCK_SEND_BUF_SIZE=? ; export GS_SOCK_SEND_BUF_SIZE
# GS_SOCK_RECV_BUF_SIZE=? ; export GS_SOCK_RECV_BUF_SIZE

# Environment variable which turns on tracing of socket operations.  Enabling this
# variable will cause many extra messages to be printed to the gem log.
#
# GEMSTONE_SOCKET_DEBUG=1 ; export GEMSTONE_SOCKET_DEBUG

# --------------------------------
# Following verify and print controls  are in terms of markSweep count
# and scavenge count .  Verification or printing will start at the 
# specified scavenge or mark sweep (counted from GciLogin) , and continue
# for the life of the session .  To enable a specific item,
# uncomment the definition and the export and edit the count value.

# Verification of object memory at scavenge, for use when
# memory corruption or GC bugs are suspected.
# Warning GS_DEBUG_VMGC_VERIFY_SCAV uses lots of cpu time.
# 
# GS_DEBUG_VMGC_VERIFY_SCAV=1
# export GS_DEBUG_VMGC_VERIFY_SCAV

# Verification of object memory at mark sweep, for use when
# memory corruption or GC bugs are suspected.
# GS_DEBUG_VMGC_VERIFY_MKSW=1
# export GS_DEBUG_VMGC_VERIFY_MKSW

# Verification of object memory at logout, for use when
# memory corruption or GC bugs are suspected.
# GS_DEBUG_VMGC_VERIFY_LOGOUT=1
# export GS_DEBUG_VMGC_VERIFY_LOGOUT

# Print two line GC summary for each scavenge.
# warning, GS_DEBUG_VMGC_PRINT_SCAV can produce lots of output
# GS_DEBUG_VMGC_PRINT_SCAV=1
# export GS_DEBUG_VMGC_PRINT_SCAV

# Print two line GC summary for each MarkSweep .
#  also enables detailed code_gen printing on OutOfMemory
# GS_DEBUG_VMGC_PRINT_MKSW=1
# export GS_DEBUG_VMGC_PRINT_MKSW

# Print detailed memory usage (about 20 lines) for each mark sweep.
# GS_DEBUG_VMGC_PRINT_MKSW_MEMORY=1
# export GS_DEBUG_VMGC_PRINT_MKSW_MEMORY

# Print Smalltalk stack  at scavenge (warning lots of output)
# GS_DEBUG_VMGC_SCAV_PRINT_STACK=1
# export GS_DEBUG_VMGC_SCAV_PRINT_STACK

# Print Smalltalk stack at mark sweep.
# GS_DEBUG_VMGC_MKSW_PRINT_STACK=1
# export GS_DEBUG_VMGC_MKSW_PRINT_STACK

# Print C stack at scavenge
# warning, GS_DEBUG_VMGC_SCAV_PRINT_C_STACK can cause extreme slow downs,
#   2 seconds per scavenge. 
# GS_DEBUG_VMGC_SCAV_PRINT_C_STACK=1
# export GS_DEBUG_VMGC_SCAV_PRINT_C_STACK

# Print C stack at markSweep
# warning, GS_DEBUG_VMGC_MKSW_PRINT_C_STACK can cause extreme slow downs,
#   2 seconds per markSweep. 
# GS_DEBUG_VMGC_MKSW_PRINT_C_STACK=1
# export GS_DEBUG_VMGC_MKSW_PRINT_C_STACK

#  Print transaction boundaries (begin/commit/abort) , 1 line each
# GS_DEBUG_VM_PRINT_TRANS=1
# export GS_DEBUG_VM_PRINT_TRANS

#  Do not print Smalltalk stack and instance counts when OutOfMemory error occurs
# GS_DEBUG_VMGC_VERBOSE_OUTOFMEM=0
# export GS_DEBUG_VMGC_VERBOSE_OUTOFMEM
#
# Trace method compiles
#  0 = no tracing, 1 = one line (class,selector) of each method compiled
#  2 = in addition bytecode disassembly 
#  3 = in addition native code assembly listing 
GS_DEBUG_COMPILE_TRACE=0
export GS_DEBUG_COMPILE_TRACE

# --------------------------------
# GS_DEBUG_VMGC_PRINT_MKSW_MEMORY_USED specifies a percent of memory 
# used threshold.
# If the GS_DEBUG_VMGC_PRINT_MKSW_MEMORY_USED environment variable
# is not defined, the default is 75 percent.
# At the end of each mark sweep, if the percent used is greater than
# this threshold, the markSweep is printed, the Smalltalk stack 
# is printed to stdout, and the threshold is raised by 5 percent.  Thus in
# situation producing error 4067, OutOfMemory, you should get several
# Smalltalk stacks printed in the gem log file before the session dies.

# GS_DEBUG_VMGC_PRINT_MKSW_MEMORY_USED=75
# export GS_DEBUG_VMGC_PRINT_MKSW_MEMORY_USED

# --------------------------------

# GS_DEBUG_VMGC_MKSW_MEMORY_USED_SOFT_BREAK specifies a percent of memory
# used threshold.
# If the GS_DEBUG_VMGC_MKSW_MEMORY_USED_SOFT_BREAK environment variable
# is not defined, the default is infinity. 
# At the end of each mark sweep, if the percent used is greater than
# this threshold, a SoftBreak (error 6003) is generated, and
# the threshold is raised by 5 percent. 
#
# Suggested setting of 75% is enabled here.
#
# Uncomment if you want to get a soft break when almost out of memory.
#
#GS_DEBUG_VMGC_MKSW_MEMORY_USED_SOFT_BREAK=75
#export GS_DEBUG_VMGC_MKSW_MEMORY_USED_SOFT_BREAK

#-----------------------------------------
# GS_CORE_TIME_OUT controls how long a process waits for a C debugger
# to attach after hitting an assertion failure or a SEGV .
GS_CORE_TIME_OUT=60
export GS_CORE_TIME_OUT


# start up gemname   
#  	sleep 3600 # enable for DEBUGGING
#       exit 0 # enable for DEBUGGING
exec "$gemdir/$gemname" "$@"
# with the above exec nothing after this is ever executed
