Nepřípustná Instrukce při přeplnění paměti – Pascal – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Nepřípustná Instrukce při přeplnění paměti – Pascal – Fórum – Programujte.comNepřípustná Instrukce při přeplnění paměti – Pascal – Fórum – Programujte.com

 

Mircosoft+1
Věrný člen
31. 7. 2007   #1
-
0
-

Ahoj programátoři, potřeboval bych zase jednou trochu poradit.

Mám program v TP 7, real mód. Vytvářím poměrně dlouhý spojový seznam s prvky o velikosti 8 B (vím, že ve skutečnosti se pro každý alokuje 16 B) a potřebuju spolehlivě ošetřit situaci, kdy zaplní celou paměť. Před každým použitím New na vytvoření nového prvku si Maxavailem zkontroluju, jestli je na něj dost paměti; pro jistotu to beru s rezervou a jestli není volných aspoň 64 B, tak už nic nealokuju. Teoreticky je všechno v pořádku, většinou takhle zaplnění paměti odchytím, zpracuju a žádný Heap Overflow se nekoná. Jenže cca ve 30% případů mi program spadne s windowsí hláškou "program se pokusil provést nepřípustnou instrukci a bude ukončen", což znamená, že někde zapisuju do nealokované paměti. Jenže nic takového tutově nedělám.

Takže otázka zní: může třeba nějak kolidovat hromada se zásobníkem? Že bych třeba normálně na hromadě alokoval proměnnou, zapsal bych do ní, ale přepsal bych tím něco v zásobníku, třeba lokální proměnné nebo návratovou adresu nějaké procedury?

P.S.: kdybych to chtěl dělat ve FP nebo Delphi, tak bych to udělal, jenže nechci, tak mě na ně prosím neodkazujte.

Nahlásit jako SPAM
IP: ...–
Chceš-li lepší odpověď, polož lepší otázku.
Moje stránka.
Laaca
~ Anonymní uživatel
225 příspěvků
1. 8. 2007   #2
-
0
-

Zvláštní. Zkoušel jsi dělat druhý kontrolní test ještě pomocí MemAvail? Co si zkusit pohrát s nastavením heapu pomocí direktivy $M ?

Nahlásit jako SPAM
IP: ...–
Mircosoft+1
Věrný člen
1. 8. 2007   #3
-
0
-

$M jsem zkoušel. Hromadu jsem skrouhnul postupně až na 50 kB, ale nepomohlo to. Stejně tak změna velikosti zásobníku.

Memavail mě původně nenapadl. Takže jsem ho zkusil (přidán do všech podmínek), ale nezabralo to. Ještě jsem zkusil zvětšit rezervu (když není volných aspoň 100 B, tak nealokuju), ale jsem na tom pořád stejně.

Problém je, že mi tady nepomůže krokování a watche, protože ta chyba se objevuje víceméně náhodně. Někdy se zaplněnou paměť odchytit podaří, jindy ne. Už jsem viděl hlášky "program se pokusil provést nepřípustnou instrukci", "program vyvolal výjimku na adrese...", "program porušil všeobecnou ochranu", "program vyvolal blíže neurčenou výjimku" a pár dalších. Podle té první bych tipoval, že se (občas) CS:IP dostane na nějaký nesmysl, což znamená buď že jsem si přepsal kus programu v code segmentu (což je blbost), nebo že se z těla té procedury přepsala její návratová adresa uložená v zásobníku a procedura se pak retla neznámo kam. Vím, že zásobník se plní směrem dolů (push snižuje SP a pop ho zvyšuje), ale nevím, kde začíná ani kde by měl normálně končit a jestli TP nějak kontroluje, jestli nekoliduje s hromadou a jestli New nealokuje paměť na území zásobníku.

Ještě si s tím zkusím chvíli hrát, a uvidíme, jak to dopadne.

Hmm... a nebo... ... právě mě napadla brutální myšlenka:

procedure ...(...);

Begin
asm
pop návratovou adresu ze zásobníku do nějakých proměnných
push zase všechno zpátky na zásobník, aby procedura nic nepoznala
end;
...tady někde ta chyba vzniká...
asm
pop totéž co na začátku, ale získaná data zahodit
push místo nich ty uložené původní hodnoty
end;
End;

Jestli selže všechno ostatní, tak zkusím i tohle. Ale asi by to nebylo nic jednoduchého, protože ta procedura není pod direktivou Assembler, je docela dlouhá, má dvě lokální podprocedury a hromadu lokálních proměnných, takže najít v zásobníku návratovou adresu bude asi docela dřina... no nic, tohle bude až poslední možnost.

Nahlásit jako SPAM
IP: ...–
Chceš-li lepší odpověď, polož lepší otázku.
Moje stránka.
Mircosoft+1
Věrný člen
2. 8. 2007   #4
-
0
-

Vyřešeno.
Já hlava dubová, nakonec to všechno způsobil úplně jiný úsek kódu než jsem původně myslel (jedno zákeřně podteklé statické lokální pole), ten spojový seznam už byl OK.

Závěr: Maxavail funguje spolehlivě, kolize zásobníku a hromady netřeba se obávat. A příště nebudu tolik pospíchat s psaním do fóra :-].

Nahlásit jako SPAM
IP: ...–
Chceš-li lepší odpověď, polož lepší otázku.
Moje stránka.
Smokie0
Expert
2. 8. 2007   #5
-
0
-

Kludne sa mozes aj nabuduce ponahlat. Kazdy problem, ktory sa tu objavi, aj vyrieseny, moze pomoct inym ludom :)

Nahlásit jako SPAM
IP: ...–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 17 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý