2010-12-07 7 views
21

Hem Linux hem de GNU kullanıcı alanı (glibc) bir dizi "WONTFIX" hatasına sahip gibi görünüyor; yani, sorumlu tarafların ISO C ve/veya POSIX gerekliliklerini açıkça ihlal etmelerine rağmen düzeltmeye isteksiz olduklarını beyan ettikleri hatalar, ama ben ' Bu tür hataları ve çevrelerinde çalışma önerilerini listeleyen programcılar için herhangi bir kaynağın farkında olmamak. İşte GNU/Linux'ta WONTFIX hataları ve bunların etrafında nasıl çalışılır?

akla gelen birkaçı:

  • Linux UDP select hata: select (ve ilgili arayüzler) bayrağı en kısa sürede bir paket alındıktan olarak okunması için hazır bir UDP soket dosya tanımlayıcısı olmadan sağlama toplamını doğrular. Sonraki recv/read/etc'de, eğer sağlama toplamı geçersiz ise, çağrı engellenir. Bunun etrafında çalışmak her zaman UDP soketlerini blokaj yapmayan moda geçirir ve EWOULDBLOCK koşulunu ele alır. Doğru olarak hatırlarsam Maradns bu hatadan etkilenen ilk kayda değer projeydi ve ilk olarak (başarısızlıkla) düzeltmek için şikayetçi oldu. Not: Martin v. Löwis tarafından işaret edildiği gibi, görünüşe göre bu hata düzeltildi. Linux'un gerçekten güncel olmayan sürümlerini desteklemeniz gerekiyorsa, geçici çözümler yalnızca gerekli olabilir.
  • GNU C kitaplığındaki printf ailesi, bir alan kesinliği (%.3s'daki gibi) belirtildiğinde, potansiyel olarak kesilmiş çıktıya neden olduğunda, bağımsız değişkenleri %s olarak bayt dizeleri yerine çok baytlı karakter dizeleri olarak yanlış şekilde ele alır. Tüm printf altsisteminin değiştirilmesi (ya da yalnızca printf işlev ailesini çok baytlı olmayan karakter bayt dizeleriyle değiştirmekten başka bir çözüm bilmiyorum, ancak bir UTF içinde snprintf kullanarak eski kod sayfası dizelerini işlemek istiyorsanız bu sorun olabilir -8 yerel ayar).
  • Bazı syscall'lar için errno sonuç kodları (hangisinin doğru olduğunu hatırlayamıyorum). Genellikle GNU/Linux man sayfalarını okuduysanız ve bunları standartla karşılaştırırsanız, bunları kontrol etmek için yeterince kolaydır. (Bunun için bir referans bulamıyorum ve belki ben yanılıyorum bulabilirim yakın ENOTSUP ve EOPNOTSUP aynı değere sahip bir konudur;. PDTR 24715 bakınız

biraz daha böcek ve geçici çözümler yapabiliriz nelerdir. ? bu listeye eklemek Benim hedeflerini bu soruyu soran şunlardır: hem yeni hem de deneyimli programcılar hızla intended- çalıştırırken ortaya çıkabilecek olası sorunların farkına böylece

  1. böyle hataların daha kapsamlı bir listeyi oluşturmak için GNU/Linux üzerinde taşınabilir program.
  2. SO kolektif beyninden, mümkün olduğunca çok sayıda hata için akıllı ve göze batmayan standart çözümlerin düşünüldüğünü düşünmek yerine, herkes kendi çözümlerini sokulduktan sonra icat etmek yerine, ve belki de en ufak, çirkin, ya da hack yollarla yapmak yerine - ya da Daha da kötüsü, daha uyumlu sistemler için desteği bozacak şekilde.
+7

Kim kapatacaksa, lütfen açıklayınız. Açıkçası bir programlama konusu olan geçici çözümler hakkında soru sorduğumdan bunun konu dışı olabileceğini görmüyorum. Bunu kabul etmenin ayrı bir sebebi olacağını söylemek için hafif bir tartışmacı olduğunu itiraf ediyorum, ancak eğer odak, bu sorunlarla başa çıkacak çözümlere, sadece bir suçlamadan ziyade, göze çarpan bir yöntemle yapıcı bir arayışsa, bunun değerli bir soru olduğunu düşünüyorum. –

+3

Ne bugs? Linux standartlara uygun değilse, yanlış olan standarttır. –

+0

@R .. - sadece şaka. ama bu şekilde düşünen insanlar varsa şaşırmayacağım. Ve değerinde olan şey için - bence bu iyi bir soru. –

cevap

5

Hak talebinde bulunduğunuz yazdırma sorununu yeniden oluşturamıyorum. bana doğru görünen bir de_DE.UTF-8 yerel baskılar "Löw", programı

#include <stdio.h> 
#include <locale.h> 

int main() 
{ 
     setlocale(LC_ALL, ""); 
     printf("%.4s\n", "Löwis"); 
     return 0; 
} 

Running: Ben 4 bayt istedi ve (ö 2 byte) dört bayt var. Kütüphane çok baytlı karakterler sayarsa, çıktı "Löwi" olmalıdır. Bu glibc 2.11.2 ile.

Düzenleme: Dizgiyi "% .2s \ n" olarak değiştirmek yalnızca "L", yani yalnızca bir bayt yazdıracaktır. Ancak, bu the specification uygun, birçok bayt yazılır o daha hassas belirtilirse

, artık diyor ki. Hiçbir durumda

(vurgu madeni), ve daha sonra

kısmi bir karakter yazılır eder.

Böylece kısmi bir karakter yazılan neden olur iki bayt (yani L ve O kurşun bayt) baskı için, tam olmayan UTF-8 baskı uygun olmayan olacaktır.

+0

Güzel Bul! Ama onun asıl sorusu yerine örneklerine odaklanıyorsunuz: böceklerin etrafında nasıl çalışılacağı. Hatalı olduklarını kanıtlamak için her bir örnekte birer birer olmak, sadece onun daha fazla örnek vermesine neden olacaktır. – Konerak

+3

"" xxxö "olarak değiştirmeyi deneyin ve sadece 3 bayt aldığınızı göreceksiniz. Bu aptal bir örnektir, ancak yerel dizinin kodlamasıyla uyuşmayan birden çok farklı kodlamayla dizelerle çalışmaya çalışıyor olsaydınız gerçek bir örnek olurdu. ISO C bunu yapmanıza izin verir (çünkü 's% s' yalnızca bayt cinsinden belirtilmiştir) ancak glibc bunu yasaklamaktadır. Her neyse, bu şeylerin hata olup olmadığını tartışmak istemiyorum. İyi nitelikli insanlar tarafından zaten belgelenmişlerdir. Sorunların ve geçici çözümlerin bir listesini oluşturmayı düşünüyorum. –

+1

Veya hatayı görmek için biçim dizesini ''% .2s ''olarak değiştirin. –

4

UDP sorununun aslında var olduğuna inanmıyorum. Şu anki Linux çekirdeğinde udp_poll

/** 
*  udp_poll - wait for a UDP event. 
*  @file - file struct 
*  @sock - socket 
*  @wait - poll table 
* 
*  This is same as datagram poll, except for the special case of 
*  blocking sockets. If application is using a blocking fd 
*  and a packet with checksum error is in the queue; 
*  then it could get return from select indicating data available 
*  but then block when reading it. Add special case code 
*  to work around these arguably broken applications. 
*/ 
unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait) 
{ 
     unsigned int mask = datagram_poll(file, sock, wait); 
     struct sock *sk = sock->sk; 

     /* Check for false positives due to checksum errors */ 
     if ((mask & POLLRDNORM) && !(file->f_flags & O_NONBLOCK) && 
      !(sk->sk_shutdown & RCV_SHUTDOWN) && !first_packet_length(sk)) 
       mask &= ~(POLLIN | POLLRDNORM); 

     return mask; 

} 

Yani buna select/anket yoluyla rapor ediliyor kötü sağlama ile UDP paketlerini gizlemek yok geliyor bana okur. Bu versiyon 85584672 (2009) revizyonundan beri kullanılmaktadır. Fakat daha önce de (en azından 2005'ten beri), kod, görünüşte, seçim/yoklamada kötü paketlerin aynı türünü yapıyordu.

+0

Güzel Bul! Ama onun asıl sorusu yerine örneklerine odaklanıyorsunuz: böceklerin etrafında nasıl çalışılacağı. Hatalı olduklarını kanıtlamak için her bir örnekte birer birer olmak, sadece onun daha fazla örnek vermesine neden olacaktır. – Konerak

+3

Ancak bu makalenin iddia edilen amacı: belirli sorunları bulmak ve belirli çalışma ortamları göndermek. Dolayısıyla, ilk iki sorun için, hiçbir işin gerekmediği ortaya çıkmaktadır (mevcut sürümlerle en azından). Yani bunların gerçek bir sorun olduğuna inanan herkes, onların olmadıklarını bilerek yardımcı olmaktır. Gerçek hatalar ortaya çıkarsa, iş çevrelerini tartışmaya başlayabiliriz. –

+0

Birinde haklısınız. Bunu bir WONTFIX olarak listeledim, çünkü aslında böyle bir şeydi. Görünüşe göre yeterince insan sonunda şikâyet etti (ya da belki de çekirdek içselleri bunu düzeltmek için yeteri kadar değişti) aslında düzeltildi. Bulduğun için teşekkürler. Öte yandan, standardı yanlış okudunuz. –

İlgili konular