From: goodman_j [goodmanNOgoSPAM@accuwx.com.invalid]
Sent: Wednesday, March 08, 2000 2:02 PM
To: Info-VAX@Mvb.Saic.Com
Subject: Re: how to patch image linked /debug to run without invoking
the debugger when image is run as foreign command.

Here's a DCL command procedure that will clear or reset the
debug and/or trace bits in the image header.  Works for me
great under VMS 6.2 Vax and Alpha.

I made a minor mod to this, but the author is Wolfgang Moeller.
The original is available at the WKU.EDU fileserver (SET_EXE).

$! "patch" an executable to change the LINK /DEBUG and /TRACE
settings
$!
$! usage:	@SET_EXE image [/[no]DEBUG] [/[no]TRACE]
$!
$! w.j.m. 06-nov-1991
$! mod 01-mar-1994 wjm: support AXP/VMS (1.5) executables
$! mod 02-mar-1994 wjm: use IHA$ symbols for VAX; don't permit
{NOTRACE,DEBUG}
$!
$! mod 27-Oct-1998  JG: Open readonly if no changes requested
with qualifers so
$!			status of an installed or running image
can be checked.
$!
$! NOTE: this is *unsupported* stuff!
$!*****
$!
$!* some definitions ...
$!
$ SYS$IMGSTA = %x7FFEDF68
$ IHD$W_ACTIVOFF = 2
$ IHD$L_LNKFLAGS = 32
$ IHD$V_LNKDEBUG = 0
$ IHA$L_TFRADR1 = 0
$ IHA$L_TFRADR2 = 4
$ IHA$L_TFRADR3 = 8
$!
$ e_SYS$IMGSTA_l = %x00000340	! [???]
$ e_SYS$IMGSTA_h = %xFFFFFFFF	! [???]
$ EIHD$L_ACTIVOFF =  16
$ EIHD$L_LNKFLAGS =  80
$ EIHD$V_LNKDEBUG =  0
$ EIHD$L_MAJORID =  0
$ EIHD$L_MINORID =  4
$ EIHD$K_MAJORID =  3
$ EIHD$K_MINORID =  0
$ EIHA$L_TFRADR1 = 8
$ EIHA$L_TFRADR1_H = 12
$ EIHA$L_TFRADR2 = 16
$ EIHA$L_TFRADR2_H = 20
$ EIHA$L_TFRADR3 = 24
$ EIHA$L_TFRADR3_H = 28
$ EIHA$L_TFRADR4 = 32
$ EIHA$L_TFRADR4_H = 36
$!
$ CLI$_MAXPARM = 229528 + 2	! -E-MAXPARM, too many
parameters ...
$ CLI$_CONFQUAL = 231426	! -E-CONFQUAL, conflicting
qualifiers
$ CLI$_INVQUAL = 231434 	! -E-INVQUAL, invalid qualifier
$ CLI$_REQPRMABS = 231442	! -E-REQPRMABS, required
parameter is absent
$ SS$_BADIMGHDR = %x0044	! -F-BADIMGHDR, bad image header
$ SS$_NOSUCHFILE = %x0910 + 4	! -F-NOSUCHFILE, no such file
$!
$ on warning then goto errex
$!
$!
$!* parse the command line ...
$!
$ cmdline = f$edit
(p1+" "+p2+" "+p3+" "+p4+" "+p5+" "+p6+" "+p7+" "+p8,-
		   "trim,compress,upcase")
$ cmdline = f$extract(0,f$locate("!",cmdline),cmdline)	! ...
just to make sure
$ cmdpar = cmdline
$ cmdqual = ""
$cmdparse_loop:
$ cmdparse_qual = "/" + f$element(0," ",f$element(1,"/",cmdpar))
$ if cmdparse_qual.eqs."//" then goto cmdparse_done
$ cmdpar = cmdpar - cmdparse_qual
$ cmdqual = cmdqual + cmdparse_qual
$ goto cmdparse_loop
$cmdparse_done:
$ cmdpar = f$edit(cmdpar,"trim,compress")
$!
$ filename = f$element(0," ",cmdpar)
$ if filename.eqs."" then return CLI$_REQPRMABS		! too
few parameters
$ if f$element(1," ",cmdpar).nes." " then -
	return CLI$_MAXPARM				! too
many parameters
$!
$ q_trace = -1
$ q_debug = -1
$ iq = 0
$q_loop:
$ iq = iq + 1
$ q = f$element(iq,"/",cmdqual)
$ if q.eqs."/" then goto q_loop_end
$ if q.eqs."" then return CLI$_INVQUAL
$ if f$locate(q,"DEBUG").eq.0 then goto q_debug_on
$ if f$locate(q,"TRACE").eq.0 then goto q_trace_on
$ if f$length(q).lt.3 then return CLI$_INVQUAL
$ if f$locate(q,"NOTRACE").eq.0 then goto q_trace_off
$ if f$locate(q,"NODEBUG").eq.0 then goto q_debug_off
$ return CLI$_INVQUAL
$q_debug_on:
$ q_debug = 1
$ goto q_loop
$q_trace_on:
$ q_trace = 1
$ goto q_loop
$q_debug_off:
$ q_debug = 0
$ goto q_loop
$q_trace_off:
$ q_trace = 0
$ goto q_loop
$!
$q_loop_end:
$ if q_debug.eq.1.and.q_trace.eq.0 then return CLI$_CONFQUAL
$ if q_debug.eq.1 then q_trace = 1	! /DEBUG requires /TRACE
$ if q_trace.eq.0 then q_debug = 0	! /NOTRACE
requires /NODEBUG
$ read_only = 0
$ if q_debug.eq.-1.and.q_trace.eq.-1 then read_only = 1
$!
$!
$!* open file ...
$!
$ fs = f$parse(filename,".EXE")
$ if fs.eqs."" then return SS$_NOSUCHFILE
$!
$ close/nolog SET_EXE_FILE
$ if (read_only)
$    then $ open/read/share SET_EXE_FILE 'fs'
$    else $ open/read/write/share SET_EXE_FILE 'fs'
$ endif
$!
$ if f$file(fs,"RFM").nes."FIX" .or.-
     f$file(fs,"MRS").ne.512 then return SS$_BADIMGHDR	! don't
like this file
$!
$!
$!* read and decode image header ...
$!
$ read SET_EXE_FILE b
$!
$ e_major = f$cvui(EIHD$L_MAJORID*8, 32, b)
$ e_minor = f$cvui(EIHD$L_MINORID*8, 32, b)
$ eihd = e_major.eq.EIHD$K_MAJORID .and.
e_minor.eq.EIHD$K_MINORID
$!
$ if eihd
$ then
$	write SYS$OUTPUT fs," assumed to be an AXP executable"
$!
$	lnkdebug = f$cvui(EIHD$L_LNKFLAGS*8 + EIHD$V_LNKDEBUG,
1 ,b)
$!
$	actoff = f$cvui(EIHD$L_ACTIVOFF*8,32,b)
$	tra1_l = f$cvui((actoff + EIHA$L_TFRADR1)*8, 32,b)
$	tra1_h = f$cvui((actoff + EIHA$L_TFRADR1_H)*8, 32,b)
$	tra2_l = f$cvui((actoff + EIHA$L_TFRADR2)*8, 32,b)
$	tra2_h = f$cvui((actoff + EIHA$L_TFRADR2_H)*8, 32,b)
$	tra3_l = f$cvui((actoff + EIHA$L_TFRADR3)*8, 32,b)
$	tra3_h = f$cvui((actoff + EIHA$L_TFRADR3_H)*8, 32,b)
$	tra4_l = f$cvui((actoff + EIHA$L_TFRADR4)*8, 32,b)
$	tra4_h = f$cvui((actoff + EIHA$L_TFRADR4_H)*8, 32,b)
$!
$	lnktrace = tra1_l.eq.e_SYS$IMGSTA_l .and.
tra1_h.eq.e_SYS$IMGSTA_h
$ else
$	write SYS$OUTPUT fs," assumed to be a VAX executable"
$!
$	lnkdebug = f$cvui(IHD$L_LNKFLAGS*8 + IHD$V_LNKDEBUG,
1 ,b)
$!
$	actoff = f$cvui(IHD$W_ACTIVOFF*8,16,b)
$	tra1 = f$cvui((actoff + IHA$L_TFRADR1)*8, 32,b)
$	tra2 = f$cvui((actoff + IHA$L_TFRADR2)*8, 32,b)
$	tra3 = f$cvui((actoff + IHA$L_TFRADR3)*8, 32,b)
$!
$	lnktrace = tra1.eq.SYS$IMGSTA
$ endif
$!
$ if lnkdebug .and. .not.lnktrace then return SS$_BADIMGHDR
	! can't be
$!
$!
$ chg = 0
$ txt = "/TRACE setting: "
$ txt = txt + f$element(lnktrace,"|","OFF|ON")
$ if q_trace.ge.0 .and. q_trace.ne.lnktrace
$ then
$	chg = 1
$	txt = txt + " => " + f$element(q_trace,"|","OFF|ON")
$	if lnktrace
$	then
$		if eihd
$		then
$			b[(actoff + EIHA$L_TFRADR1)*8,32] =
tra2_l
$			b[(actoff + EIHA$L_TFRADR1_H)*8,32] =
tra2_h
$			b[(actoff + EIHA$L_TFRADR2)*8,32] =
tra3_l
$			b[(actoff + EIHA$L_TFRADR2_H)*8,32] =
tra3_h
$			b[(actoff + EIHA$L_TFRADR3)*8,32] =
tra4_l
$			b[(actoff + EIHA$L_TFRADR3_H)*8,32] =
tra4_h
$			b[(actoff + EIHA$L_TFRADR4)*8,32] = 0
$			b[(actoff + EIHA$L_TFRADR4_H)*8,32] = 0
$		else
$			b[(actoff + IHA$L_TFRADR1)*8,32] = tra2
$			b[(actoff + IHA$L_TFRADR2)*8,32] = tra3
$			b[(actoff + IHA$L_TFRADR3)*8,32] = 0
$		endif
$	else
$		if eihd
$		then
$			if tra4_l.ne.0 .or. tra4_h.ne.0 then -
				return SS$_BADIMGHDR	! too
many trfadr's
$			b[(actoff + EIHA$L_TFRADR1)*8,32] =
e_SYS$IMGSTA_l
$			b[(actoff + EIHA$L_TFRADR1_H)*8,32] =
e_SYS$IMGSTA_h
$			b[(actoff + EIHA$L_TFRADR2)*8,32] =
tra1_l
$			b[(actoff + EIHA$L_TFRADR2_H)*8,32] =
tra1_h
$			b[(actoff + EIHA$L_TFRADR3)*8,32] =
tra2_l
$			b[(actoff + EIHA$L_TFRADR3_H)*8,32] =
tra2_h
$			b[(actoff + EIHA$L_TFRADR4)*8,32] =
tra3_l
$			b[(actoff + EIHA$L_TFRADR4_H)*8,32] =
tra3_h
$		else
$			if tra3.ne.0 then -	! too many
transfers addresses
				return SS$_BADIMGHDR
$			b[(actoff + IHA$L_TFRADR1)*8,32] =
SYS$IMGSTA
$			b[(actoff + IHA$L_TFRADR2)*8,32] = tra1
$			b[(actoff + IHA$L_TFRADR3)*8,32] = tra2
$		endif
$	endif
$ endif
$ write SYS$OUTPUT txt
$!
$ txt = "/DEBUG setting: "
$ txt = txt + f$element(lnkdebug,"|","OFF|ON")
$ if q_debug.ge.0 .and. q_debug.ne.lnkdebug
$ then
$	chg = 1
$	txt = txt + " => " + f$element(q_debug,"|","OFF|ON")
$	if eihd
$	then
$		b[EIHD$L_LNKFLAGS*8 + EIHD$V_LNKDEBUG, 1] = 1 -
lnkdebug
$	else
$		b[IHD$L_LNKFLAGS*8 + IHD$V_LNKDEBUG, 1] = 1 -
lnkdebug
$	endif
$ endif
$ write SYS$OUTPUT txt
$!
$!
$!* update the file ...
$!
$ if chg then write/update/symbol SET_EXE_FILE b
$!
$ close SET_EXE_FILE
$!
$ exit
$!
$!
$!* some error ...
$!
$errex:
$ status = $status
$ set noon
$ close/nolog SET_EXE_FILE
$ exit status.or.%x10000000

In article <8a606q$pnm$1@nnrp1.deja.com>, snead_george_w@my-
deja.com wrote:
>Hi everybody,
>
>When you have completed debugging a program which
>you linked with "/debug" and are satisfied with
>its behavior, you can run the image, declining to
>invoke the debugger with the following switch:
>
>$ run /nodebug my_dir:my__image.exe
>
>This is especially useful if you plan to run the
>program linked debug in a batch procedure,
>because otherwise, the program will exit without
>executing, if you simply run the image.  ( I
>believe that the debugger gains control, tries to
>take its input from sys$input which is the batch
>file. It gets the control-z passed to it from dcl
>because DCL sees in that the next record from the
>batch stream, is not debugger input, but a dcl
>command starting with the dollar sign.  So, the
>debugger prompt gets control-z and exits the
>image.)
>
>But what if your program must be defined as a
>foreign command in order to take parameters from
>the command line in this fashion:
>
>$ foreign_cmd = "$dev:[dir]image.exe"
>$ foreign_cmd  para_1 para_2
>
>The foreign command prevents you from declining
>the debugger in the usual way of -
>$ run /nodebug my_image.exe
>
>Does anyone have a way to run a debugged image as
>a foreign command in a batch job and prevent the
>debugger from being activated?  I'm familiar with
>the option of putting debugger "go" commands in a
>debugger command file pointed to by dbg$init
>logical, so I'm exploring other possibilities.
>
>Years back, there was a short patch procedure
>applied against a field in the image's header
>which disabled the debugger from starting up when
>the image was run.  Does anyone remember this
>patch.  Or, is there a better way?
>
>Thanks again,
>
>George Snead
>
>
>Sent via Deja.com http://www.deja.com/
>Before you buy.
>
>


J. Goodman
----------
"Any technology sufficiently advanced is indistinguishable
from magic."  Clarke

* Sent from RemarQ http://www.remarq.com The Internet's Discussion Network *
The fastest and easiest way to search and participate in Usenet - Free!