Tutnew1 2.1

Matti Rintala (bitti@cs.tut.fi)


Sisältö

   
Käyttötarkoitus

Tutnew on kirjasto, joka määrittelee uudelleen C++:n new- ja delete-operaattoreiden tarjoaman dynaamisen muistinhallinnan ja lisää siihen ajoaikaisia tarkistuksia. Tutnew antaa virheilmoituksen seuraavista virhetilanteista:

Jokainen virheilmoitus sisältää ilmoituksen siitä, millä rivillä ja missä tiedostossa virheen aiheuttanut muisti on varattu ja vastaavasti millä rivillä ja missä tiedostossa sitä yritetään vapauttaa. Uudelleenvapauttamisen ja vapauttamisen jälkeisen sotkemisen yhteydessä ilmoitetaan lisäksi, millä rivillä ja missä tiedostossa muisti on vapautettu.

Näiden virhetarkistusten lisäksi Tutnew antaa mahdollisuuden simuloida muistin loppumista. Käännösaikaisten vakioiden avulla ohjelma on mahdollista kääntää niin, että dynaamista muistia on käytössä vain jokin ennalta ilmoitettu määrä. Samoin on mahdollista saada aikaan muistin loppuminen n:nnessä muistinvarauksessa (missä n on käyttäjän antama vakio). Mahdollista on myös määrätä muistinvarauksen epäonnistumisen todennäköisyys (ja antaa satunnaislukugeneraattorille siemenluku). Edellä mainitut ominaisuudet on myös mahdollista kytkeä päälle ohjelmasta käsin kutsumalla Tutnew'n asetusfunktiota.

Tutnew kerää myös tilastoa muistinvarausten lukumäärästä sekä varatun muistin kokonais ja maksimimäärästä. Tämä tilasto tulostetaan oletusarvoisesti muistin loppumisen yhteydessä, mutta esikääntäjäoptiolla tilaston saa tulostumaan aina ohjelman lopussa, tai ohjelmasta voi kutsua funktiota, joka tulostaa senhetkisen tilanteen.

Mikäli muisti loppuu (joko todellisuudessa tai Tutnew'n simuloimana), Tutnew antaa tästä varoituksen ja ilmoittaa, mikä newoperaatio on aiheuttanut muistin loppumisen. Tutnew tarkkailee myös muistin loppumisesta aiheutuvia poikkeuksia ja ilmoittaa, mikäli tällaista poikkeusta ei käsitellä (ts. mikäli funktioita terminate() tai unexpected() kutsutaan Tutnew'n aiheuttaman käsittelemättömän poikkeuksen vuoksi).

   
Käyttö

Tutnew on tällä hetkellä testattu egcs:n versiolla 1.1.2 ja gcc:n versiolla 2.95.1. Sen toimivuudesta muissa ympäristöissä ei ole varmuutta.

Normaalisti Tutnew ilmoittaa havaitsemistaan virheistä heti virheen sattuessa, ja keskeyttää ohjelman (paitsi jos esikääntäjäsymboli TUTNEW_NOABORT on määritelty, jolloin ohjelman suoritus jatkuu virheestä huolimatta, ks. kohta [*]).

Tutnew ilmoittaa vapauttamattomasta muistista sekä korruptoituneesta vapautuneesta muistista vasta ohjelman lopussa. Mikäli ohjelmassa halutaan tarkistaa nämä asiat kesken ohjelman, voi koodissa kutsua funktiota tutnew_print_diagnostics(). Ilman parametreja tai parametrilla false se tulostaa listan vapauttamattomista muistialueista sekä korruptoituneesta vapautetusta muistista. Parametrilla true se listaa vain korruptoituneen vapautetun muistin. (Huomaa, että korruptoituneen muistin tarkistus ei onnistu, jos esikääntäjäsymboli TUTNEW_NOGARB on määritelty, ks. kohta [*])

   
Käyttö Lintulassa ja Proffalla

Tutnew'n käyttö on yksinkertaista. Sen käyttämiseksi jokaisen suoritettavaa koodia sisältävän tiedoston (siis lähinnä .cctiedostot) alkuun laitetaan kaikkien muiden otsikkotiedostojen lukemiskomentojen (#include ...) jälkeen komento

#include <tutnew>
Tämä komento korvaa ISO C++:n komennon #include <new> (mutta ohjelma toimii, vaikka <new> ja <tutnew> molemmat luettaisiin).

Tämän jälkeen ohjelman voi kääntää normaalisti. Linkkausvaiheessa täytyy ohjelmaan vielä linkata Tutnew-kirjasto lisäämällä linkkauskäskyyn käännösvipu -ltutnew, siis esim.

g++ -W -Wall -pedantic -o ohjelma ohjelma.o toinen.o -ltutnew

   
Käyttö Linuxissa

Linuxiin käännetty Tutnew-kirjasto löytyy nimellä tutnew-linux-kääntäjä-ja-versio.tar.gz lintulan hakemistostosta ~ bitti/pub/tutnew tai FTP:llä paikasta ftp://ftp.cs.tut.fi/
pub/tut/bitti/tutnew/tutnew-linux.tar.gz
. Paketti tulee purkaa samaan hakemistoon itse ohjelman lähdekoodin kanssa.

Tämän jälkeen jokaisen kooditiedoston alkuun laitetaan heti kaikkien muiden otsikkotiedostojen (#include ...) luvun jälkeen komento

#include "tutnew.h"

Ohjelman linkkausvaiheessa linkkauskäskyyn lisätä vielä optiot -L. ja -ltutnew (ks. käyttö lintulassa, kohta [*]), siis esim.

g++ -W -Wall -pedantic -L. -o ohjelma ohjelma.o toinen.o -ltutnew

   
Konfigurointi

Tutnew'n toimintaan vaikuttavat seuraavat esikääntäjäsymbolit. Alla mainitut symbolit kannattaa yleensä määritellä kääntäjän komentoriville tms, esim. g++:ssa g++ -DTUTNEW_ENDSTAT -DTUTNEW_LANG="SUOMI". (Toinen mahdollisuus on tietysti määritellä symbolit #define-käskyllä ennen #include:a, mutta tätä ei kannata käyttää, ks. seuraava) Jos em. konfigurointia käytetään, on samat symbolit oltava määriteltynä jokaisessa kooditiedostossa, muuten käytetty konfiguraatio on määrittelemätön.

Oletusarvoisesti Tutnew antaa virheilmoituksensa englanniksi. Määrittelemällä esikääntäjäsymbolin TUTNEW_LANG arvoksi haluttu kieli, saadaan virheilmoitukset muilla kielillä. Tällä hetkellä tuettuja kieliä ovat ENGLISH, SUOMI ja POHOJANMAA (ja piakkoin ainakin MANSE)2. Kääntäjän komentorivillä kieli asetetaan optiolla -DTUTNEW_LANG="KIELI".

Jos symboli TUTNEW_NOABORT on määritelty, ei Tutnew kaada ohjelman suoritusta virheilmoituksiin, vaan ohjelman suoritus jatkuu virheestä huolimatta. Asetuksen voi myös kääntää päälle/pois ohjelman ajon aikana funktiolla tutnew_abort(true/false).

Jos symboli TUTNEW_NOGARB on määritelty, ei Tutnew tarkista, sotketaanko jo vapautettua muistia. Tällöin ohjelman muistinkulutus pienenee (normaalisti sotkeentumistestaus aiheuttaa sen, että kaikki ohjelman varaama muisti vapautetaan itse asiassa vasta ohjelman lopussa).

Jos symboli TUTNEW_NOMSG on määritelty, ei Tutnew tulosta mitään virheilmoituksia. Muistitestaukset suoritetaan kuitenkin edelleen ja ohjelma kaadetaan virheen sattuessa (ellei symbolia TUTNEW_NOABORT ole määritelty). Asetuksen voi myös kääntää päälle/pois ohjelman ajon aikana funktiolla tutnew_msgs(true/false).

Jos symboli TUTNEW_ENDSTAT on määritelty, tulostaa Tutnew ohjelman lopussa yhteenvedon suoritettujen new- ja deleteoperaatioiden määrästä sekä käytetyn dynaamisen muistin kokonais ja maksimimäärästä. Asetuksen voi myös kääntää päälle/pois ohjelman ajon aikana funktiolla
tutnew_end_stat(true/false).

Jos symboli TUTNEW_NOOUTWARN on määritelty, ei Tutnew tulosta varoitusta muistin loppumisen (tai sen simuloimisen) yhteydessä. Asetuksen voi myös kääntää päälle/pois ohjelman ajon aikana funktiolla tutnew_outwarn(true/false).

Jos symboli TUTNEW_MEMLIMIT on määritelty johonkin numeroarvoon, määrää tämä arvo, kuinka paljon dynaamista muistia Tutnew antaa ohjelman käyttöön. Jos arvo on positiivinen, koskee muistirajoitus ainoastaan niissä kooditiedostoissa tehtyjä muistinvarauksia, joissa Tutnew on otettu käyttöön include-komennolla. Jos arvo on negatiivinen, koskee muistirajoitus kaikkia ohjelmassa tehtyjä muistinvarauksia (myös vakiokirjastoissa tehtyjä yms). Muistirajoituksen voi myös asettaa ohjelman ajon aikana funktiolla
tutnew_set_memlimit(0/muistiraja). Kääntäjän komentorivillä rajoitus asetetaan optiolla -DTUTNEW_MEMLIMIT=muistiraja.

Jos symboli TUTNEW_FAILCYCLE on määritelty numeroarvoon n ($n \ne 0$), epäonnistuu ohjelmassa joka n:s muistinvaraus (ts. muisti ``loppuu'' maagisesti joka n:nnellä muistinvarausyrityksellä). Rajoituksen voi myös asettaa ohjelman ajon aikana funktiolla tutnew_set_failcycle(0/lukumäärä). Kääntäjän komentorivillä rajoitus asetetaan optiolla -DTUTNEW_FAILCYCLE=n.

Jos symboli TUTNEW_FAILPROB on määritelty liukulukuarvoon p( $0 \le p \le 1$), on joka muistinvarauksessa todennäköisyys p, että muisti ``loppuu'' (ts. varausyritys epäonnistuu). Jos lisäksi symboli TUTNEW_PROBSEED on määritelty numeroarvoon, käytetään tätä arvoa satunnaislukugeneraattorin siemenlukuna. Rajoituksen voi myös asettaa ohjelman ajon aikana funktiolla tutnew_set_failprob(todennäköisyys) tai tutnew_set_failprob(todennäköisyys, siemenluku). Kääntäjän komentorivillä rajoitus asetetaan optiolla
-DTUTNEW_FAILPROB=p (ja mahdollisesti vielä -DTUTNEW_PROBSEED=siemen.

Jos symboli TUTNEW_VERSION on määritelty, tulostaa Tutnew ohjelman alussa versionumerotietonsa. Tästä on hyötyä, mikäli Tutnew tuntuu toimivan väärin ja siitä halutaan tehdä virheraportti.

   
Rajoitukset Tutnew'n käytössä

Tutnew määrittelee C++:n new- ja delete-komennot esikääntäjämakroiksi. Tämän vuoksi ohjelmakoodissa ei voi suoraan määritellä tai kutsua operator new tai operator delete -funktioita. Mikäli näitä halutaan käyttää tai määritellä, tulee juuri ennen ko. operaattorien määrittelyä/kutsua lisätä koodiin rivi #include <untutnew> (tai #include "untutnew.h" Linuxissa). Vastaavasti heti operaattoreiden määrittelyn tai kutsun jälkeen lisätään rivi #include <tutnew> (tai #include "tutnew.h" Linuxissa).

Toinen rajoitus on, että (varsin kyseenalainen) koodi new X ->f() (ja vastaavat) täytyy Tutnew'tä varten kirjoittaa sulkujen kanssa ((new X)->f()), jotta se menisi kääntäjästä läpi. On kuitenkin epätodennäköistä, että kukaan koskaan tarvitsisi moista hirvitystä.

   
Versiohistoria

1.0
Ensimmäinen julkaistu versio
1.1
Lisätty tutnew_print_diagnostics()
1.2
Lisätty #include <untutnew>
2.0
Lisätty dokumentaatio Tutnew 2.0:n uusista ominaisuuksista
2.1
Selvennetty include-järjestystä koskeva teksti

Tästä dokumentista ...

Tutnew1 2.1

This document was generated using the LaTeX2HTML translator Version 98.1p1 release (March 2nd, 1998)

Copyright © 1993, 1994, 1995, 1996, 1997, Nikos Drakos, Computer Based Learning Unit, University of Leeds.

The command line arguments were:
latex2html -split 0 -no_navigation -local_icons tutnew.tex.

The translation was initiated by Matti Rintala on 1999-10-11


Footnotes

...Tutnew1
Dokumentaatio ja kirjasto © 1997,1999 Matti Rintala
... MANSE)2
Muutkin murreversiot olisivat mukavia. Jos olet innostunut tuottamaan uuden murreversion, ota yhteyttä! (bitti@cs.tut.fi


Matti Rintala
1999-10-11