c ++ - Windows WriteFile problem ved brug af tråde

Indlæg af Hanne Mølgaard Plasc

Problem



Mit firma udvikler en hardware, der skal kommunikere med software. For at gøre dette har vi lavet en driver, der gør det muligt at skrive til og læse fra hardwaren. For at få adgang til driveren bruger vi kommandoen:


HANDLE device = CreateFile(DEVICE\_NAME,
                                GENERIC\_READ | GENERIC\_WRITE,
                                0x00000007,
                                &sec,
                                OPEN\_EXISTING,
                                0,
                                NULL);


Læsning og skrivning udføres ved hjælp af funktionerne:


WriteFile(device,&package,package.datasize,&bytesWritten,NULL);


og


ReadFile(device,returndata,returndatasize,&bytesRead,NULL);


Og endelig, CloseHandle (enhed), for at lukke filen.


Dette virker fint, hvis funktionerne kaldes fra hovedtråden. Hvis de bliver kaldt fra en anden tråd, får vi fejl 998 (no\_acccess), når vi forsøger at skrive mere end et par elementer. Trådeene oprettes ved hjælp af


CreateThread(NULL, 0, thread\_func, NULL, 0, &thread\_id);


Jeg løber tør for ideer her, nogen forslag?


redigere:
Når du kører følgende sekvens:


Main\_thread:
CreateFile
Write
Close
CreateThread
WaitForThread

Thread\_B:
CreateFile
Write
Close


Main\_Thread lykkes og Thread\_B gør det ikke. Men når der skrives små sæt data, fungerer det fint. Kan dette skyldes, at Thread\_B ikke arver alle Main\_Threads adgangsrettigheder?


Edit2:
en masse god tænkning foregår her, meget værdsat! Efter noget arbejde på dette problem synes følgende at være tilfældet:


Api indeholder en kø-tråd, der håndterer alle pakker, der går til og fra enheden. Denne tråd håndterer peger til pakkeobjekter. Når en peger når forkanten af ​​køen, kaldes en 'send\_and\_get' -funktion. Hvis arraysne i pakken er tildelt i samme tråd, der kalder funktionen 'send\_and\_get', fungerer det fint. Hvis arraysne er tildelt i en anden tråd, mislykkes sendingen. Sådan repareres dette, men jeg ved det ikke.

Bedste reference


Ifølge winerror er Win32 fejl 998 en af ​​følgende native status værdier (som ville blive returneret af O/S eller driveren):


   998 ERROR\_NOACCESS <--> 0x80000002 STATUS\_DATATYPE\_MISALIGNMENT
   998 ERROR\_NOACCESS <--> 0xc0000005 STATUS\_ACCESS\_VIOLATION
   998 ERROR\_NOACCESS <--> 0xc00002c5 STATUS\_DATATYPE\_MISALIGNMENT\_ERROR


Adgangskrænkelse kan være en sandsynlig kandidat baseret på dig at sige, 'når du forsøger at skrive mere end et par elementer.' Er du sikker på, at den buffer du sender er stor nok?


Justeringsfejlene er ret eksotiske, men det kan være relevant, hvis enheden har nogle justeringskrav, og udvikleren valgte at bruge disse særlige fejl.


-Scott

Andre referencer 1


Lyder stadig for mig som det er samtidig adgang.
Dine separate tråde, der skriver til denne enhed, skal beskytte adgangen til filen korrekt ved hjælp af en mutex eller lignende. Åben håndtaget i hovedtråden og lad det åbne eller beskytte hele Åben -> Skriv -> Luk sekvens, der kan forekomme i hver tråd (med en mutex).

Andre referencer 2


Som en fejlfinding, da det er din egen chauffør, kan du få chaufføren til at logge på de anmodninger, den modtager, fx i hændelsesloggen. Indstil to testkørsler, som er identiske, bortset fra at man kører al koden i hovedtråd og den anden kører al koden i en anden tråd. Sammenligning af resultaterne skal give dig et bedre indblik i, hvad der sker.


Det ville også være en god ide at få din driver til at rapportere eventuelle fejlkoder, at den vender tilbage til operativsystemet.

Andre referencer 3


Den første ting, du bør tjekke, er, om fejlen (998) rapporteret af din chauffør eller kerne-mode I/O-manager (som er ansvarlig for at starte IRP'en og ringe til din chauffør), selv før anmodningen når din chauffør. Du skal kunne opdage dette, da dette er din driver. Log kun opkaldene til driverens Dispatch-rutine, hvad det vender tilbage, hvad det gør (kalder det andre drivere eller opkald IoCompleteRequest med en fejlkode eller osv.), Og ting skal blive klar.


Fra det scenario, du beskriver, ser det ud til at sandsynligvis fejlen skyldes din chauffør. For eksempel kan din driver tildele en global statsstruktur til et svar på CreateFile (som er driverens IRP\_MJ\_CREATE) og rense det, når filen er lukket. en driver vil ikke fungere korrekt, hvis der samtidig åbnes to filer, så lukkes en, mens den anden stadig modtager I/O-anmodninger.