[c++] Valgrind hangt op stat() in FUSE uit ander thread

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • cyberstalker
  • Registratie: September 2005
  • Niet online

cyberstalker

Eersteklas beunhaas

Topicstarter
Ik heb een filesystem geschreven middels FUSE. Hiervoor ben ik nu integratie-tests aan het schrijven. Hiervoor maak ik de FUSE mount in een ander thread en test ik dan verschillende operaties op deze mount vanuit de main thread.

Dit werkt allemaal prima, maar ik wil alle tests ook graag via valgrind kunnen draaien. Dat gaat stuk bij het uitvoeren van de integratie-test. Als ik valgrind strace, dan zie ik dat deze hangt op de stat() call. Deze blijft oneindig lang wachten. Valgrind gebruikt op dat moment geen CPU en strace blijft dan ook stlistaan. De enige manier hieruit is het proces te SIGKILL-en.

Nu heb ik ergens gelezen dat valgrind je code single-threaded draait. Is er een manier om dit toch op deze manier te testen of zal ik moeten forken en een apart proces moeten starten voor het mountpoint?

Ik ontken het bestaan van IE.


Acties:
  • 0 Henk 'm!

  • Matis
  • Registratie: Januari 2007
  • Laatst online: 07-10 19:27

Matis

Rubber Rocket

Valgrind zelf draait single threaded, maar hij emuleert wel degelijk meerdere threads.
Voor wat betreft je probleem, daar kan ik je niet mee helpen.
Ik weet niet zeker of een hoe valgrind overweg kan met system calls.

If money talks then I'm a mime
If time is money then I'm out of time


Acties:
  • 0 Henk 'm!

  • Radiant
  • Registratie: Juli 2003
  • Niet online

Radiant

Certified MS Bob Administrator

Wat doen de verschillende threads verder? Blijft die mount-thread gewoon wachten of doe je iets van signalling?

Wellicht dat je gewoon ergens een deadlock hebt die nu toevallig door valgrind getriggerd wordt om een of andere reden (omdat de timings net iets anders zijn, bijvoorbeeld).

Acties:
  • 0 Henk 'm!

  • cyberstalker
  • Registratie: September 2005
  • Niet online

cyberstalker

Eersteklas beunhaas

Topicstarter
Die mount-thread draait gewoon een event loop die leest van de FUSE fd. Die zou dus moeten gaan lezen op het moment dat ik vanuit de main thread een operatie doe (zoals stat()). Dat gebeurt niet wanneer ik vanuit valgrind draai.

De enige signalling die ik overigens doe is een async watcher die ik vanuit de main thread trigger die in de mount-thread de FUSE sessie beeindigd, waarna de event loop stopt (omdat er geen watchers meer actief zijn).

De hele FUSE mount is dus event-driven geschreven, maar voor testen is het wel zo makkelijk om gewoon synchrone code te kunnen maken. Performance is dan toch van secundair belang.

[ Voor 16% gewijzigd door cyberstalker op 14-02-2017 10:39 ]

Ik ontken het bestaan van IE.


Acties:
  • +1 Henk 'm!

  • Radiant
  • Registratie: Juli 2003
  • Niet online

Radiant

Certified MS Bob Administrator

Interessant leesvoer: http://valgrind.org/docs/...html#manual-core.pthreads

Als ik de aanname doe dat valgrind het vrijgeven van zijn 'lock' doet binnen de context van de thread die de lock momenteel heeft (dit kan ik niet terugvinden in de docs) gaat dit nooit gebeuren omdat die thread 'hangt' in een system call, gaat je andere thread ook nooit lopen en wordt logischerwijs de system call nooit afgemaakt.

Je kan die andere locking methode die ze noemen eens proberen en anders zou ik inderdaad maar eens kijken of je niet kan forken of valgrind kan vertellen dat hij een van de twee threads niet moet monitoren.

Als je perse beide threads wil monitoren zou je ze in twee processen en twee afzonderlijke valgrind-instanties kunnen draaien en IPC gebruiken.

Acties:
  • +1 Henk 'm!

  • cyberstalker
  • Registratie: September 2005
  • Niet online

cyberstalker

Eersteklas beunhaas

Topicstarter
Bedankt voor de suggestie. Helaas heeft het wijzigen van locking options niet mogen helpen. Ik heb het nu maar opgegeven en de Makefile aangepast zodat deze clang's address sanitizer gebruikt. Deze werkt gewoon out-of-the-box (en nog eens een stuk sneller ook). Geen idee of deze net zo grondig is als valgrind, maar voor nu lijkt het afdoende te zijn.

Ik ontken het bestaan van IE.


Acties:
  • 0 Henk 'm!

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
Eerlijk gezegd is valgrind een C tool. C++ code schrijf je met RAII, dan zijn memory leaks geen zorg meer.

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


Acties:
  • +1 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 08-10 20:31

.oisyn

Moderator Devschuur®

Demotivational Speaker

Dat is wat kort door de bocht. Om dezelfde reden zijn er ook nog steeds memory leaks in GC talen: slecht opgezette object lifetimes.

[ Voor 4% gewijzigd door .oisyn op 16-02-2017 21:44 ]

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.


  • Rukapul
  • Registratie: Februari 2000
  • Laatst online: 17:16
Valgrind doet ook wel iets meer dan alleen memory leaks detecteren.

Een testmethode die juist onafhankelijk is van (fouten makende ontwikkelaars, want mens) is een prima method om robustere code op te leveren. Buffer overflows, read-before-write zijn ook aardig om mee te pakken. of juist die ene subtiele endianness error long ago die het devteam niet gevonden kreeg

Acties:
  • 0 Henk 'm!

  • cyberstalker
  • Registratie: September 2005
  • Niet online

cyberstalker

Eersteklas beunhaas

Topicstarter
MSalters schreef op woensdag 15 februari 2017 @ 21:54:
Eerlijk gezegd is valgrind een C tool. C++ code schrijf je met RAII, dan zijn memory leaks geen zorg meer.
Interessant. Hoe doe je dit precies als je asynchrone code schrijft? Stel dat je bijvoorbeeld een bestand uitleest. Hoe alloceer je dan een buffer voor de data op de stack en zorg je dat deze beschikbaar blijft tot nadat de callback voltooid is?

Ik ontken het bestaan van IE.


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 08-10 20:31

.oisyn

Moderator Devschuur®

Demotivational Speaker

Je callback object (typisch een closure) kan toch een std::vector<char> ownen?

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.


Acties:
  • 0 Henk 'm!

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
cyberstalker schreef op vrijdag 17 februari 2017 @ 19:00:
[...]

Interessant. Hoe doe je dit precies als je asynchrone code schrijft? Stel dat je bijvoorbeeld een bestand uitleest. Hoe alloceer je dan een buffer voor de data op de stack en zorg je dat deze beschikbaar blijft tot nadat de callback voltooid is?
Kwestie van Boost.asio gebruiken. Het idee dat jij verantwoordelijk bent voor de IO buffer is ook al een C idee.

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


Acties:
  • 0 Henk 'm!

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

H!GHGuY

Try and take over the world...

De file die ge-stat() wordt staat toevallig niet op je fuse mountpoint?

Afhankelijk van je kernel kan het ook zijn dat je een kernel deadlock triggert hierdoor. In latere kernels gebeuren pathname lookups optimistisch onder RCU met fallback op locking, in oudere kernels was dit sowieso een lock. Mogelijk heb je dus een deadlock op dat niveau.

Als je even 2 minuten wacht (althans zo staan de defaults op veel distro's) zou je mogelijk een "hung task timeout" in de kernel logs kunnen krijgen. Anders kun je ook via /proc/sysrq-trigger (voor help: echo 'h' > /proc/sysrq-trigger; dmesg | tail) even alle kernel tasks hun stacktrace laten dumpen in de kernel logs. Dan zie je meteen of je zo'n deadlock gemaakt hebt.

ASSUME makes an ASS out of U and ME

Pagina: 1