Yon lòt Heisenbug pase kwokodil la

Yon lòt Heisenbug pase kwokodil la

$> set -o pipefail

$> fortune | head -1 > /dev/null && echo "Повезло!" || echo "Вы проиграли"
Повезло!

$> fortune | head -1 > /dev/null && echo "Повезло!" || echo "Вы проиграли"
Вы проиграли

Isit la fortune pwogram kondisyonèl san exit(rand()).

Èske ou ka eksplike? sa ki mal isit la?

Digresyon lirik-istorik

Mwen te vin fè konesans ak Heisenbug sa a yon ka nan yon syèk de sa. Lè sa a, pou pòtay la nan FaxNET li te nesesè yo kreye plizyè sèvis piblik atravè tiyo "jwe dam" anba FreeBSD. Kòm espere, mwen konsidere tèt mwen yon pwogramè avanse ak san patipri ki gen eksperyans. Se poutèt sa, mwen te gen entansyon fè tout bagay ak anpil atansyon epi ak anpil atansyon ke posib, peye atansyon espesyal sou manyen erè ...

Eksperyans anvan mwen nan fè fas ak ensèk nan sendmail ak uucp/uupc te ajoute nan dilijans mwen nan "manyen erè apwofondi." Pa gen okenn pwen nan plonje nan detay yo nan istwa sa a, men mwen te plede ak Heisenbug sa a pou de semèn pou 10-14 èdtan. Se poutèt sa, li te vin chonje, e yè ansyen zanmi sa a te sispann vizite ankò.

TL;DR Repons

Sèvis piblik head kapab fèmen kanal la soti nan fortune touswit le pli vit ke li li premye liy lan. Si fortune rezilta plis pase yon liy, Lè sa a, apèl ki koresponn lan write() pral retounen yon erè oswa rapòte ke mwens byte yo pwodiksyon pase sa yo mande a. Nan vire, ekri ak manyen erè atansyon fortune gen dwa reflete sitiyasyon sa a nan estati sòti li. Lè sa a, akòz enstalasyon set -o pipefail pral travay || echo "Вы проиграли".

Sepandan, head gendwa pa rive nan tan fèmen anvan fortune pral fini pwodiksyon done. Lè sa a, li pral travay && echo "Повезло!".

Nan youn nan jodi a mwen GNUMakefile gen konsa fragman:

echo '#define MDBX_BUILD_COMPILER "$(shell set -o pipefail; $(CC) --version | head -1 || echo 'Please use GCC or CLANG compatible compiler')"'

Tradui nan moun

Li komen isit la pou GNU Fè и frape nan fason konpilatè a lè l sèvi avèk opsyon an --version li mande ki moun li ye, epi si opsyon a pa sipòte, Lè sa a, yo mete yon souch "Tanpri itilize GCC oswa CLANG konpatib du".

Tankou chodyè ka jwenn nenpòt kote. Li te parèt nan kote sa a depi lontan e li te travay pafètman toupatou (Linux, Solaris, OSX, FreeBSD, WSL elatriye). Men yè nan altlinux sou platfòm lan Elbrus 2000 (E2K) Mwen remake:

#define MDBX_BUILD_COMPILER "lcc:1.23.20:Sep--4-2019:e2k-v3-linux Please use GCC or CLANG compatible compiler"

Franchman, mwen pa t 'rekonèt imedyatman ansyen "konesans" mwen an. Anplis, pwojè a te deja teste anpil fwa sou Elbrus ak anba yon anpil nan distribisyon diferan, ki gen ladan Alt. Avèk divès kalite konpilateur, vèsyon GNU Make ak bash. Se poutèt sa, mwen pa t 'vle wè erè mwen an isit la.

Lè w ap eseye repwodui pwoblèm nan ak/oswa konprann sa k ap pase, bagay ki pi etranj yo te kòmanse rive.
Eple liy kòmand:

echo "#define MDBX_BUILD_COMPILER '$(set -o pipefail; LC_ALL=C cc --version | head -1 || echo "Please use GCC or CLANG compatible compiler")'"

Chak kounye a epi Lè sa a, li ta pwodwi tèks siplemantè, Lè sa a, pa... Souvan youn nan opsyon yo ta bwa pou yon tan byen long, men si ou poked pi lontan, ou toujou jwenn tou de!

Natirèlman, strace tout bagay nou! Apre sa, mwen te tape yon tirad strace, men pa gen tan peze Antre, mwen rekonèt ansyen zanmi m 'Mesye Heisenbug, ak devlopè yo. du tèt mwen 25 ane de sa, Nostalgie… E mwen deside tris epi ekri nòt sa 😉

By wout la, tankou nenpòt ki respekte tèt yo Heisenbug, anba strace prefere pa repwodui.

Se konsa, sa k ap pase?

  • Sèvis piblik head gen dwa (oswa pito, se menm fòse) fèmen kanal la ke yo te li le pli vit ke li li kantite yo mande nan liy.
  • Ekriven pwogram ki jenere done (nan ka sa a cc) kapab enprime plizyè liy ak gratis fè sa atravè plizyè apèl write().
  • Si lektè a ap gen tan fèmen kanal la sou bò li anvan fen anrejistreman sou bò ekriven an, Lè sa a, ekriven an ap resevwa yon erè.
  • Pwogram ekriven gen dwa tou de inyore erè ekri chanèl la epi reflete li nan kòd fini ou a.
  • Akòz enstalasyon set -o pipefail kòd fini tiyo a pral ki pa zewo (erè) si rezilta a se ki pa zewo soti nan omwen yon eleman, ak Lè sa a, li pral travay. || echo "Please use GCC or CLANG compatible compiler".

Ka gen varyasyon selon jan pwogram ekriven travay ak siyal yo. Pa egzanp, pwogram nan ka fini anòmalman (ak jenerasyon otomatik yon estati revokasyon ki pa zewo/erè), oswa write() pral retounen rezilta a nan ekri mwens byte pase sa yo mande ak mete errno = EPIPE.

Ki moun ki koupab?

Nan ka ki dekri a ti kras nan tout bagay. Erè manyen nan cc (lcc:1.23.20:Sep—4-2019:e2k-v3-linux) se pa redondants. Nan anpil ka li pi bon pou fè erè sou bò a nan prekosyon, byenke sa a ekspoze defo toudenkou nan yon boilerplate ki fèt pou konpòtman tradisyonèl yo.

Ki sa ki fè?

Mal:

fortune | head -1 && echo "Повезло, но вы рискуете!" || echo "WTF?"

Kòrèkteman:

  1. (fortune && echo "Успешно" || echo "Ошибка") | head -1

    Isit la, entèprèt kòmand la pral okipe fèmen pi bonè yon tiyo lè w ap fè sèvis tiyo enbrike la ("nan" parantèz yo). An konsekans, si fortune pral rapòte yon erè alekri nan yon kanal fèmen nan estati a, Lè sa a, pwodiksyon an || echo "Ошибка" li pap jwenn okenn kote, paske kanal la deja fèmen.

  2. fortune | cat - | head -1 && echo "Успешно" || echo "Ошибка"

    Isit la nan sèvis piblik la cat aji kòm yon amortisseur paske li inyore erè a EPIPE sou retrè. Sa a se ase pou kounye a konklizyon fortune ti (plizyè liy) ak adapte nan tanpon chanèl la (soti nan 512 bytes a ≈64K, nan pifò OS ≥4K). Sinon pwoblèm nan ka retounen.

Ki jan yo trete kòrèkteman EPIPE ak lòt erè anrejistreman?

Pa gen yon sèl solisyon bon, men gen rekòmandasyon senp:

  • EPIPE egzije dwe trete (ak reflete nan estati a sòti) lè pwodiksyon done ki mande entegrite. Pou egzanp, pandan operasyon an nan achiv oswa sèvis piblik backup.
  • EPIPE pi bon pou inyore lè w ap montre enfòmasyon ak mesaj oksilyè. Pou egzanp, lè w ap montre enfòmasyon sou opsyon --help oswa --version.
  • Si kòd la ap devlope ka itilize nan yon tiyo anvan | head, Lè sa a, EPIPE Li se pi bon inyore, otreman li se pi bon nan pwosesis ak reflete nan estati a sòti.

Mwen ta renmen pwofite okazyon sa a pou m eksprime rekonesans mwen anvè ekip yo MCST и altlinux pou gwo travay pwodiktif. Detèminasyon ou se etonan!
Kenbe la Camarades, leve reyinyon nan sezon otòn la!

Mèsi berez pou korije fot ak erè.
KDPV soti nan Georgy A.

Sous: www.habr.com

Add nouvo kòmantè