"MInnessäkra" språk

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Användarvisningsbild
Krille Krokodil
Inlägg: 4062
Blev medlem: 9 december 2005, 22:33:11
Ort: Helsingborg

Re: "MInnessäkra" språk

Inlägg av Krille Krokodil »

Marta skrev: 13 november 2022, 08:10:21 Var är det stora problemet? Görs en memset före free så är där inget kvarlämnat. Eller är det libs som lämnar kvar saker som andra processer kan komma åt? Hur som, inget som påverkar språkval för hobbybruk.
Minsta problem. Tänker du 1 bit snett i C/C++ så har du ett fel som kan märkas allt mellan omedelbart till oändligheten bort.

Går man 1 bit utanför sina variabeldeklarationer i C# så kraschar programmet och ganska så ofta så sker det omedelbart när man
provkör koden. Ex. indexering av arrayer & for-loopar där det är ganska vanligt att man både har otur när man tänker/slinter
på tangenterna i C/C++ och att felet blir lurigt och inte visar sig tydligt direkt.
pfyra
Inlägg: 347
Blev medlem: 8 mars 2015, 14:14:44
Ort: utanför Karlstad

Re: "MInnessäkra" språk

Inlägg av pfyra »

Marta skrev: 13 november 2022, 08:10:21 Var är det stora problemet? Görs en memset före free så är där inget kvarlämnat. Eller är det libs som lämnar kvar saker som andra processer kan komma åt? Hur som, inget som påverkar språkval för hobbybruk.
Det är tyvärr inte så enkelt att rensa minnet då kompilatoroptimeringar tar bort onödig kod (och att skriva något till minne precis innan det frigörs är "onödigt"). Har för mig att openssl hade något bekymmer med det här för några år sen, men minns inte riktigt..
MiaM
Inlägg: 9961
Blev medlem: 6 maj 2009, 22:19:19

Re: "MInnessäkra" språk

Inlägg av MiaM »

Det går ju att länka in en funktion som kompileras separat, som inte gör nånting, och så skickar man parametrar till den funktionen så ser kompilatorn till att faktiskt köra kod som skapar vad dessa parametrar innehåller. Eller så kan den separatkompilerade funktionen göra minnestvätten.
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43176
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: "MInnessäkra" språk

Inlägg av sodjan »

Alla dessa "Det är ju bara...", "Man kan ju bara...", "Det går ju..." o.s.v. verifierar ju problemet som rapporten (och andra) pekar ut.
Och rapporten konstaterade att det finns andra verktyg för att utveckla applikationer som tar hand om problemet i verktyget.
Användarvisningsbild
Marta
EF Sponsor
Inlägg: 6921
Blev medlem: 30 mars 2005, 01:19:59
Ort: Landskrona
Kontakt:

Re: "MInnessäkra" språk

Inlägg av Marta »

Det är viktigt att ha kontroll vid all programmering. Tunga, sega språk löser ingenting. Givetvis skall sizeof() användas och inte siffror där så är möjligt. Bättre också att överallokera och använda sizeof()-1 eller vad som nu behövs.

"Vet" gcc opimering vad memset() är för något? I så fall är där något jag missat att tänka på vid försök till "säker" avslutning av program. Det enklaste/bästa hade ju varit om operativet rensat vid deallokering. Detta oavsett om processen terminerade korrekt eller t.ex. med segfault.
Mr Andersson
Inlägg: 1397
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

Re: "MInnessäkra" språk

Inlägg av Mr Andersson »

Kompilatorn får ta bort memset (eller vilket funktionsanrop som helst) om den kan bevisa att det inte påverkar körningen av din kod.
Det kallas "as if"-regeln. Kompilatorn får ändra din kod hur som helst om det observerbara resultatet körs som om (as if) det hade varit din kod som körts rakt av.
memset eller inte, utan någon annan access före free, påverkar inte hur ditt program beter sig. Sen om någon annan process teoretiskt kan få ditt gamla minne är utanför standardens omfång. Det bör väl helst lösas på OS-nivå om man vill vara helt säker att ingen kan se gammal data.
Vill man garantera att memset blir kvar så använd volatile-pekare.
Användarvisningsbild
Krille Krokodil
Inlägg: 4062
Blev medlem: 9 december 2005, 22:33:11
Ort: Helsingborg

Re: "MInnessäkra" språk

Inlägg av Krille Krokodil »

På en PC med stort OS så skiljer inget praktisk i prestanda mellan C/C++ och C#.

Man använder referenser, pekare och manuell minneshantering när det behövs i C# och när
det inte behövs låter man bli och skriver då kod med finkornigt minnesskydd ner till minsta objekt
och automatisk uppstädning av det minne som inte längre används.
Användarvisningsbild
Marta
EF Sponsor
Inlägg: 6921
Blev medlem: 30 mars 2005, 01:19:59
Ort: Landskrona
Kontakt:

Re: "MInnessäkra" språk

Inlägg av Marta »

Ett funktionsanrop före free() som kompilatorn inte känner till _måste_ göras. Det kan ju skriva till global eller static variabel. Memset är väl något i glibc som länkas och därmed borde vara okänt för kompilern och inte optimeras bort.
Mr Andersson
Inlägg: 1397
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

Re: "MInnessäkra" språk

Inlägg av Mr Andersson »

Ja det stämmer. Nyckelorden är "som kompilatorn inte känner till".
Den behöver inte veta hur implementeringen av memset ser ut eller att funktionen länkas in externt. Den vet vad resultatet ska bli och att det inte finns några okända bieffekter eftersom memsets beteende är spec:at i standarden.
Om du skriver en funktion som ska mata hunden och döper den till memset har du ingen rätt att klaga när hunden svälter ihjäl eftersom du använde ett reserverat namn och kompilatorn tog bort vad den trodde var ett känt beteende.
The names of all library types, macros, variables and functions that come from the ISO C standard are reserved unconditionally; your program may not redefine these names.
Visst, det är ganska vanligt att folk gör sina egna implementationer med standardnamn ändå, och det fungerar oftast. Men det är inte garanterat att fungera.
Jag hade däremot fel om volatile, gcc tar bort memset ändå.

Kod: Markera allt

extern void foo(void*);

int main() {
  volatile char* p = malloc(10*sizeof(*p));
  foo(p);
  memset(p, 0, 10*sizeof(*p));
  free(p);
}
Kompilerat med O2, register-accesser borttagna för att spara plats.

Kod: Markera allt

main:
  call    malloc
  call    foo
  call    free
Sätter man memset före foo-anropet får gcc inte ta bort memset eftersom det påverkar minnet som foo ser.

Kod: Markera allt

main:
  call    calloc <-- malloc utbytt. gcc ser inte koden för malloc & calloc internt men den vet vad resultatet ska bli
  call    foo
  call    free
Det verkar som att det enda sättet att garantera att memset blir kvar i gcc är att stänga av optimeringen, antingen globalt eller i en wrapper-funktion.

Kod: Markera allt

__attribute__((optimize("no-dce"))) // no dead code elimination
__attribute__((noinline))
void* mymemset(void *s, int c, size_t n) {
    return memset(s, c, n);
}

Kod: Markera allt

main:
  call    malloc
  call    foo
  call    mymemset
  call    free
  
mymemset:
  jmp memset
memset på globaler eller statics kommer inte tas bort. Detta gäller bara dynamiskt allokerat minne och stack-variabler.
Skriv svar