2010-12-07 6 views
21

Tanto Linux como el espacio de usuario GNU (glibc) parecen tener varios errores "WONTFIX", es decir, errores que las partes responsables han declarado no estar dispuestos a corregir a pesar de violar claramente los requisitos de ISO C y/o POSIX, pero yo No estoy al tanto de ningún recurso para programadores que enumere dichos errores y sugerencias para evitarlos.¿Qué son los errores de WONTFIX en GNU/Linux y cómo solucionarlos?

Éstos son algunos que vienen a la mente:

  • El Linux UDP select error: select (e interfaces relacionadas) bandera de un descriptor de archivo de socket UDP listo para leer tan pronto como un paquete ha sido recibido, sin confirmando la suma de comprobación. En los siguientes recv/read/etc., Si la suma de comprobación no es válida, la llamada se bloqueará. Para solucionar este problema, es necesario configurar siempre los sockets UDP en modo no bloqueante y tratar con la condición EWOULDBLOCK. Si mal no recuerdo, MaraDNS fue el primer proyecto notable afectado por este error y el primero en quejarse (sin éxito) para que lo arreglaran. Nota: Como señaló Martin v. Löwis, aparentemente este error ya se solucionó. Las soluciones temporales probablemente solo sean necesarias si necesita admitir versiones realmente desactualizadas de Linux.
  • La familia printf en la biblioteca C de GNU trata erróneamente argumentos como %s como cadenas de caracteres multibyte en lugar de cadenas de bytes cuando se especifica una precisión de campo (como en %.3s), lo que puede causar una salida truncada. No conozco ninguna solución excepto reemplazar todo el subsistema printf (o simplemente no usar la familia de funciones printf con cadenas de bytes de caracteres no multibyte, pero esto puede ser problemático si desea procesar cadenas de páginas de códigos heredadas usando snprintf mientras está en un UTF -8 configuración regional).
  • Incorrecto errno códigos de resultado para ciertas llamadas de sistema (no recuerdo cuales son correctas). Por lo general, estos son fáciles de verificar si solo lee las páginas Man de GNU/Linux y las compara con el estándar. (No puedo encontrar las referencias para este y tal vez me equivoque El más cercano que puedo encontrar es el tema de ENOTSUP y EOPNOTSUP tener el mismo valor;. Ver PDTR 24715

¿Cuáles son algunos más errores y soluciones que podamos. ? añadir a esta lista Mis objetivos al hacer esta pregunta son:

  1. para construir una lista más completa de tales errores de manera que los nuevos y experimentados programadores pueden convertirse rápidamente en conocer los posibles problemas que pueden surgir cuando se ejecuta una intended- programa para ser portátil en GNU/Linux.
  2. Aprovechar el cerebro colectivo SO para idear soluciones estándar inteligentes y discretas para tantos errores como sea posible, en lugar de que todos tengan que inventar sus propios métodos alternativos después de ser picados, y posiblemente hacerlo de maneras menos óptimas, feas o hackosas, o peor aún, de maneras que rompen el apoyo para sistemas más conformes.
+7

Quien haya votado para cerrar, por favor explique. No veo cómo podría estar fuera de tema ya que pregunté sobre soluciones alternativas que son claramente un tema de programación. Admito que es un poco argumentativo que sería una razón separada para proponer el cierre, pero si el enfoque es una búsqueda constructiva de soluciones que aborden estos problemas de manera discreta en lugar de simplemente una censura, creo que es una pregunta que vale la pena. –

+3

¿Qué errores? Si Linux no cumple con los estándares, es claramente el estándar que está mal. –

+0

@R .. - Es una broma. pero no me sorprendería si hay personas que realmente piensan de esta manera. Y por lo que vale, creo que esta es una buena pregunta. –

Respuesta

5

No puedo reproducir el problema de impresión que usted reclama. Al ejecutar el programa

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

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

en un de_DE.UTF-8 impresiones locale "bajo", que se ve bien para mí: Pedí 4 bytes, y tengo cuatro bytes (o es 2 bytes). Si la biblioteca hubiera contado caracteres de varios bytes, la salida debería haber sido "Löwi". Esto es con glibc 2.11.2.

Editar: Al cambiar la cadena a "% .2s \ n", solo se imprimirá "L", es decir, solo un byte. Sin embargo, esto es conforme a the specification, que dice

Si no se especifica la precisión, no más de que muchos bytes deben ser escritos.

(el énfasis es mío), y luego

En ningún caso un carácter parcial escribirse.

Así que desde la impresión de dos bytes (es decir, la L, y el byte inicial de O) daría como resultado un carácter parcial siendo escrita, sería no conforme a imprimir UTF-8 incompleta.

+0

¡Bonito hallazgo! Pero te estás enfocando en sus ejemplos en lugar de su pregunta real: cómo evitar los errores. Yendo después de cada ejemplo, uno por uno, para demostrar que no son insectos, solo hará que escuche más ejemplos. – Konerak

+3

Intenta cambiarlo a '" xxxö "' y verás que obtienes solo 3 bytes. Este es un ejemplo tonto, pero un ejemplo real sería si estuvieras tratando de trabajar con cadenas en múltiples codificaciones diferentes que no coinciden con la codificación de la configuración regional. ISO C le permite hacer esto (porque '% s' se especifica puramente en términos de bytes) pero glibc lo prohíbe. De todos modos, no quiero discutir si estas cosas son errores. Ya están bien documentados por personas bien calificadas. Pregunto sobre la construcción de una lista de problemas y soluciones. –

+1

O simplemente cambie la cadena de formato a '"% .2s "' para ver el error. –

4

No creo que el problema UDP realmente exista. En el núcleo Linux actual, udp_poll lee

/** 
*  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; 

} 

Por lo tanto, me parece que se esconde paquetes UDP con malas sumas de comprobación de ser reportada a través de selección/sondeo. Esta versión del código se está utilizando desde la revisión 85584672 (2009). Pero incluso antes (al menos desde 2005), el código aparentemente estaba haciendo el mismo tipo de eliminación de paquetes malos en select/poll.

+0

¡Bonito hallazgo! Pero te estás enfocando en sus ejemplos en lugar de su pregunta real: cómo evitar los errores. Yendo después de cada ejemplo, uno por uno, para demostrar que no son insectos, solo hará que escuche más ejemplos. – Konerak

+3

Pero ese es el objetivo declarado de este artículo: encontrar problemas específicos y publicar soluciones específicas. Por lo tanto, para los primeros dos problemas, resulta que no se necesita una solución alternativa (al menos con las versiones actuales). Entonces, cualquier persona que crea que se trata de un problema real es ayudado sabiendo que no es así. Si se presentan errores reales, entonces podríamos comenzar a discutir soluciones alternativas. –

+0

Tienes razón. Lo enumeré como WONTFIX porque así era originalmente. Aparentemente, la gente eventualmente se quejó (o tal vez las partes internas del kernel cambiaron lo suficiente como para que arreglarlo se volviera fácil) que en realidad fue arreglado. Gracias por el hallazgo En cuanto a la otra, has leído mal el estándar. –

Cuestiones relacionadas