Errores estúpidos en C. Break, Switch, If. 1990 Crash de red telefónica

Estaba dudando en preguntar esto, ya que parece muy fácil.

¿Qué está mal en este pseudocódigo?

En el software de conmutación (escrito en C), había;

  • un largo “do … while” construye, que contiene
  • una statement de “cambio”, que contenía
  • una cláusula “si”, que contenía
  • una “pausa”, que estaba destinada a la cláusula “if”
    • pero en su lugar se rompió de la statement de “cambio”.

Esto provocó una caída del sistema telefónico en 1990 (consulte: http://users.csc.calpoly.edu/~jdalbey/SWE/Papers/att_collapse.html ).

Necesito una explicación muy simple, por qué este código es incorrecto. Creo que la respuesta más simple es que, dentro de una cláusula if, no es posible una ruptura. Entonces, ¿qué statement debe escribirse en lugar de una ruptura dentro de una cláusula if para obtener el efecto deseado, que es la ruptura de la cláusula if?

Sospecho que la descripción / pseudocódigo es incorrecta cuando dice:

  • una “ruptura”, que estaba destinada a la cláusula “if”

Tendría sentido si se supone que eso es:

  • una break , que estaba destinada a terminar el bucle do while while

La descripción del problema tiene sentido.

 do { ... switch (...) { case ...: ... break; ... case ...: ... if (critical_condition()) break; // Intended to exit loop - actually exits switch only ... break; // Terminates the case in the switch } } while (!time_to_stop()); 

Leyendo la URL a la que se hace referencia en la pregunta, el pseudo-código es:

En pseudocódigo, el progtwig dice lo siguiente:

 1 while (ring receive buffer not empty and side buffer not empty) DO 2 Initialize pointer to first message in side buffer or ring receive buffer 3 get copy of buffer 4 switch (message) 5 case (incoming_message): 6 if (sending switch is out of service) DO 7 if (ring write buffer is empty) DO 8 send "in service" to status map 9 else 10 break END IF 11 process incoming message, set up pointers to optional parameters 12 break END SWITCH 13 do optional parameter work 

Cuando el interruptor de destino recibió el segundo de los dos mensajes cronometrados mientras aún estaba ocupado con el primero (búfer no vacío, línea 7), el progtwig debería haber salido de la cláusula if (línea 7), procesó el mensaje entrante, y configurar los punteros a la base de datos (línea 11). En cambio, debido a la statement de interrupción en la cláusula else (línea 10), el progtwig abandonó la statement del caso por completo y comenzó a realizar un trabajo de parámetros opcionales que sobrescribió los datos (línea 13). El software de corrección de errores detectó la sobrescritura y apagó el interruptor mientras se reinicia [ sic ]. Debido a que cada conmutador contenía el mismo software, los reinicios se conectaban en cascada por la red, incapacitando al sistema.

Esto concuerda con mi hipótesis: el pseudocódigo en la pregunta es una caracterización incorrecta del pseudocódigo en el documento.


Otra referencia sobre el mismo tema (encontrada a través de una búsqueda de Google ‘att crash 1990 4ess’) dice:

Error de descripción

Lo que se informó en las Notas de ingeniería de software de ACM [Referencia 2] es que el defecto del software se debió a un error de progtwigción elemental, que se describe a continuación:

En el texto del progtwig “C” ofensivo había una construcción de la forma: [ Sangría errática como en el original ]

 /* ``C'' Fragment to Illustrate AT&T Defect */ do { switch expression { ... case (value): if (logical) { sequence of statements break } else { another sequence of statements } statements after if...else statement } statements after case statement } while (expression) statements after do...while statement 

Error de progtwigción descrito

El error es que el progtwigdor pensó que la statement de interrupción aplicada a la instrucción if en el pasaje anterior, claramente nunca se ejercitó. Si lo hubiera sido, entonces los evaluadores habrían notado el comportamiento anormal y habrían podido corregir [ sic ]

La única advertencia a esta statement es la siguiente: es posible que las pruebas aplicadas al código contengan información que revele el error; sin embargo, si los evaluadores no examinan la salida y notan el error, entonces la deficiencia no es con esto [ sic ]

En el caso de una statement de ruptura fuera de lugar, es muy probable que el error se haya detectado.

Referencias

  1. “¿Podemos confiar en nuestro software?”, Newsweek, 29 de enero de 1990.

  2. ACM SIGSOFT, Software Engineering Notes, vol. 15, No. 2, página 11ff, abril 1990.


Aparentemente, el progtwigdor realmente pensó que la break terminaría con la sentencia if ; fue un pequeño apagón mental que llevó a un gran apagón en el mundo real.

Si lo entiendo bien, el bloque else donde se produce la statement de break incriminada es simplemente parte de ese “error de una línea” como se llama antes de 1 . No veo ninguna buena razón para que esa else exista allí, a menos que se pensara que los “ciertos tipos de mensajes” que recibieron la optimización fueron la única ocurrencia de un búfer no vacío al procesar un mensaje. La descripción que vinculó pierde buenas ofertas de conocimiento de dominio, sin la cual al menos no puedo entender completamente ese fragmento de código. Intentaré de todos modos dar una explicación.

Como las declaraciones de break solo pueden referirse a un switch o un bucle, puedo asumir que:

hipótesis # 1

el codificador original pretendía “acelerar el procesamiento de ciertos tipos de mensajes” cortando la instrucción while con tal break . Sin embargo, el anidamiento engañó al chico y lo dejó supervisar que la statement de switch y no el while se vio afectado por la break .

hipótesis # 2

el codificador original realmente tenía la intención de terminar rápidamente la instrucción de switch , pero puso esa break demasiado pronto y se olvidó de actualizar los punteros a los parámetros opcionales, por ejemplo, marcando que no se proporcionaron parámetros opcionales con el mensaje actual.

  1. Así lo llamaría “bug de dos líneas”