NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!
NOVINKA - Online rekvalifikační kurz Java programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.

Programátorská Akta X

UFOExistují věci mezi nebem a zemí. Na první pohled nevysvětlitelné události, které bohužel provází i nás - programátory. Jde o případy, kde se obrovskou shodou náhod stalo něco, co se vymyká lidskému chápání. Níže naleznete několik takových případů, kdy jsem nevěděl, jestli je to, co se děje, možné, nebo se mi to jen zdá.

 

Pascal: "Neznám příkaz end"

Pascalovský debugger mi hlásil chybu na konci jedné procedury, konkrétně na řádku, na kterém nebylo napsáno nic jiného, než "end;". Nejprve jsem hledal chybu v řádku nad tím, ale nic. Nakonec jsem zakomentoval celé tělo procedury a nechal jen begin a end. Ta samá chyba: "Neznámý identifikátor". Vymazal jsem vše na řádku a napsal ho znovu - nic se nezměnilo. Poté jsem otevřel pas soubor v textovém editoru (ne Notepadu, ale v pokročilejším) v naději, že se tam vyskytuje nějaký znak, který Pascal nezobrazí a zároveň ho bere za chybu, ale žádný tam nebyl. Vymazal jsem pro jistotu celý řádek a napsal ho znovu. A co se nestalo: "Compile successful" . Z autora kódu nakonec vypadlo, že ho nepsal přímo v Pascalovském editoru, ale v něčem jiném. Musel se mu tam vloudit nějaký znak, který se nezobrazil ani v Pascalu a ani v textovém editoru. Ten jsem vymazal spolu s calým řádkem, předtím jsem totiž v Pascalu vymazal jen end a středník, znak tam asi zůstal. Zajímavé, že? :)

 

Delphi: "Nelze vložit tlačítko na formulář, aneb někde to asi teče"

Toto je opravdu velký kousek, ale stojí za přečtení, je to asi můj největší programátorský akt X. Svůj velký projekt Organizer Student DOG jsem psal zpočátku v Delphi 7 a až do té doby s ním nebyl žádný problém. Jednoho krásného dne mi ale při pokusu o vložení nového bitbuttonu na formulář Delphi zahlásily nějakou chybu, již si přesně nevybavuji znění, byla to nějaká vyjímka plná nesmyslných adres. K mému zděšení jsem nebyl schopen na formulář nic přidat. "Že by tam toho bylo moc? Vždy? v Delphi jsou napsány i softwaru pro banky, ty přeci musí mít na formuláři více komponent, než já!, říkám si." Projekt jsem zavřel a otevřel znovu, tak samá chyba. Po nějaké době jsem se o to pokusil znovu a vše bylo v pořádku. Asi nějaká náhoda, utěšuji se a programuji dál. Po přidání druhého tlačítka ale opět vyskočila ta samá hláška a tlačítko se nevložilo. Když jsem jich pár vymazal, šly zase vložit, ale další jsem tam potom nenacpal. To samé se začalo dít i s dalšími komponentami. Program byl nepoužitelný. Došel jsem k závěru, že se něco muselo po**** v Delphi a ony nějak poškodily zdrojové kódy k formuláři.

Nainstaloval jsem si tedy na notebook Delphi 2007 (stejně jsem do nich chtěl program jednou převést) a začal tvořit všechny formuláře znovu. Byla to neskutečná práce, přítelkyně seděla u velkého PC a hlásila "bitbutton 131, left 10 top 150 caption uložit, width 50 height 25 onclick procedure bitbutton131click". Já na notebooku naklikával komponentu po komponentě, a že jich bylo. po několika dnech jsem napojil nové formuláře na kód programu a vše spustil: "V pořádku". Nové komponenty šly na formulář vkládat v pořádku. Zdrojáky formuláře se tedy nějak poškodily. Ale to nebylo všechno :)

Po několika dnech mi program začal házet chybovou hlášku "Access violation", vždy při práci s kalendářem, ale nedokázal jsem přijít na to, jak ji spolehlivě vyvolat. Také mi bylo divné, že se mi nikdy předtím neobjevila, když byl program ještě kompilován pod Delphi 7. V zoufalosti jsem se obrátil na jediného člověka, který by mohl vědět, o co jde, na mého strejdu Petra, který se programováním zabývá na vysoké úrovni. Když jsem k němu dorazil, žádná chyba se zamozřejmě neukázala. Klikali jsme v kalendáři na všechno možné a nic. Vypadal jsem, že nemám všech pět pohromadě, ale po hodině a půl pokusů nám chyba nakonec vyskočila.

Podařilo se nám ji vyvolat kliknutím na tlačítka a dny v kalendáři v určitém pořadí!. Jednalo se vždy o stejnou adresu v paměti, kde došlo k vyjímce. Po dalších několika hodinách zběsilého zkoumání jsme vyloučili chybu v kódu zbývala jediná možnost - musí to dělat komponenta na správu obrázků. A světe div se, ona si opravdu někdy odplivla někam do paměti, která ji nepatřila. Komponenta se jmenovala delfi_listbox a umožňovala do listboxu vložit obrázky. Používal jsem ji, protože v Delphi 7 nebyla žádná vestavěná alternativa. V Delphi 2007 jsme nalezli podobnou komponentu přímo od výrobců, tu jsem zaměnil za delfi_listbox a chyba byla pryč.

Jaké je tedy rozřešení? Komponenta delfi_listbox byla špatně napsaná (ne mnou) a v jednom, takřka nevyvolatelném případě se snažila zapisovat do paměti, která ji nepatřila. Starší Delphi 7 tuto chybu neodhalily a nechaly ji protéct, shodou náhod někam, kde mají uložený formulář, který zničila. Výsledkem bylo, že na něj nešlo už nic vložit.

Programování je někdy hold trochu dřina...

 

HTML: "Ten obrázek ti napravo prostě nezařadím"

 

Při aktualizaci webu jsem do textu vložil obrázek s align="right" v očekávání, že ho text bude obtékat. Ale co se nestalo - text se zalomil a obrázek se zobrazil na samostatném řádku. Po chvíli laborování jsem si na disku vytvořil textový soubor s příponou htm a do něj napsal jen tento řádek:

Toto je zkušební text <img alt="" align="right" src="obrazek.png">

Výsledek ovšem vypadal stejně, jako předtím - obrázek nebyl napravo, ale na dalším řádku. Co se to děje?! Nakonec jsem zjistil, že na to má vliv jeden tag, a to doctype, který jsem na webu zapomněl připsat a do prázdného souboru jsem ho také nevložil. Po přidání řádku

<!DOCTYPE HTML PUBLIC "-W3CDTD HTML 4.01 Transitional//EN" "http://www.w3­.org/TR/html4/l­oose.dtd">

se vše zobrazilo normálně. Prohlížeče tedy bez definice verze html považují dokument pravděpodobně za nějaký starý standard, ve kterém se asi nedalo zarovnat napravo :)

 

DelphiX: "Na některých počítačích se seká kurzor myši"

 

Další neuvěřitelný bug, jehož hledání mi zabralo celý týden. Když jsem měl svou hru Bermen téměř dokončenou a datum nevyhnutelného odevzdání bylo za dveřmi, objevil se zajímavý problém: "Na počítači souseda se ve hře sekal kurzor myši". Jelikož byla hra již po betatestu a nikdo tento problém neměl, svedl jsem to na nějaký hardwarový problém. V zápětí se ale objevili další dva lidé, kterým se hra chovala stejně. Po důkladné kontrole kódu (několika tisíců řádků :) ) jsem nenašel jedinou chybu. Rozhodl jsem se tedy použít radikální řešení. Postupně jsem odmazával kusy hry a běhal za sousedem s flashkou, kde jsem zkoušel, zda se chyba projevuje. Na všech mých počítačích totiž hra fungovala dobře a jeho PC bylo jediné přístupné místo, kde se bug projevoval. Když ze hry nezbylo už nic jiného než prázdné okno s kurzorem myši, sekala se stále. Jelikož jsem používal delfáckou událost onmousemove, vsadil jsem na nekompatibilitu s DelphiX a použil jejich implementaci myši přímo z DirectX input. Rozdíl je v tom, že myš nevrací souřadnice na obrazovce, ale jen o kolik se kurzor pohnul a na jakou stranu (funguje jako joystick). Člověk si tedy musí napsat něco na převod těchto údajů do souřadnic a omezit, aby kurzor nevyjel z obrazovky. Výhoda je v tom, že lze pracovat se senzitivitou myši. Po této úpravě hra fungovala bez problému. Oddychl jsem si a hru odeslal do soutěže Becherovka game. Bohužel předčasně...

Po nějaké době se objevili lidé, kterým se hra sekala také. Jedním z nich byl Travolta, který mi do hry pomohl vytvořit doplňující 2d grafiku. Přijel jsem k němu s notebookem a snažil se přijít na příčinu tak extrémního zpomalení hry, které se projevovalo dokonce jen v některých lokacích. Po odpoledni stráveném další kontrolou oněch tisíců řádků se nic nezměnilo. Dospěl jsem k závěru, že výskyt chyby nemá žádný pravidelný vzorec a není na ničem závislý, skoro to vypadalo, jakoby si to náhodně vybralo místnosti, kde hra nebude fungovat. Svedl jsem to na to, že někde musí přetékat dynamické pole, což jsem ale po dalších kontrolách vyloučil. Po několika dnech strávených zběsilým hledáním na internetu a projížděním kódu enginu jsem se uchýlil k tutoriálům, vytvořených samotným tvůrcem komponenty DelphiX. A čeho jsem si nevšiml! Formulář ukázkového programu byl typu tDxForm (Form1: tDxForm) a ne tform, jako jsem měl já. Dočetl jsem se, že tdxform je upravená třída delfáckého formuláře pro handlování nějakých volání Directu X. Když jsem to u sebe změnil - vše fungovalo! :)

Tímto bych chtěl zanadávat všem autorům Delphi X tutoriálů (Hlavně na Živě a Builderu), kde v návodu typu vytvořte formulář a natáhněte plátno není ani zmínka o změně třídy formuláře. Nepište o něčem, čemu nerozumíte!

A jak to dopadlo s hrou? Do soutěže jsem ihned odeslal opravu, ale bylo mi řečeno, že hra se bude hodnotit tak, jak byla do termínu zaslána a oprava se pouze potom uvolní ke stažení. Celé dva měsíce jsem doufal, že se chyba neprojeví a mé prosby byly vyslyšeny - Bermen vyhrál druhé místo a 35.000 kč, žádný z porotců neměl s hrou problém.

Suma sumárum: Běh DelphiX na běžném formuláři měl nevysvětlitelný vliv na plynulost hry, která se zasekávala v náhodných, nesouvisejících, ale vždy stejných místnostech. Nikdo by mi asi neřekl, co se tehdy přesně dělo, já jsem se uspokojil klasickým vysvětlením s vytékáním paměti.


 

Všechny články v sekci
Zábava
Článek pro vás napsal David Hartinger
Avatar
Uživatelské hodnocení:
14 hlasů
David je zakladatelem ITnetwork a programování se profesionálně věnuje 15 let. Má rád Nirvanu, nemovitosti a svobodu podnikání.
Unicorn university David se informační technologie naučil na Unicorn University - prestižní soukromé vysoké škole IT a ekonomie.
Aktivity