Re:
> Per Ostberg writes:
> >1) the running program needs to extensively check if there is a
> >breakpoint set
> >2) no optimization can be made by the compiler
>
> The actual reason is #2: when the compiler is asked to produce symbolic
Actually, there's far more overhead due to #1, if you rephrase it a bit.
The problem is that at every procedure entry, procedure exit, and
(possibly, depending upon compiler implementation) every statement,
there's a "conditional breakpoint" instruction emitted by the compiler (and,
unless something special is done at link time, is in the program binary code).
Let's just assume the common conditional breakpoints are emitted (procedure
entry and procedure exit). That's going to add about 78 microseconds per
procedure call (on a 3000/968).
Yes, #2 is important as well...but it depends upon how many procedure
calls you make. If you have big procedures that loop a lot within themselves,
#2 is more important than #1. If you have a lot of procedures that do
a small amount each, #1 is more important.
> So it's impossible to do symbolic debugging on optimized code on the
> HP 3000, and difficult even on those few systems which support it.
It's surprisingly good on HP-UX as of 11.0 (or so) ... they put a lot
of effort into this area in that group that ignores the HP 3000 :(
> Even with symbolic debugging turned on, the running
> program never has to check for breakpoints; that's done
> (in effect) by the hardware. When you set a breakpoint in a program, the
> debugger replaces the first instruction of the statement on which you've
> set the breakpoint with an illegal instruction.
True...but, "symdebug 'toolset'$ emits breakpoints *into the code stream*.
BTW, you can tell the linker to convert those breakpoints into NOPs
by specifying "NODEBUG" on your LINK command.
They're called "conditional" breakpoints because they don't always
interrupt your program all the way back to the debugger. If, however,
you run your program as:
:run prog; debug
trap t a
c
then you'll pop up into the debugger at every procedure entry and exit!
Here's a sample program Pascal program to demonstrate the potential
overhead. Timings follow it.
----------------cut here------------------
$symdebug 'toolset'$
program debug_test (output);
var
old_plabel : integer;
Function proctime : integer; intrinsic;
Procedure terminate; intrinsic;
Function timer : integer; intrinsic;
Procedure xcontrap; intrinsic;
{**************************************************************}
function add1 (n : integer) : integer;
begin
add1 := n + 1;
end {add1 proc};
{**************************************************************}
procedure cy_handler;
begin
terminate;
end {cy_handler proc};
{**************************************************************}
procedure looper (n : integer);
var
loops : integer;
begin
loops := 0;
while loops < n do
loops := add1 (loops);
end {looper proc};
{**************************************************************}
procedure test (n : integer);
var
ct : integer;
et : integer;
rslt : integer;
begin
et := timer;
ct := proctime;
looper (n);
ct := proctime - ct;
et := timer - et;
if et < 0 then {handle TIMER rollover}
et := et + 2073600000; {# of millisecs in 24 days}
;
writeln ('looper (', n:8, ') took ',
ct:8, ' CPU, ',
et:8, ' elapsed millisecs');
end {test proc};
{**************************************************************}
begin
xcontrap (baddress (cy_handler), old_plabel);
test ( 1000);
test ( 10000);
test (100000);
end.
Here's the binary code, showing a couple of the conditional breakpoints:
$3a ($6c) nmdebug > dc looper, 10
000050fc looper 6bc23fd9 STW 2,-20(0,30)
00005100 looper+$4 37de0080 LDO 64(30),30
00005104 looper+$8 6bda3f39 STW 26,-100(0,30)
00005108 looper+$c 0001400e BREAK (proc enter)
0000510c looper+$10 6bc03f91 STW 0,-56(0,30)
00005110 looper+$14 4bd33f91 LDW -56(0,30),19
00005114 looper+$18 4bd43f39 LDW -100(0,30),20
00005118 looper+$1c 8a934032 COMBF,<,N19,20,looper+$3c
0000511c looper+$20 e85f1e75 BL add1,2
00005120 looper+$24 4bda3f91 LDW -56(0,30),26
00005124 looper+$28 6bdc3f91 STW 28,-56(0,30)
00005128 looper+$2c 4bd53f91 LDW -56(0,30),21
0000512c looper+$30 4bd63f39 LDW -100(0,30),22
00005130 looper+$34 82d55fcd COMBT,< 21,22,looper+$20
00005134 looper+$38 08000240 OR 0,0,0
00005138 looper+$3c 0001600e BREAK (proc exit)
Note the "BREAK (proc enter)" and "BREAK (proc exit)" ... those are the
procedure entry/exit breakpoints.
LINK ...; NODEBUG
RUN...
looper ( 1000) took 0 CPU, 0 elapsed millisecs
looper ( 10000) took 3 CPU, 3 elapsed millisecs
looper ( 100000) took 35 CPU, 34 elapsed millisecs
LINK ...
RUN
looper ( 1000) took 78 CPU, 79 elapsed millisecs
looper ( 10000) took 780 CPU, 795 elapsed millisecs
looper ( 100000) took 7875 CPU, 7916 elapsed millisecs
Stan Sieler [log in to unmask]
www.allegro.com/sieler/wanted/index.html www.allegro.com/sieler
|