2009-03-12 11 views
8

He oído a menudo que C puede estrellarse espectacularmente. Recientemente tuve mi primera prueba de esto cuando una función que esperaba devolver una cadena en su lugar devuelve pequeñas caras felices. Desde entonces he sido más cuidadoso con la inicialización de punteros y la memoria mallocing para matrices. Aún así, sin embargo, tengo problemas para creer que un programa podría fallar TAN mal ...¿cuánto se puede bloquear c?

Supongo que dependerá del alcance del programa. Quiero decir, si un error en un programa que trata con tu fan copia caras felices en algún espacio importante en la memoria ...?

Mi pregunta es, ¿cuánto mito hay en el mundo de los espectaculares accidentes C? ¿Puedo obtener algunos ejemplos concretos de cosas peligrosas que uno debería evitar?

z.

+7

"... volvieron caras felices", al menos murió con una sonrisa en su rostro? – David

+0

Es posible que desee agregar el hecho de que está ejecutando esto en una Nintendo DS, ya que los comentarios, ideas y sugerencias de los usuarios pueden ser completamente diferentes en función de ese escenario. –

+0

¿qué tan malo quieres que se cuelgue? – user21714

Respuesta

8

El sistema operativo evita la mayoría de los problemas horribles en estos días. Lo peor que he hecho es bloquear la máquina (solo tuve que reiniciar manteniendo presionado el botón de encendido) y mezclar algunos archivos.

Todo depende de qué recursos está accediendo realmente. Si está escribiendo archivos, existen algunas formas en que las estructuras de directorios pueden enredarse, lo que solía confundir las utilidades del sistema, pero la mayoría de esos problemas se han solucionado. Si está haciendo algo como root, bueno, entonces seguramente puede hacer un lío porque muchos más archivos del sistema son grabables. Si está usando la red, hay muchas cosas que pueden ir moderadamente mal, pero no es mucho más que usar demasiado ancho de banda. Por supuesto, unos años de programación y verá todo tipo de cosas improbables.

En su mayor parte, sin embargo, está bien experimentar y jugar. En estos días, los sistemas son lo suficientemente resistentes como para no hacer un lío del que es demasiado difícil salir. El sistema operativo mantiene cada programa en su propia pieza de memoria y no permite el acceso para cambiar los sistemas críticos a menos que sea administrador/root. Su puntero colgante de variedad de jardín puede imprimir cosas divertidas o bloquear su programa, pero no va a destruir una computadora moderna.

Desde un comentario en otra respuesta: "Estoy usando la Nintendo DS para ejecutarlos"

Ok, que importa! (Primero: idea increíble! Suena divertido.) Codificar para algo así no es lo mismo en términos de lo que puede salir mal como la mayoría de los códigos para una computadora de escritorio. Un breve vistazo a la documentación de libnings y algunos tutoriales sobre programación de Nintendo DS me indica que no hay ningún sistema operativo para hablar. Entonces, no tengo idea de cuánto podría hacer con un puntero, probablemente mucho. Posiblemente algo dañino. Puede ser una buena idea buscar personas que hayan hecho programación para esa plataforma antes, ver lo que tienen que decir.

+0

Hmm yeah! He estado ejecutando mi programa en un emulador de DS, pero estoy muerto de miedo de probarlo en mi DS. Desearía que los chicos de Liberty leyeran Stackoverflow. – Ziggy

17

Creo que probablemente fue peor en los días de memoria pre-virtual cuando se podía destruir la memoria de otros procesos, pero hoy en día lo peor que puede pasar es simplemente bloquear tu propio programa. Por lo general, a través de fallas de segmentación de punteros malos.

Eso excluye, por supuesto, explotar cosas al mal uso de los recursos del sistema; puede hacerlo en cualquier idioma.

+0

A menos que escriba código en un dispositivo incrustado sin un sistema operativo o escriba controladores de dispositivo del sistema operativo. En ese caso, es divertido si un desbordamiento de búfer puede escribir en la memoria asignada de IO, lo que hace que muestre valores de basura en esos pines IO, que controla la velocidad de un motor y hace que acelere ... – nos

10

Lo peor que me ha pasado eran corrupción de memoria que no causan un accidente de inmediato, pero después de un tiempo .. lo que es tan difícil de detectar .. argh

+0

Me volví paranoico sobre abusar de assert for un tiempo debido a un escenario como el suyo, donde un pequeño error poco a poco se filtra la memoria o, peor aún, corrompe los datos en silencio durante un período de tiempo. – David

5

Bueno, si estás escribiendo código del núcleo , a veces puede sobrescribir los bits críticos de la memoria del sistema, como vectores de interrupción, tablas de descriptores globales, tablas de procesos, ¡y todo tipo de cosas divertidas!

1

Si el código se ejecuta en un sistema operativo de forma remota moderna, no se puede copiar caras felices en puntos al azar en la memoria. Puede bloquear todo lo que quiera, y solo dará como resultado la finalización de su proceso.

Lo más cerca que puede llegar a estropear realmente su sistema es abusar de los recursos de procesador/memoria/disco, o generar tantos subprocesos que el sistema operativo se queda sin PID (si todavía está utilizando un valor de 32 bits para almacenarlos) .

+0

Considerando que el sistema operativo debe asignar una pila para cada proceso y espacio suficiente en la memoria para el proceso en sí, me imagino que se quedaría sin memoria antes de que el sistema operativo se quede sin PID. – dreamlax

3

Hoy en día es un poco difícil hacer que C falle que es difícil (a menos que esté codificando un kernel del sistema operativo o algo así).

De vuelta en los días DOS/Win95/Win98, podría hacer que un programa C chash realmente, realmente mal. Solía ​​obtener esto mucho:

Cada vez que tenía una operación de puntero peligroso que estropeó la memoria, conseguí una pantalla basada en caracteres llena de todo tipo de personajes, en diferentes colores, algunos de ellos, parpadeando !!! Supongo que las operaciones arruinaron de alguna manera la memoria de video.

Pero hoy, dado que los procesos se ejecutan en kernels seguros, lo peor que obtendrá si su proceso se va.

5

C no puede colgar nada. La programación descuidada puede bloquear todo.

Las "caras felices" son una indicación de que su código ha dañado la memoria. Lo único que C tuvo que ver con eso es el hecho de que eligió usarlo. (Y el hecho de que su sistema operativo permitió que ocurriera es sorprendente - ¿todavía está ejecutando una versión de DOS?)

+0

Eh, aún puede garabatear en la memoria siempre que sea suya: P ¡También puede leer los indicadores de memoria pasados, una vez más, siempre que sea suyo! ¡Entonces no necesitas ejecutar DOS solo para que aparezcan caras sonrientes! –

+0

Punto tomado. Supongo que ha pasado tanto tiempo desde que lo hice que no hubiera pensado que todavía era posible. La última vez que me sucedió, IIRC era DOS 3.2, y tuve caras felices y tristes y colores parpadeantes. :-) Muy atractivo, en realidad. –

+0

sin embargo, no estoy usando Windows para ejecutar mis programas, solo para compilarlos. Estoy usando la Nintendo DS para ejecutarlos, ¡así que debo ser más cuidadoso! – Ziggy

12

Cuando estaba aprendiendo a programar C++, estaba en un sistema Mac corriendo 7 u 8 No lo hago recuerda cual. De todos modos, no tenía memoria virtual protegida, por lo que muchos errores, como dejar un puntero colgando o un desbordamiento del búfer, provocarían la falla de toda la computadora. Recuerdo que cuando Apple anunció por primera vez que iban a crear un nuevo sistema operativo que se había protegido espacio de memoria en la Macworld o algo, mostraron el código fuente de un programa:

while (true) 
    *(int *)i++ = 1; 

Y faltando el programa y sólo el programa terminado, y no toda la máquina (tenía un mensaje como "No necesitas reiniciar tu computadora"), toda la sala llena de desarrolladores estalló en aplausos. De todos modos, obviamente no tener memoria protegida realmente hizo que la programación en C o C++ fuera realmente difícil debido a la mayor gravedad del bloqueo.

Hoy en día no es tan importante a menos que esté programando algo que se ejecuta a nivel de supervisor, no tiene la capacidad de bloquear el sistema operativo.

+4

Escribí un programa similar al de mi C-64. Fue "serpiente". La serpiente atravesó debidamente la primera hilera, se envolvió en la segunda fila, etc., y de la parte inferior de la pantalla en el recuerdo que siguió, dibujó pequeñas serpientes y dejó espacios. Finalmente se comió su propio código. Choque. –

+0

Lol Hice algo increíblemente similar con mi c-64 –

+0

¡Esas historias son increíbles! Mi primer gran error confuso fue un desbordamiento de la pila causado al crear instancias de oyentes de mouse dentro de un ciclo while. Mientras bucles! – Ziggy

1

Había una computadora, el Commodore PET 4032 (también conocido como "Fat 40") donde era posible quemar permanentemente el chip de video si insertaba el valor incorrecto en la parte incorrecta de la memoria. Puedes imaginar que si hubiera habido un compilador de C en esa máquina, un puntero salvaje podría causar un daño físico irreparable a la computadora.

6

Aquí hay un fragmento rápida de Henry Spencer "Diez Mandamientos para los programadores de C":

  • Mandamiento # 2 - No seguirás el puntero NULL, para el caos y la locura te esperan en su extremo.
  • Claramente las escrituras sagradas fueron transcritas aquí, ya que las palabras deberían haber sido `` puntero nulo '', para minimizar la confusión entre el concepto de punteros nulos y el macro NULL (de los cuales más anon). De lo contrario, el significado es claro. Un puntero nulo apunta a regiones llenas de dragones, demonios, botavaras e innumerables otras criaturas asquerosas, todas las cuales se deleitan en participar en tu programa si perturbas su sueño. Un puntero nulo no apunta a un 0 de ningún tipo, a pesar de algún viejo código blasfemo que supone imprudentemente esto.

Para aquellos que no están familiarizados con C, creo que la mejor introducción concisa escrita a C se hace por "The Ten Commandments for C Programmers (Annotated Edition)" por Henry Spencer. La forma en que está escrito realmente le muestra al lector los peligros de C ... mientras que al mismo tiempo es gracioso (lo que significa que el lector realmente prestará más atención).

=========================

Personalmente ... C no se bloquea tan mal cuando usted está haciendo escritorio desarrollo porque tiene el lujo de seg-fallar. Seg-fallas son cuando el sistema operativo lo ve tratando de REALMENTE F 'cosas arriba y dice "¡hey! Usted no está permitido allí" y detiene el proceso.

Cuando estás haciendo un desarrollo de C incrustado ... es cuando obtienes las cosas realmente increíbles y escandalosas ... es decir, te REQUIEREN un ciclo de encendido el 99.9% del tiempo. Me gusta esta vez donde el código de alguna manera arruina mi pila de llamadas ... y luego estás ejecutando alguna otra función al azar ... y entonces el ISR de alguna manera todavía está funcionando ... y toma 2 semanas arreglar ese tipo de error.

0

Bueno, de vuelta en los días de DOS, logré sobre escribir parte del sector de arranque, nada como reiniciar para encontrar "OS no encontrado" o lo que sea que fue el mensaje.

Se aprende de la manera difícil que ser muy, muy cuidadoso de escritura en el disco después de eso ...

1

En los días de DOS realidad escribió sobre-información del BIOS. Tuve que conseguir un técnico para arreglarlo. Mi primera computadora en casa: 286. No se puede iniciar después de uno o dos días.

0

C le permite trabajar con la máquina bastante cerca de directamente. Cuán espectacularmente se puede bloquear es una función de lo que la máquina puede hacer.

Entonces: Un proceso de modo de usuario sin privilegios especiales en un buen sistema operativo moderno en realidad no hará mucho. Pero tienes software por todos lados. Piense en el software que controla los sistemas de frenado en un tren. Piense en el software que ejecuta el intercomunicador de emergencia cuando alguien realmente necesita ayuda. Piensa en el software que ejecuta las señales en una carretera transitada. Piensa en el software que ejecuta un sistema de misiles guiados.

Actualmente, hay software por todos lados. Mucho de esto está escrito en C.

0

Cuando estaba escribiendo los controladores Win98, el BSOD embrujaba a todos.Recuerdo el siguiente error que hizo

_SOME_TAG_ typedef struct {

int nSomeVar; 
    int nSomeMore; 
    ... 

} MYSTRUCT, * PMYSTRUCT;

.... PMYSTRUCT pMyStruct;

// Y utilizo esta estructura sin asignar memoria ;-) pMyStruct-> nSomeVar = 0;

Y las colisiones de los conductores eran tan horrible, pero tuvimos una SoftIce de Numega, aunque se hace sólo 10 años .. me siento como sus edades volver

1

en cualquier sistema operativo con memoria protegida lo peor que puede pasar es que tu proceso falla Ahora bien, si su proceso pasa a ser parte del kernel o una extensión del núcleo, obviamente puede bloquear todo el sistema operativo, pero eso es lo peor que puede hacer.

Sin embargo, realmente esto es lo mismo con muchos otros lenguajes (por ejemplo, en C deferencia, un puntero nulo, en java utiliza una referencia de objeto establecida en nulo, ambos bloquearán su proceso).

Por lo tanto, creo que con la memoria protegida, C no puede hacer más daño que cualquier otra lengua (a menos que su proceso es parte del sistema operativo;))

+0

Apostaría que lo peor que puede pasar es en realidad con los conductores;) – eglasius

2

antes de memoria protegida arquitecturas, la mayor parte del Los vectores de salto utilizados por el sistema operativo se almacenaron en la página cero de la memoria (direcciones que empiezan en cero)

por lo que escribir en las ubicaciones de memoria en la página cero - fácilmente con punteros nulos/incorrectos - cambiaría los vectores de salto del sistema operativo , causando todo tipo de comportamientos de colisión extraños, desde teclados bloqueados y pantallas de video parpadeantes llenas de basura, hasta el frenesí parpadeante de la unidad de disco duro, la pantalla azul de la muerte, el reinicio, etc.

[codificación en lenguaje ensamblador fue aún más divertido]

0

En la universidad yo tenía la tarea de crear un proxy multi-threading.

De vez en cuando, el proxy no respondía a ninguno de los recursos que extraía la página. El código que causa el problema:

Algunos códigos con problemas de desbordamiento, que utilizan variables cerca de un manejador de archivos. Antes de saber qué estaba pasando, me pareció realmente extraño que mover la declaración del manejador de archivos "solucionó" el problema, lol.

Ps. marque este (no en c, pero una buena historia :)): http://trixter.wordpress.com/2006/02/02/computing-myth-1-software-cannot-damage-hardware/

0

Si el software en cuestión se ejecuta en una PC, puede "simplemente" derribar su computadora.

Sin embargo, si se controla el funcionamiento del motor en su coche - o, peor aún, el ABS - no va a ser sólo el software que se estrella ...

0

Un accidente no es el peor de los casos cosa que puede suceder

Leí acerca de un viejo programa de compresión de archivos Unix (ya sabes, como Zip) que no verificaba el valor de retorno de fclose. Sí, fclose puede devolver un error. La salida a un archivo normalmente se almacena en el búfer, por lo que incluso si una llamada a fwrite o putc parece funcionar, y devuelve OK, los datos aún pueden estar en un búfer, esperando a ser escritos.Cuando se invoca fclose, se vacían los datos no escritos y esto puede fallar, ya que (por ejemplo) el disco puede estar lleno. Y dado que el programa de compresión usualmente se ejecutaba solo porque el disco estaba casi lleno, esto sucedió con bastante frecuencia. Así que el programa truncó silenciosamente el nuevo archivo comprimido, el archivo descomprimido original fue eliminado, y el año siguiente o más cuando alguien intentó descomprimir el archivo, ¡al final faltaba!

Creo que este es un buen ejemplo de por qué arrojar excepciones puede ser algo bueno.

Cuestiones relacionadas