EDICIóN GENERAL
141 meneos
1830 clics
[ENG] Microsoft está valorando usar Rust

[ENG] Microsoft está valorando usar Rust

Según un informe publicado por Microsoft , el 70% de los bugs corregidos en su productos se deben a problemas con el uso de la memoria. Rust está diseñado para tener un acceso seguro a la memoria por lo que su adopción supondría una mejora importante en la calidad del software de Microsoft,. Otras empresas, además de Mozilla, que han adoptado Rust recientemente son Cloudflare, Dropbox, y Brave browser.

| etiquetas: microsoft , mozilla , rust , seguridad , memory leak , memory safe
Comentarios destacados:                            
#5 #2 Una afirmación como esa sólo puede venir de alguien que jamás ha hecho un proyecto mínimamente complejo en C. O en cualquier otro lenguaje.

Y no, no soy fanboy de microsoft.
#6

Puedes dar muchísimas clases de C o C++, pero por el hecho de subestimar la complejidad de los proyectos en esos lenguajes, parece que sólo has hecho programas sencillos.
#14 Si ha sido unicamente profesor, seguramente lo más complejo que habrá programado serán los mini ejercicios esos de ver si una palabra es un palíndromo. :-D
#11 Pues buena suerte con esas contrataciones, habra que tener paciencia, porque, por lo menos en este mundo, todavia no ha nacido la persona que es capaz de crear codigo totalmente libre de errores.
#12 Esa persona no ha nacido. Pero a un equipo de personas que Implementan calidad y revisión de pares no se la cuelas.
#13 te falta meter tu mensaje entre tags <ironic>
#13 ¿Te crees que no se escapan errores? Siempre hay cosas que se rompen. Siempre, en Software y en cualquier cosa. O acaso, por ejemplo tu casa no tiene averías? Por poner un ejemplo físico de algo diferente. Pues, en el software ocurre exactamente lo mismo, hay averías, es decir, bugs o incluso errores de fábrica que muchas veces debido a la complejidad son inevitables.
#13 Si, si se la cuelas.
#6 Esto explica por qué dices cosas sin ningún sentido. Eres un teórico en lugar de alguien con experiencia práctica.
Si trabajases en cualquier proyecto real de una mínima complejidad sabrías que es inevitable que se produzcan errores. La cantidad de cosas que hay que tener en cuenta es tan grande que es normal que alguna se te escape.

Tú dices que invirtiendo lo suficiente consigues eliminar todos los errores y no es así, nunca se podrán eliminar todos porque siempre habrá casos que ni en…   » ver todo el comentario
#28 se de un tío que pidió tests funcionales para cada posible caso de uso y recibió una estimación de un par de cientos de años
#28 no se si es un ejemplo plausible( ni si quiera se si puedo usar aquí la palabra plausible pero el corrector de iPhone lo sugiere) pero yo hago juegos y muchas veces testeamos en un equipo de cuatro personas los procedimientos, luego con grupos de más de 20 amigos, pero al final acabas viendo en YouTube videos de gente que hace algo que a ninguno se os había ocurrido y peta x procedimiento y dices joder...
Que lo parcheas y solucionas esa situación pero es lo que dices, es imposible no cometer fallos
Madre mía, aquí es que todo el mundo programa en C/C++ nivel John Carmack y no tiene nunca memory leaks. Si Microsoft esta valorando Rust, es porque ya se ve en el ejemplo de Mozilla. Y si Firefox ha mejorado tanto en performance y errores es en parte gracias a Rust. Ya que los propios desarrolladores han comentado que las partes que han reescrito en Rust eliminaron memory leaks a punta pala.
#19 No, solo una persona. El resto le ha dicho que no se flipe.
#19 incluso los que programan nivel John Carmack (como por ejemplo, John Carmack mobile.twitter.com/ID_AA_Carmack/status/1094419108781789184) son capaces de apreciar Rust.

Simplemente el tipo del que hablas no ha tirado un proyecto que no sea una práctica de la universidad en su vida.
Rust es como C++ pero la sintaxis está diseñada para que sea fácil identificar errores.
Para mi es el lenguaje del futuro.
#9 No es la sintaxis lo que está diseñada para que sea fácil detectar errores. Es la semántica y el compilador.
#9 Pero su gestión de memoria, aunque algo engorrosa, es cojonuda. Tienen razón en m$. Rust tiene mucho futuro y, añado, golang también. Son el C/C++ del siglo XXI.
#11 la tipica frase cuñadil sobre desarrollo de software
#6 Eso no significa nada. Aun recuerdo alguna profesora de programación que tuve en la carrera :palm:

En un proyecto mínimamente grande donde mete mano mucha gente y con cierta antigüedad eso que dices no tiene sentido, simplemente son aplicaciones con una cantidad de código heredado que es imposible controlar las consecuencias de muchos cambios, si usas ahi la política de despidos que dices, no solo no mejorarás la calidad del software, si no que la gente bajo presión será mas propensa a…   » ver todo el comentario
#6 En C++ tienes smartpointers si no te quieres preocupar de la gestión de memoria. En C, que es de lo que hablábamos, no tienes nada parecido. Y aún así, si te empeñas, puedes conseguir que haya leaks.
#11 ¿De verdad crees que en Microsoft no hay buenos programadores y bien pagados?
«memory leak» -> fuga de memoria. Por favor.

Con C++ puedes utiliar auto y std::shared_ptr, disponible desde C++11. en.cppreference.com/w/cpp/memory/shared_ptr
#21 No he oído fuga de memoria en mi vida.
#25 Pues es un término bastante habitual.
#21 auto no tiene nada que ver con la gestion de memoría.
Mejor nombraría los smart pointer en general, el shared es un tipo de ellos si, como su nombre indica, lo quieres compartir.
#34, #21...es que no tienen nada que ver con Rust. Los smart pointers y eso le dan a C++ algo parecido a un garbage collector Como a golang o java. Pero aún así puedes tener memory leaks, por ejemplo, montando alguna referencia compleja que nunca se libere, o una mala gestión de memoria creando y destruyendo memoria que podrías reaprovechar.

Sin embargo, Rust tiene, a nivel de lenguaje, directivas para que el programador indique la inmutabilidad de una variable y la capacidad de mutar los parámetros recibidos. Eso le da al compilador una información preciosa para saber cómo debe gestionar esa memoria o detectar accesos prohibidos.
#52 #65
Con unique_ptr, const, move:
nercury.github.io/c++/intro/2017/01/22/cpp-for-rust-devs.html
Al fin y al cabo Rust lo que implementa son las semánticas de mover y el chequeo estático que lo asegure.

Con metaprogramación: medium.com/@bhuztez/emulate-borrow-checker-in-c-with-stateful-metaprog
Permite chequeo estático.

Es cuestión de tiempo que el estándar integre la funcionalidad. Como siempre, opcional.

Crítica a Rust: hackernoon.com/why-im-dropping-rust-fd1c32986c88
* Necesidad de usar C en algunos casos.
* Detalles de implementación de rasgos (traits) y conteo de referencias.
* Imposible de modificar el comportamiento del compilador.
#72

> Al fin y al cabo Rust lo que implementa son las semánticas de mover y el chequeo estático que lo asegure.

Ah bueno, si "solo" implementa eso...

> Therefore, a good practice in C++ is to avoid using move in the case like this, even if this means unnecessary deep copy of the value, to avoid the accidental usage of the moved value.

Nada más que decir.

> Con metaprogramación

En Rust es algo nativo.

> Es cuestión de tiempo que el estándar integre la funcionalidad.

Hablemos entonces.

> Como siempre, opcional.

O mejor no.

> Crítica a Rust:

www.reddit.com/r/rust/comments/5295nf/why_im_dropping_rust/
#95
Ah bueno, si "solo" implementa eso...
Pues sí, sólo implementa eso.

Nada más que decir.
Que Rust utiliza semánticas de movimiento siempre, y no es bueno usarlas siempre.

En Rust es algo nativo.
No, en Rust está «integrado» («nativo» es otra cosa). Y eso un coñazo porque no lo puedes desactivar.

Hablemos entonces.
Contigo no hay nada que hablar.

O mejor no.
No entiendes C++.

www.reddit.com/r/rust/comments/5295nf/why_im_dropping_rust/
#96

> Que Rust utiliza semánticas de movimiento siempre, y no es bueno usarlas siempre.

No. Lo que te está diciendo es que C++ es semejante mierda que la práctica recomendada es tremendamente ineficiente.

In C++, it is possible to accidentally use moved value. Therefore, the move operations usually set the original container size to zero.

> Y eso un coñazo porque no lo puedes desactivar.

O dicho de otro modo "déjame introducir bugs en producción que yo sé lo que hago".

> Contigo no hay nada que hablar.

Lo dice el del argumentazo de "no entiendes C++".
#97
No. Lo que te está diciendo es que C++ es semejante mierda que la práctica recomendada es tremendamente ineficiente.
No. Lo que dice es que las semánticas de movimiento no son siempre eficientes. No es que no entiendas C++, es que ni tan siquiera entiendes como funciona una arquitectura Von Neumann.

O dicho de otro modo "déjame introducir bugs en producción que yo sé lo que hago".
Eso lo dice alguien que utiliza un lenguaje con anotaciones para una de sus características fundamentales (ciclos de vida).

Lo dice el del argumentazo de "no entiendes C++".
Lo dice el que no tiene ningún argumento.
#98

> es que ni tan siquiera entiendes como funciona una arquitectura Von Neumann.

¿Puedes explicarte? No veo qué tiene que ver.
#98

> Eso lo dice alguien que utiliza un lenguaje con anotaciones para una de sus características fundamentales (ciclos de vida).

Un error con tus lifetimes solo puede generar más restricciones, no menos. Por su naturaleza no puedes introducir bugs. Como mucho harás que tu código no compile por haber hecho una restricción demasiado fuerte.
#100
En castellano, ciclos de vida.

Probablemente ya lo hayas leído, pero aquí te dejo otro enlace de bugs que puedes introducir con las características tan bondadosas de Rust: gankro.github.io/blah/only-in-rust/
TL;DR: don't infer lifetimes that unsafe pointers produce!

No son infalibles. ¿Esto también es un «déjame introducir bugs en producción que yo sé lo que hago» o es más bien un «es que no sabes Rust» o «no deberías escribir código potencialmente inseguro nunca»?

Balla, no me lo experava.
#21 no compares los smart pointers con el borrow checker porque no lo sustituyen.
#21 «memory leak» -> fuga de memoria. Por favor.

Pensaba que estaba solo en esta lucha por evitar la desaparición del castellano.
Estamos en 2019, la industria del software no puede seguir en esta situación ni seguir aguantado a zombies que siguen repitiendo que el problema es contratar a buenos programadores. Rust está siendo una revolución y con razón. C y C++ tendrán que evolucionar para eliminar los fallos de gestión de memoria de raíz o desaparecer a largo plazo.
#11 No es ese el problema, un lenguaje de programación en muchos aspectos no deja de ser unas directrices de diseño. Si controlar manualmente la memoria es un quebradero de cabeza, y es más que probable que una persona se equivoque, pues mejor usar directrices que no incluyan ese problema.
#11 Microsoft tiene algunos de los mejores ingenieros del mundo, a los que paga bien y tiene entre algodones. Me quieres decir que les faltas tú o qué?
Así que los inventores de C#, F#, Visual Basic, Visual Foxpro, typescript y mil lenguajes más se decantan por usar un lenguaje creado por la Mozilla fundation... Todo muy en la línea de Microsoft xD
#29 tranquilo, Rust# esta en camino
#29 me encantaría ver un windows escrito en typescript o vb...
#39 pues cojearía de todos lados, aunque siempre se ha dicho que con VB "nunca se hizo tanto con tan poco"
#56 yo añadiría: nunca se hizo tanto (daño) con tan poco.
#29 Microsoft ha cambiado mucho con respecto a aquella Microsoft de cuando IE6 y sucedáneos. Hasta el framework es open source.
#29 Lo mejor es que se han decantado por Chrome para hacer simbiosis con Edge. Dejando a Firefox de lado.
#29 Ya desecharon su propio motor de HTML para usar el de Chrome así que esto tampoco sería tan raro.
#48 Decir que la gente en Microsoft no sabe programar es de un cuñadismo máximo.

Ya les gustaría a muchos listos de aquí pasar una entrevista para entrar en Microsoft ganando 150k de entrada.
#57 Hasta el más listo y experimentado se equivoca, por eso siempre es recomendable hacer pruebas exhaustivas y siempre que sea posible hacer una revisión del software.

Y a poco que hayas trabajado en el mundo de desarrollo te habrás dado cuenta que revisar no es la opción más popular entre no pocos responsables de proyecto (como en todos los sitios, vamos). Lo que monda dinero y solo da calidad muchas veces se minusvalora.

Si has llegado a una conclusión distinta, creo que no has vivido una situación similar.
#66 Lo que me hace gracia es que la mitad de los que comentan aquí queriendo dar lecciones a Microsoft sobre como desarrollar software, probablemente trabajan en Indra o se ganan la vida desarrollando plugins de Wordpress...
#57 Pero donde ha dicho eso ? No creo que se refiera a Microsoft en el sentido de que ellos programen mal. Lo dice en general, supongo, si aprendes a programar con cuudado en C no necesitas Rust u otros, eso es asi. Ahora, Rust tiene constructos que ayudan EN AlGUNAS COSAS, ojo, que no es una panacea.
Rust no solo previene las fugas de memoria. A los listillos que se creen que todo se soluciona con un poco de cuidado os recomiendo informaros un poco de la clase de errores que evita Rust.

Os recuerdo que no todos los proyectos software son vuestras prácticas de la universidad de 2000 líneas monohilo. Que tengáis alumnos imbéciles no significa que en Microsoft cometan ese tipo de errores.

Y no, los smart pointers no suplen al borrow checker.

Y aún así Rust es mucho más que sus características de seguridad. Es un lenguaje muy cómodo de usar y su semántica es más parecida a Python que a C, pero con las características de rendimiento de un lenguaje de sistemas.
#74 De acuerdo en todo.

Sin embargo, una actitud de cuidado por los detalles de lo que se está haciendo es diferente a detalles que puede subsanar el lenguaje. Por ejemplo un lenguaje donde no se declaren las variables puede tener errores simples de tipeo que se evitarían en un lenguaje con declaración de variables. Esos son lenguajes peligrosos por mal diseño del propio lenguaje. Es estúpido hacer perder el valioso tiempo de un programador en revisar esos detalles cuando un lenguaje con…   » ver todo el comentario
# #11 sí, no hay más que ver que en Google no hay tienen bugs.
Pues van a flipar. Si son capaces de que no les maten en la zona de spawn que se preparen para los raid.
#41 programaran usando paneles solares y puertas AND
No soy experto pero llevo toda la vida oyendo sobre las fugas de memoria como un problema que había que minimizar. Lo extraño es que la propuesta de rust no haya aparecido antes
#38 Hace muchos años que había lenguajes con recolector de basura (Java, C# ...) lo que libera al programador de mucho trabajo relacionado con la gestión de memoria. Lo que no había era lenguajes diseñados para ser capaces de sustituir a C y C++
#78 Para eso, los programadores de golang tenemos una fantástica instrucción llamada defer. Toda liberación de recursos se incluye en el defer. El defer se ejecutará al salir de la función, por tanto podemos abusar del early return que todo queda limpito.

Ventajas de los lenguajes modernos.
#83 Programa un driver de NT en golang... no se como sera eso, pero go es un lenguaje que usa garbage collector y demas... no se, para muchas cosas si, y ningun problema en reconocerle esos meritos, pero no ya solo el lenguaje, sino el hecho de no tener 100% control de que se hace cuando, donde y como... un lenguaje que no tenga eso de una forma completamente explicita y clara... para programavion a bajo nivel, de SO, etc.... yo al memos no lo quiero.
#83 No he programado un driver de verdad en 20 años. No voy a empezar ahora. Para todo lo demás, golang
#83 en C# está el using que hace Dispose y tan feliz. No sé si es lo mismo pero en caso de ser así tampoco es reinventar la rueda :-S
Es tal la cantidad de comentarios cuñados de este hilo que se me hace imposible otorgar el premio al cuñado informático.
#85 Si, pero solo pilla cosas cuando se dan ( y si, hara que los que a veces se dan pero no petan, peten ). Pero si hay algo que no se reproduce cuando lo ejecutas con valgrind, pues no lo vas a pillar.
#86 por eso siempre hay que tener cobertura de código cercano al 100% y usar valgrind en tus test unitarios. Todo esto lo daba por sentado estando hablando de valgrind. Es un analizador dinámico.
#92 Bueno, esa es otra historia, y si, con maa covertura pruebas mas superficie, pero ya me se como va, coverturas del 80-85% y luego salen cosas en cliente.
Por si alguien tiene interés en aprender Rust: exercism.io/tracks/rust
Según mi punto de vista es que ya no hay desarrolladores de C. Los que hay ahora ni saben lo que es un analizador de código estático (cppcheck sin irte muy lejos) ni dinámico (valgrind, que tampoco hablamos de soluciones avanzadas). Se programa en C como se programa en JavaScript, y cuesta mucho enseñar a las nuevas generaciones el tema de lo que realmente se está haciendo con la memoria y el micro a bajo nivel.
#24 A ver. Es cierto que es difícil enseñar C a alguien acostumbrado a Javascript o a otros lenguajes modernos. Eso no quiere decir que para ciertas cosas Rust pueda ser mejor que C ni que en C sea extremadamente fácil pegarte un tiro en el pie.
The reason for this high percentage is because Windows and most other Microsoft products have been written mostly in C and C++, two "memory-unsafe" programming languages that allow developers fine-grained control of the memory addresses and where code can be executed.

¿Revisar un poco el código no podría ayudar también?
#1 En muchos casos tal vez sea mejor que los desarrolladores enfoquen su atención en cosas mucho más importantes que en detalles que no tienen que ver con el problema como por ejemplo revisar con lupa a ver si hay un desbordamiento de memoria. Un lenguaje donde sean imposibles sería más conveniente.
#4 #3 tal vez sea un idea loca, pero windows es un producto de software. A lo mejor hasta podemos "pedirle" un poco de calidad a su software.
#7 Es una idea loca, créeme.
El negocio del software no está en el desarrollo; sino en el mantenimiento. La pasta ha estado ahí de toda la vida.
#8. Como con los coches y la revisiones (y reparaciones) en los concesionarios oficiales. Al parecer el coche eléctrico necesita mucho menos mantenimiento lo que explica en parte que se haya tardado tanto en seguir los pasos de la marca Tesla.
(CC #7)
#8 en el desarrollo a medida, puede. En la venta de paquetes software, ni de coña
#3 No es tanto revisar despues, pero al programar cosas de sistema operativo, drivers, firmware y tal, se deberia programar con esa actitud de control por los detalles, "programacion lenta, concienzuda". Muchas mentalidades de ese tipo hacen, generalmente, que el codigo empeore. Llevo, entre una cosa y otra unos 15 años programando drivers y cosas del estilo y esa programacion lenta y de pensar y tener muy presente la memoria y el procesador y demas, esa actitud de control casi…   » ver todo el comentario
#1 Los errores de memoria son jodidos de localizar. Por ejemplo, si en una función tienes que liberar la memoria al salir, pero tienes muchos puntos de salida, es fácil que se te olvide liberarla en alguno de ellos. Y encontrar luego donde, es jodido.
#4 por eso para ese tipo de cosas se contrata a alguien que sepa y se le paga bien.
#4 Por eso una de las recomendacioones es no tener más de un punto de salida de una función, especialmente si vas a trabajar con memoria. Si la función es compleja quizás sea mejor hacer varias en vez de meterlo todo ahí. Sé que no siempre es tan sencillo como lo pintan, pero seguro que ayuda.

En cualquier caso las últimas versiones de C++ han añadido muchas ayudas al control de memoria para poder evitar y, si es necesario, localizar más fácilmente las fugas de memoria y las violaciones de acceso a memoria.
#30 #27 Err..no.
Por un lado tenemos la validacion de parametros recibidos, que cada comprobación puede ser un return en caso de error tras el seteo del error.
Por otro lado una funcion invoca a otras funciones cuyo valor devuelto puede ser un error y se debe terminar a la recepción del mismo la ejecución.
Una función con un "return" solo se ve en la Universidad. En la vida real no existen.
Antes de salir hay que liberar la memoria, o asegurarte de pasar aguas arriba el puntero a la…   » ver todo el comentario
#58 En la vida real existen, igual que también existen los casos en que varios return hacen el código más ágil y más eficiente. De todo hay en esta vida.

Y sí, los memory leaks no son lo peor que uno puede encontrarse, especialmente si se trabaja con codigo antiguo, pensado para plataformas concretas que en un hardware más moderno puede dar otros problemas de los que uno a veces no se da cuenta hasta bastante después de tener el código muy avanzado.

Y tal y como comentas, trabajar con cadenas…   » ver todo el comentario
#27 Los puntos de salida de una función no tienen nada que ver con la gestión de memoria. Es sólo un tema de legibilidad e incluso hay tendencias que están en contra, favoreciendo el early return.
#61 Early returns si, pero cuando no haya hasta ese punto mucho que liberar y que no haya que andar haciendo muchas IFs para saber que habia o que no habia hasta ese punto. Cuando hay diferentes niveles de recursos adquiridos, goto a etiqueta final y todas las salidas por un punto unico de liberacion de recursos.
#61 Efectivamente, a eso me refiero, a ficilitar el mantenimiento y la claridad del código. El early return es muy útil cuando está claro y justificado.
#27 Es tan sencillo como usar goto a una parte final comun que libere lo que haga falta.
#77 Te faltó el ironic al final de la frase
#4 Con alguna excepción, una función debería tener un único punto de salida.
#4 eso es así con C, con C++ y RAII eso no pasa. A parte hay herramientas como valgrind, que aunque no son la panacea, leaks de memoria como el que mencionas te los pilla.
#32 Ojo, valgrind pilla lo que se de en ejecucion, y muchos leaks, desbordes, etc. ocurren raras veces, vamos, que valgrind te pillara cosas que se reproduzcan facil, pero corner cases...
#79 valgrind pilla los punteros que ya no son accesibles, por eso he dicho que no es la panacea
#4 Y en esos casos es donde esta justificado y recomendado usar un goto a un punto final que libera lo que haga falta.
#1 O aprender a programar en C y C++ antes de ponerse a hacer aplicaciones complejas con esos lenguajes.
#1 "Cuñao seal of approval" {0x1f3c6}

Mención especial para #26 y el resto. Gracias por participar.
#31 lo del cuñao queda bien cuando no hay muchos argumentos para contradecir un argumento. ¿donde están los tuyos?

Lo mismo nunca has estado en un proyecto de construcción de software, pero, como ya ha comentado más gente, las prioridades no suelen ser contratar gente con mucha experiencia codificando, ni aplicar metodología de medición de calidad, ni mucho menos revisar lo construido.

Ahora, gente que habla de cosas que no entiende, aquí y en los proyectos hay muchos.
#31 ¿En serio me estás diciendo que es mejor ponerse a programar en C o C++ sin saber a la hora de acometer proyectos complejos?
Yo diría que el "cuñao" aquí eres tú.
#1 ya lo revisan, no creas que le vas a enseñar a Microsoft buenas prácticas.
#37 así a primera vista parece que es mejorable el proceso
#1 También pueden actualizar un poco el código. En C++ moderno (C++11 y posteriores) hay muchísimas formas de gestionar la memoria de forma segura y eficiente.

#37 Pues, a juzgar por la calidad de algunos de sus productos, yo diría que a lo mejor sí.
#1 Y los automóviles en lugar de equiparlos con airbags y cinturones de seguridad, podriamos conducirlos con mas cuidado
Me parece buena idea. O también podrían contratar programadores que sepan C antes de encargarles un proyecto, y despedir programadores cuando sean responsables de un bug que hayan tenido que parchear.
#2 Una afirmación como esa sólo puede venir de alguien que jamás ha hecho un proyecto mínimamente complejo en C. O en cualquier otro lenguaje.

Y no, no soy fanboy de microsoft.
#5 O de alguien que da clases de C++ y está cansado de ver ñapas en las entregas de prácticas.
#6 porque una práctica con 3000 líneas de código es lo mismo que un sistema operativo con 50 millones, no te fastidia...
#6 dar clases no acredita nada, siempre se ha dicho que los buenos programadores se dedican a programar y los mediocres a enseñar.

Ojo que no te estoy atacando, probablemente incluso lo de dar clases lo hagas después de salir de currar programando. Solo puntualizo que el hecho de dar clases no da más valor a tu comentario.
#6 Pobres alumnos. Un profesor con Dunning-Kruger. La eterna efermedad de nyestra univ.
#2 Venga, y despedimos profesores si tienen una falta de ortografía también
#2 Un error de memoria en yacc y estaba ahí desde hace 33 años. Hablamos de Unix y hablamos de yacc un programa hecho por programadores para programadores... y ahí estaba el error hasta que alguien lo vio:

marc.info/?l=openbsd-cvs&m=121553004431393&w=2
«12
comentarios cerrados

menéame