Race tilstand

En race condition , også en konkurrence  [ 1 ]  , er en designfejl i et flertrådet system eller applikation, hvor driften af ​​systemet eller applikationen afhænger af den rækkefølge, som dele af koden udføres i. Fejlen har fået sit navn fra en lignende designfejl i elektroniske kredsløb (se signal racing ).

Udtrykket race condition refererer til teknisk jargon og er resultatet af en sjusket bogstavelig oversættelse af den engelske ækvivalent. I et mere stringent akademisk miljø er det sædvanligt at bruge udtrykket concurrency uncertainty .

En race condition er en "flydende" fejl ( heisenbug ), som dukker op på tilfældige tidspunkter og "forsvinder", når du forsøger at lokalisere den.

Mulige konsekvenser

På grund af ukontrolleret adgang til delt hukommelse kan en race-tilstand føre til helt andre fejl, der kan opstå på uforudsigelige tidspunkter, og et forsøg på at replikere fejlen til fejlfindingsformål med lignende driftsbetingelser kan mislykkes.

De vigtigste konsekvenser kan være:

Therac-25 sag

Therac -25 strålebehandlingsmaskinen var den første medicinske enhed i USA, der udelukkende var afhængig af software for sikkerhed . Denne enhed fungerede i tre tilstande:

  1. Elektronterapi : Elektronpistolen bestråler patienten direkte; computeren indstiller elektronenergien fra 5 til 25 MeV .
  2. Røntgenterapi : En elektronpistol bestråler et wolframmål , og patienten bestråles med røntgenstråler, der passerer gennem en kegleformet diffuser. I denne tilstand er elektronenergien konstant: 25 MeV .
  3. I den tredje tilstand var der ingen stråling. En stålreflektor placeres i elektronernes bane (i tilfælde af en ulykke), og strålingen simuleres af lys . Denne tilstand bruges til at rette strålen nøjagtigt til det ømme sted.

Disse tre tilstande blev indstillet af en roterende skive, hvori der var et hul med afbøjningsmagneter til elektronisk terapi, og et mål med en diffuser til røntgen. På grund af en kapløbstilstand mellem kontrolprogrammet og tastaturmotoren skete det nogle gange, at disken i røntgenterapitilstanden var i positionen "Elektronterapi", og patienten blev direkte bestrålet med en 25 MeV elektronstråle, som førte til overeksponering. Samtidig viste sensorerne "Nul dosis", så operatøren kunne gentage proceduren, hvilket forværrede situationen. Som følge heraf døde mindst to patienter.

En del af koden blev hentet fra Therac-6 og Therac-20. Samtidig havde Therac-6 ikke røntgenbehandling, og Therac-20 havde hardwaresikkerhedsforanstaltninger, der forhindrede strålingen i at tænde, når disken var i den forkerte position.

Eksempel

Overvej et kodeeksempel (i Java ).

flygtig int x ; // Tråd 1: while ( ! stop ) { x ++ ; } // Tråd 2: while ( ! stop ) { if ( x % 2 == 0 ) System . ud . println ( "x=" + x ); }

Lad x=0. Antag, at programmet udføres i følgende rækkefølge:

  1. If-sætningen i tråd 2 tester x for paritet.
  2. Udsagnet " x++ " i tråd 1 stiger x gange én.
  3. Output-sætningen i tråd 2 udsender " x=1 ", selvom variablen ser ud til at være paritetskontrolleret.

Løsninger

Lokal kopi

Den nemmeste måde at løse dette på er at kopiere variablen x til en lokal variabel. Her er den rettede kode:

// Tråd 2: while ( ! stop ) { int cached_x = x ; if ( cachelagret_x % 2 == 0 ) System . ud . println ( "x=" + cachelagret_x ); }

Naturligvis fungerer denne metode kun, når der kun er én variabel, og kopiering udføres i én maskininstruktion.

Synkronisering

En mere kompleks og "dyr", men også mere universel løsningsmetode er trådsynkronisering , nemlig:

int x ; // Tråd 1: while ( ! stop ) { synchronized ( someObject ) { x ++ ; } } // Tråd 2: while ( ! stop ) { synchronized ( someObject ) { if ( x % 2 == 0 ) System . ud . println ( "x=" + x ); } }

Her sker det før semantik ikke kræver nøgleordet volatile.

Kombineret måde

Antag, at der er to variable (og nøgleordet volatilehar ingen effekt), og den anden tråd System.out.printlnhar mere kompleks behandling i stedet. I dette tilfælde er begge metoder utilfredsstillende: den første, fordi den ene variabel kan ændre sig, mens den anden kopieres; det andet skyldes, at for meget kode er synkroniseret.

Disse metoder kan kombineres ved at kopiere "farlige" variabler i en synkroniseret blok. På den ene side vil dette fjerne begrænsningen på én maskininstruktion, på den anden side vil det give dig mulighed for at slippe af med for store synkroniseringsblokke.

flygtig int x1 , x2 ; // Tråd 1: while ( ! stop ) { synchronized ( someObject ) { x1 ++ ; x2 ++ ; } } // Tråd 2: while ( ! stop ) { int cached_x1 , cached_x2 ; synchronized ( someObject ) { cached_x1 = x1 ; cachelagret_x2 = x2 ; } if (( cached_x1 + cached_x2 ) % 100 == 0 ) DoSomethingComplicated ( cached_x1 , cached_x2 ); }

Der er ingen åbenlyse måder at opdage og rette løbsforhold på. Den bedste måde at slippe af med racer er at designe et multitasking-system korrekt.

Hacks ved at udnytte raceforhold

Der er en klasse af fejl (og typer af angreb, der udnytter dem), der tillader et  uprivilegeret program at påvirke driften af ​​andre programmer gennem evnen til at ændre offentlige ressourcer (normalt midlertidige filer  ; filen er tilgængelig til skrivning af hele eller dele af brugere af systemet på grund af en programmørs fejl.

Det angribende program kan ødelægge indholdet af filen, få offerprogrammet til at gå ned, eller ved at ændre dataene tvinge programmet til at udføre en handling på niveau med dets privilegier.

Det er af denne grund, at software med alvorlige sikkerhedskrav, såsom webbrowseren , bruger tilfældige tal i kryptografisk kvalitet til at navngive midlertidige filer.

Noter

  1. Raymond, Eric S. Kunsten at Unix-programmering / oversættelse. fra engelsk. - M . : Forlaget " Williams ", 2005. - S. 202. - 544 s. — ISBN 5-8459-0791-8 .
  2. ↑ 1 2 3 4 Greg Kroah-Hartman, Alessandro Rubini, Jonathan Corbet. Kapitel 5. Samtidigheds- og raceforhold // Linux-enhedsdrivere . - 3. udgave. - O'Reilly Media, Inc., 2005. - ISBN 0596005903 . Arkiveret 12. april 2019 på Wayback Machine

Se også