#! /bin/sh
#set -x
#=========================================================================
# Copyright (C) GemTalk Systems 1986-2024.  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, this script does not apply; to debug, 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 [ "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] [-C configParamsString]
             [-e exeConfPath] [-E exeConfFile] [-U ignoredArg] [applicationArgs] [-- ignoredText]"
HelpText="
    socketFd          - file descriptor of client socket inherited from fork
    -C  configParamsString - a string containing individual configuration parameter settings
                        in the form 'PARAM1=value;PARAM2=value'.
    -e  exeConfPath   - path to an executable file containing default used to configure the gem
    -E  exeConfFile   - path to an executable file used to configure the gem, disables environment variables 
                        and default config name/location search logic. Only one of -e -E is allowed.
    -h  print usage information and exit.
    -N  nativeCodeArg - integer value 0, 1, 2, overrides GEM_NATIVE_CODE_ENABLED values
    -T  tocSizeKB     - a command line option, overrides GEM_TEMPOBJ_CACHE_SIZE values
    -U  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.
    -- ignoredText    - values after the -- are ignored, including valid arguments, but available as 
                        command line args.
 
    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 | -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 -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:
             File specified by the -E or -e argument 
             File, or a file named 'gem.conf' in directory, specified by \$GEMSTONE_EXE_CONF 
                   environment variable.
             File named 'gem.conf' in directory specified by dir: argument in NRS, 
                   in directory specified by the startnetldi -D argument,
                   in home directory of the unix user. 

       The system configuration file only apples when not using -E. The system configuration 
       file is the first one found when searching:
             File, or a file named <hostname>.conf in directory, specified by \$GEMSTONE_SYS_CONF 
                   environment variable.
             \$GEMSTONE/data/<hostname>.conf
             \$GEMSTONE/data/system.conf

   -E disables lookup in GEMSTONE_EXE_CONF/GEMSTONE_SYS_CONF, and default-named 
   files in default locations.  Without -E,  the higher precedence configuration file is used and 
   the other potential configuration files are ignored. 
	
   Settings in the executable configuration file take precedence over settings in the system 
   configuration file. If there are multiple settings for a specific parameter within a single 
   configuration file the value of the last occurrance is used.
"
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.  

The file \$GEMSTONE/bin/services.dat translates the GemStone service name ${comid} 
to a command that executes this script.  

A copy of this script may be edited to change environment variables and the gem 
executable name and/or its directory.  You may edit \$GEMSTONE/sys/services.dat 
to add a translation, or specify the full path to your customized script in the login NRS. 

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

gemname="gem"                   # name of the gem to execute
gemdir=""                       # directory where the gem lives
appName="$gemname"		# application name, for configuration

myPath=`/usr/bin/dirname $0`

# determine gemname's location
if [ "$gemdir" = "" ]; then
  gemdir="$myPath"
fi

if [ ! -f "$gemdir/$gemname" ]; then
  gemdir="$GEMSTONE/sys"
  if [ ! -f "$gemdir/$gemname" ]; then
    echo "${comid}[Error]:   cannot find file $gemdir/$gemname"
    exit 1
  fi  
fi

# realpath not available on Darwin
if [  -f "/usr/bin/realpath" ]; then
  gemstoneEnvVal=`/usr/bin/realpath -e $GEMSTONE`
  if [ "$gemstoneEnvVal/sys" != "$gemdir" ]; then
    echo "ERROR: GEMSTONE/sys and path used to invoke this script are inconsistent"
    echo "GEMSTONE=$GEMSTONE"
    echo "realpath of GEMSTONE/sys=$gemstoneEnvVal/sys"
    echo "script invocation path=$0" 
    exit 1
  fi
else
  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
fi

echo "${comId}[Info]:    the hostname is:  $hName"
echo "   GEMSTONE is:      \"${GEMSTONE}\""
echo "   ${gemname}'s arguments are: $@ "


# This version keeps the log file even if the exit is clean.
# comment out the following line to allow delete on clean exit.
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
