Toon posts:

[C++] Integer verandert plotseling gigantisch van waarde

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik ben bezig met het volgende stukje C++ code:
code:
1
2
3
4
else if (draw_mode == DM_KOCH) {
    if (count < 6) {
        p[count].x = x;
        p[count].y = windowHeight - y;


Dit werkt perfect wanneer de int count de waarde 0, 1, 2, 3 heeft. Maar als count de waarde 4 heeft, verandert de waarde ineens naar 1080418304 na het uitvoeren van de regel p[count].x = x;

Ik doe dit in Visual Studio .NET 2003. Hetzelfde programma heb ik gerund in Eclipse met CDT-plugin onder Linux en dan werkt het wel gewoon :s Heeft iemand een idee wat er nu mis gaat?

[ Voor 5% gewijzigd door Verwijderd op 14-12-2005 17:46 ]


  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Aan het stuk code dat je post zie ik niks geks :?
Heb je nog wat meer? Heb je x niet ergens als "global" staan ofzo? Overflowtje ergens misschien?

[ Voor 35% gewijzigd door RobIII op 14-12-2005 17:50 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • Orphix
  • Registratie: Februari 2000
  • Niet online
Welke variabele wordt 1080418304 ? p[count].x (dus p[4].x) of count zelf?

[ Voor 7% gewijzigd door Orphix op 14-12-2005 17:55 ]


Verwijderd

gelukkig heeft visual studio ook een debugger .. dus .. zet eens een breakpoint bij desbetreffende plek, en 'step' dan eens door de code heen.

de snippet code die je ons laat zien doet niks met count. dus aan dit bepaalde stukje zal het wel niet liggen.

wat kan er fout zijn ?

* ergens verander je de waarde van count, en dat gaat niet goed
* ergens verander je de waarde van de variabele die NAAST count is gedefinieerd ( op de memory stack dus ) en je stopt op die plek een waarde die meer memory in beslag neemt dan die variabele kan bevatten, en je zo dus overflowt naar count, en m dus zo verandert zonder het te weten.

  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 21-04 20:42

Tomatoman

Fulltime prutser

Is count niet toevallig een member van een class waar de code in staat?

Een goede grap mag vrienden kosten.


Verwijderd

Topicstarter
Ik ben er doorheen gestept in de debugger, daarom weet ik dat count na het uitvoeren van de regel p[count].x = x; ineens veranderd is. Het is dus count die na die regel niet meer 4 is maar dat grote getal.

Het zal dan waarschijnlijk wel die tweede optie van Templar1 zijn, is er een manier om te zien welke variabele naast count op de stack staat? En waarom werkt dit in Linux dan wel?

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

mijn gok is dan dat p[] te klein is ?

heb je p op de stack of op de heap gealloceerd?

ASSUME makes an ASS out of U and ME


  • Ivo
  • Registratie: Juni 2001
  • Laatst online: 14-01-2025

Ivo

Waarschijnlijk werkt het in Linux wel, omdat Linux op een andere manier geheugen alloceert voor je declaraties als Windows dat doet. Het is dus toevallig dat het wel werkt, maar het had net zo goed keihard fout kunnen gaan in Linux. Hoe je het went of keert, er zit een bug in je code.

Verwijderd

volgens mij kun je in visual studio aangeven dat je in debug mode zit, bij de compiler opties. dan zet de compiler OM de individuele variabelen in het geheugen een sentinel value, zodat VS kan ontdekken dat er een overflow heeft plaatsgevonden, en geeft dan ook aan waar dan precies.

Verwijderd

Topicstarter
HIGHGuY schreef op woensdag 14 december 2005 @ 18:10:
mijn gok is dan dat p[] te klein is ?
Dank je wel, je hebt gelijk! :-)) Iedereen bedankt voor 't meedenken!

Verwijderd

even nog een klein commentaartje, een variabele kan helemaal niet een variabele er naast overschrijden met een ander getal omdat die te groot is, dat zou je alleen met een memory locatie die je zelf opgeeft kunnen doen, of door een union maar niet door een te groot getal opgeven of wat dan ook

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

@KOD2005:
C++:
1
2
3
4
5
6
7
8
9
void mijnFunctie()
{
   char p[50];
   int q = 0;
   while (q < 52)
   {
      p[q] = (char)255;
   }
}


met een beetje geluk krijg je hier een knoert van een access violation error op 0xFF000033
op de stack:
50 bytes voor p
4 bytes voor q

alle 50 bytes worden op char(255) = 0xFF gezet
als q = 51 => p[51] (eerste byte van q) op FF zetten
0xFF000033 < 0 < 50 zodat het volgende geteste adres:
p[0xFF000033] is... kan niet echt, he ?

ASSUME makes an ASS out of U and ME


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Verwijderd schreef op woensdag 14 december 2005 @ 19:57:
even nog een klein commentaartje, een variabele kan helemaal niet een variabele er naast overschrijden met een ander getal omdat die te groot is, dat zou je alleen met een memory locatie die je zelf opgeeft kunnen doen, of door een union maar niet door een te groot getal opgeven of wat dan ook
Of een klassieke C string die te groot (lang) wordt, die kan ook naastgelegen variabelen overscrhijven. std::string groeit netjes.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Ligt eraan, als je in een std::string of vector oid schrijf met operator[] kan het op dezelfde manier mis gaan

Verwijderd

en kan iemand mij vertellen hoe je dat zonder een acces violation error kan doen, want dat zeg ik nou juist. ik wil niet flamen ofzo maar je kan niet zomaar waardes overschrijden zonder dat je dat express aangeeft of dat je daar een melding van krijgt.

  • deDorus
  • Registratie: Augustus 2001
  • Laatst online: 09:59

deDorus

Meisje, ik ben een C-man...

Verwijderd schreef op donderdag 15 december 2005 @ 14:27:
en kan iemand mij vertellen hoe je dat zonder een acces violation error kan doen, want dat zeg ik nou juist. ik wil niet flamen ofzo maar je kan niet zomaar waardes overschrijden zonder dat je dat express aangeeft of dat je daar een melding van krijgt.
In C en ook C++ (en vele andere talen) liggen bytes voor varabelen gewoon netjes naast elkaar op de stack of heap al of niet gealigned op byte, word, of long. Je kunt rustig waardes overschijven zonder melding, zolang je maar binnen het aan het process toegekende geheugen blijft.

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

windows is behoorlijk lax in het controleren van toegang.

zolang je binnen je eigen process-ruimte blijft is er weinig kans dat Windows je een aanmaning geeft.
Linux is een stuk strenger hierin.

ASSUME makes an ASS out of U and ME


Verwijderd

ik weet wel dat ze naast elkaar liggen maar je moet in principe een load operatie doen op een adress ruimte wat niet automatisch door een compiler word gegenereert. dus je moet dit zelf aangeven en de compiler doet dat niet voor jouw.
eigenlijk wil ik zeggen dat een te groot getal jouw waarde ernaast niet overschrijdt want dat te groote getal word gewoon afgekapt tot de grootte dat word ondersteund, bij een 32 bit processor is dat dus 32 bit en dan kan je ook geen grotere getal opgeven dan 32 bit want dat past niet in de instructie. dus overflow word gewoon met modulo afgehandelt in principe.

[ Voor 46% gewijzigd door Verwijderd op 15-12-2005 14:56 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21-04 01:08

.oisyn

Moderator Devschuur®

Demotivational Speaker

Een OS kan dat niet eens controleren. Het zijn door de CPU gegenereerde fouten op het moment dat een blok geheugen niet toegankelijk is of simpelweg gewoon niet bestaat. Een gealloceerde buffer bevindt zich _altijd_ in je eigen processpace, en op het x86 platformen kun je dat slechts in blokken van 4096 bytes instellen. Als je dus 2x een array alloceert van 100 bytes, zal ook linux geen foutmelding geven op het moment dat je buiten de eerste array schrijft (vooropgesteld dat de twee allocaties naast elkaar liggen). Of je moet elke allocatie z'n eigen page geven met daartussen niet bestaande pages, maar dat is nogal inefficient.

[ Voor 5% gewijzigd door .oisyn op 15-12-2005 14:55 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 21-04 12:01

curry684

left part of the evil twins

HIGHGuY schreef op donderdag 15 december 2005 @ 14:34:
windows is behoorlijk lax in het controleren van toegang.

zolang je binnen je eigen process-ruimte blijft is er weinig kans dat Windows je een aanmaning geeft.
Linux is een stuk strenger hierin.
En hoe gaat Linux controleren dat jij op "de verkeerde plek" in je eigen process space zit?

Bull dus, bij beide OS'en doet de MMU niets anders dan het beveiligen van de eigen process space.

edit:
mep .oisyn :P

[ Voor 3% gewijzigd door curry684 op 15-12-2005 14:53 ]

Professionele website nodig?


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21-04 01:08

.oisyn

Moderator Devschuur®

Demotivational Speaker

Verwijderd schreef op donderdag 15 december 2005 @ 14:27:
en kan iemand mij vertellen hoe je dat zonder een acces violation error kan doen, want dat zeg ik nou juist.
:?
Jij hebt voor deze reactie nog niet gereageerd in deze draad, dus of ik snap het niet of jij bent verkeerd ingelogd :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

idd ik zit op de computer van me werkplek dus ik had er eigenlijk niet eens bij nagedacht
hehe :)

  • deDorus
  • Registratie: Augustus 2001
  • Laatst online: 09:59

deDorus

Meisje, ik ben een C-man...

Verwijderd schreef op donderdag 15 december 2005 @ 14:48:
ik weet wel dat ze naast elkaar liggen maar je moet in principe een load operatie doen op een adress ruimte wat niet automatisch door een compiler word gegenereert. dus je moet dit zelf aangeven en de compiler doet dat niet voor jouw.
eigenlijk wil ik zeggen dat een te groot getal jouw waarde ernaast niet overschrijdt want dat te groote getal word gewoon afgekapt tot de grootte dat word ondersteund, bij een 32 bit processor is dat dus 32 bit en dan kan je ook geen grotere getal opgeven dan 32 bit want dat past niet in de instructie. dus overflow word gewoon met modulo afgehandelt in principe.
Er wordt hier een array gebruikt. Je reserveerde bv voor 4 longs l[0] t/m l[3] en vervolgens ga je een (niet bestaande) 5e l[4] veranderen.

Verwijderd

ja en dan geef je dat dus zelf aan en dat gaat niet automatisch met overflow

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21-04 01:08

.oisyn

Moderator Devschuur®

Demotivational Speaker

Maar wat is je punt nou eigenlijk?

En ben je nou nog steeds verkeerd ingelogd? Zo ja, fix dat dan even :). Mag ik je er tevens op wijzen dat meerdere accounts per persoon niet zijn toegestaan en zal resulteren in een ban?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

ja dit ben ik echt dus, maar ik heb maar 1 account alleen de comp waar ik zeg maar op zit te posten die meld zich automatisch aan op tweakers en dat had ik even niet door. vandaar de post op julianus die wel boos op me zal worden vrijdag omdat ik zijn reputatie een beetje zit te verbeteren :D (of verpesten) maar goed foutje bedankt.
de punt was dus dat ik wou zeggen dat een overflow van 1 variabele in het geheugen niet een andere variabele overschrijdt, het lekt niet door naar een andere locatie zeg maar.

[ Voor 22% gewijzigd door Verwijderd op 15-12-2005 15:10 ]


  • deDorus
  • Registratie: Augustus 2001
  • Laatst online: 09:59

deDorus

Meisje, ik ben een C-man...

Verwijderd schreef op donderdag 15 december 2005 @ 15:02:
ja en dan geef je dat dus zelf aan en dat gaat niet automatisch met overflow
:?

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21-04 01:08

.oisyn

Moderator Devschuur®

Demotivational Speaker

De verwarring die hier ontstaat is dat KOD2005 (/ julianus) het over een overflow heeft in de zin dat een char na 0xff weer 0x00 wordt, terwijl de rest doelt op een overflow waarbij het 6e element van een array geschreven wordt die maar 5 lang is.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
.oisyn schreef op donderdag 15 december 2005 @ 14:51:
Als je dus 2x een array alloceert van 100 bytes, zal ook linux geen foutmelding geven op het moment dat je buiten de eerste array schrijft (vooropgesteld dat de twee allocaties naast elkaar liggen). Of je moet elke allocatie z'n eigen page geven met daartussen niet bestaande pages, maar dat is nogal inefficient.
Dat kan overigens wel in Windows.

Er zijn er wel degelijk verschillen tussen OSen in de mate waarin het geheugen beschermd wordt: gebruik van de NX bit, code write-only maken, etcetera. Ook is het wel haalbaar om bepaalde userspace process data af te schermen met een code page zodat een gecrashte applicatie netter af te sluiten is.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21-04 01:08

.oisyn

Moderator Devschuur®

Demotivational Speaker

dat protect je nog altijd niet tegen een buffer overflow in een app die gewoon veel writable mem gebruikt

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

@ .oisyn

misschien ligt het dan eerder aan het verschil in compiler, maar ik krijg bij dezelfde code sneller een segfault in linux dan een access violation in windows.

simpelweg 1 karakter teveel schrijven in een char* gaf me voor zover ik weet in linux problemen en in windows niet.
De echte reden hierachter ken ik niet, maar het feit is er wel ;)

ASSUME makes an ASS out of U and ME


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 21-04 12:01

curry684

left part of the evil twins

In een releasebuild is dat stom toeval (of stomme pech).

Professionele website nodig?


Verwijderd

Zoijar schreef op woensdag 14 december 2005 @ 21:24:
Ligt eraan, als je in een std::string of vector oid schrijf met operator[] kan het op dezelfde manier mis gaan
Klopt. Je kan in beide gevallen gebruik maken van de member functie at die een exception geeft als de index niet klopt. Overigens wordt iig in VC2005 ook voor operator[] de range gechecked met een assert in debug builds, wat het makkelijker maakt de fout op te sporen.
Pagina: 1