domingo, 25 de septiembre de 2011

Desing Patters

In actuality I'm reading a book about Desing Patterns, Elements of reusable Object-Oriented software by Erich Gamma.

The Desing Patters are important artifacts in the Architec Software because its can hel us to develop better systems, reuse code, major performance, etc.

But what is a Desing Pattern?
"Each pattern describes a problem which occurs over and over again in our enviroment, and then describes the core of the solution to that problem, in such a way that you can use this solution a millon times over, without ever doing it the same way twice" Christopher Alexander, In simple for are solutions for specific probles.

This books mentions 20 patterns.

  • Creational Patterns:
Factory Method
Abstract Factory
Builder
Prototype
Singleton
  • Structural Patterns:
Adapter (class)
Adapter (object)
Bridge
Composite
Decorator
Facade
Flyweight
Proxy
  • Behavioral Patterns:
Interpreter
Template Method
Chain of Responsability
Command
Iterator
Mediator
Memento
Observer
State
Strategy
Visitor

The experience, enviroment and problem tell us what is the best patter than we can to use.

The experience, enviroment and problem tell us what is the best patter than we can to use.

I will post here that Patters, explain, etc.

sábado, 16 de julio de 2011

Probando blogg

Probando blogg desd android

jueves, 11 de noviembre de 2010

Guerra de divisas

Guerra de divisas.
Euro vs Dólar vs Yuan => Peso
 
Explicaré con un ejemplo sencillo lo que es la llamada “Guerra de las divisas”,
tema muy sonado en estos días sobre la apreciación y depreciación del
peso frente al dolar, euro vs dólar, dólar vs yuan y todos contra todos.
 
Algunos recordaremos los 90s cuando el dólar costaba alrededor de los $6.00 a $8.00
Actualmente el precio del dólar ronda los $12.00, esto tiene sus pros como sus contras,
 
En México como principal motor de la economía es la exportación de petróleo de tal modo
Que cuando el dólar sube de precio un barril de petróleo vale más en pesos lo cual hace
que el gobierno tenga más liquides (dinero) lo cual le permite realizar obras públicas
Y algunos servidores públicos engorden la cartera, cuándo el  dólar vale menos pesos
se le llama apreciación del peso.
 
Cuando el dólar baja de precio, se tiene menor liquides en pesos lo que significa que
El gobierno tiene menos recursos económicos para realizar sus gastos que para nosotros
Son Servicios, educación, salud, vivienda, carreteras, etc.
 
Suponiendo que EU y un país de Europa fabrican el mismo producto y este es importado por México.
 
Si el Dólar  vale más que el  Euro, la tendencia sería adquirir el producto europeo,
por lo tanto EU perdería ingresos por exportación.
Si el Dólar vale menos que el Euro la tendencia sería adquirir el producto estadounidense,
por lo tanto el país europeo perdería ingresos.
 
Por lo que podemos ver todo esto afecta a todos, no es muy bueno que la moneda se deprecie o se aprecie con
Variaciones muy grandes.

lunes, 12 de abril de 2010

Entrevista a Joaquin Sabina

http://www.jornada.unam.mx/2010/04/09/index.php?section=espectaculos&article=a40n1esp

viernes, 2 de abril de 2010

Blogwriter

Probando blogwriter, xD

jueves, 1 de abril de 2010

Quién me ha robado el mes de abril?




En la posada del fracaso,
donde no hay consuelo ni ascensor,
el desamparo y la humedad
comparten colchón
y cuando, por la calle,
pasa la vida, como un huracán,
el hombre del traje gris
saca un sucio calendario del
bolsillo y grita
¿quién me ha robado el mes de abril?
¿Pero cómo pudo sucederme a mí?
¿Quién me ha robado el mes de abril?
Lo guardaba en el cajón
donde guardo el corazón.
La chica de BUP casi todas
las asignaturas suspendió
el curso en que preñada
aquel chaval la dejó y cuando en la pizarra
pasa lista en profe de latín
lágrimas de desamor
ruedan por la página de un bloc
y en él escribe
¿quién me ha robado el mes de abril?
¿Cómo pudo sucederme a mí?
¿Pero quién me ha robado el mes de abril?
Lo guardaba en el cajón
donde guardo el corazón.
El marido de mi madre
que en el último tren se largó
con una peluquera
veinte años menor
y cuando exiben esas risas
de Instamatic en París,
derrotada en el sillón,
se marchita viendo Falcon Crest
mi vieja y piensa
¿quién me ha robado el mes de abril?
¿Cómo pudo sucederme a mí?
¿Pero quién me ha robado el mes de abril?
Lo guardaba en el cajón
donde guardo el corazón.


Título: Quién me ha robado el mes de abril?
Año: 1988
Letra: Joaquín Sabina
Música: Joaquín Sabina
Disco: El Hombre del traje Gris (1988)

domingo, 22 de noviembre de 2009

Gira "Vinagre y rosas" J. Sabina

El viernes 20 de nov comenzó la nueva gira del maestro Sabina en Salamanca.
Dejo la crónica tomada de http://www.lavozdesalamanca.com/article6832.html


Con puntualidad artística comenzó Joaquín Sabina el primero de los conciertos de la gira de presentación de su nuevo disco “Vinagre y rosas”. Con un simple “Buenas noches Salamanca” y dos canciones del nuevo disco, Viudita de Clicquot y Parte meteorológico (…Do, re, mi, fa, sol…), segunda y cuarta pista, respectivamente. Ya había avisado Sabina, con sorna, que tocaría tragarse seis o siete canciones de las nuevas.

Después, ya si, presentación formal (Buenas noches Salamanca, buenas noches y gracias por estar ahí, gracias por el calor, muchas gracias por la paciencia, gracias por la complicidad. Es un lujo iniciar la gira aquí), dedicatoria a Benjamín Prado y poema homenaje para la ocasión, dedicado a Salamanca.
Uno escribe siempre la misma canción,
sobre un niño con cara de viejo,
que se atreve a volar bajo el cielo marrón,
que agoniza detrás del espejo.
Uno canta siempre la misma canción
otra noche en el bar de la esquina,
cerca de la estación donde duerme un vagón,
cuando el tiempo amenaza rutina.
Uno rumia siempre la misma canción
como un perro ladrando a la luna,
con la misma trompeta y el mismo trombón
de mariachi que estuvo en la tuna.
Uno acaba nunca la misma canción
que construye a trancas y barrancas,
luego llega la hora de alzarse el telón
y es un lujo que sea en Salamanca.

Medias negras, primera de las canciones antiguas y primera de las canciones coreadas, aún discretamente, seguida de Aves de paso, que sube la temperatura del Multiusos Sanchéz Paraiso. Sigue Que se llama soledad (…en el ojo de la luna…), coreada en pleno, ya no con la novedad de ser la primera, si no con el público dentro, sentido. Y enlaza directamente, sin pausa, con Puntos suspensivos (…la adrenalina en camas separadas … que embalsan los pájaros del sueño…). Media hora larga después del comienzo tiene lugar el primer de los momentos mágicos. El pabellón se luce cantando El boulevard de los sueños rotos.

Sabina presenta a los que le acompañan en el escenario, mientas Jaime Asúa (Guitarra) se marca un dueto con el jefe en Llueve sobre mojado. No es Fito Páez y se nota, la convivencia chirría como entonces, solo que en este caso de voces. Entre el resto, Pancho Varona se lleva la mayor ovación.

Abandona el escenario Sabina, y la orquesta se marca una versión rockera de Donde habita el olvido, muy buena. Un poco de modorra nos entró con una sosa primera canción por Mara Ramos, y qué alegría que la propia Mara lo compensase con una fantástica y coplera Y sin embargo te quiero (Maestro Quintero), con un retornado Sabina del que nos habíamos olvidado por un momento. Quizá para reafirmarse, sin descanso encauzada fabulosamente (¡cuanto oficio!) con De sobra sabes que eres la primera, cantada a gritos por un público que poco necesitaba para arrodillarse.

Consciente de que el público está entregado, el piano toma el protagonismo en Cristales de Bohemia (del nuevo disco) y el descenso desde el cénit al que habíamos llegado se hace más rápido de lo esperado. Momento de llamar con el móvil para comentar la jugada y admirar el escenario, que representa el tejado de una gran ciudad (¿Madrid?) plagado de un horizonte de áticos y tuberías. Algunas de estas últimas se hacen reales (obviemos esas horrorosas luces de bazar chino a su alrededor) y limitan el escenario en sus laterales. El escenario-tejado a dos niveles, con la orquesta tres escalones por encima, Sabina en el centro, marcando y compartiendo nivel preferente con Mara de rato en rato. Como ahora, que vestida de cabaretera, fumando y apoyada en una farola recién aparecida, entra en un juego con el jefe Sabina en Una canción para la magdalena. El público aplaude el estribillo (…cuando es amor sin cobrar…) y grita después (…la más puta de todas las señoras…), con un Sabina calladito que sabe que lo que gusta decir palabras gruesas.

Uno de los momentos más intimistas de la noche, cuando a la voz ronca solo la acompaña la guitarra de Pancho Varona (Sabina no se animó solo con su guitarra y voz en ningún momento del concierto) en Peces de ciudad (…mentiras que ganan juicios…) [favorita del que escribe] que sorprendentemente no es cantada por el público pero tras la que se vieron los primeros aplausos en pié en el anfiteatro bajo.

Luces fuera y monólogo de Sabina para introducir la más aplaudida de la noche: Nos sobran los motivos. El cantautor deja la guitarra, tímidos aplausos a Embustera (…embustera, tu corazón es una cremallera…) del nuevo disco. ¡Casi! Cuando suenan los punteos, en falso, de 19 días y 500 noches, y Sabina ríe la complicidad abroncando al guitarrista esquirol. En su lugar con Calle Melancolía vuelve a poner al público en éxtasis. Todos hemos salido ganando, grandes aplausos, y Sabina responde al publico con un ¡Olé! y ¡Olé!.

Ahora sí, con el público todo lo caliente que se puede estar, 19 días y 500 noches (…derrochando la bolsa y la vida…) respondida con un aplauso que apunta a final, que el propio Sabina ahoga con Princesa. Doblete y partido.

Con el público en pié, Sabina y compañía se esfuman. Los focos generales se encienden cuando el escenario-tejado se vacía. “Oes” del público seguidos de silbidos y aplausos. Todos sabemos lo que viene ahora.

Bis, primero sin Sabina con Amor se llama el juego, y luego al completo con Vinagre y rosas (…el circo ya se había ido de Albacete a Nueva York…), curiosamente relegada al primer postre pese a dar nombre al nuevo disco.

Las tuberías del escenario ponen rojas sus luces del chino para Noches de boda (…que todas las lunas sean lunas de miel…) y Nos dieron las 10. Todos en pie.

Solo los faltos de fondo físico permanecen sentados para pedir el segundo bis: Contigo (…yo no quiero saber por qué lo hiciste…) y La del pirata cojo (¡Como le oiga la SGAE!). Termina el concierto con Pastillas para no soñar, Sabina tocando un bombo como Manolo. Despedida y cierre de la cita inaugural, con repetición al día siguiente.



martes, 6 de octubre de 2009

Comparativo "session" JSP y JSF

I.- SETEAR EN SESION:

A.- JSP: request.getSession().setAttribute("miVariable",valor);

B.- JSF: FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("miVariable", valor);


II.- RECUPERAR LA SESION:

A.- JSP: request.getSession().getAttribute("miVariable");

B.- JSF: FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("miVariable");


III.- RECUPERANDO 'Context, Request, Response':

A.- JSP: En JSP es automatico al utilizar los Servlet.

B.- JSF: Se tiene que simular el manejo 'Context, Resquest, Response' tanto para el HttpServlet o el Servlet, segun se requiera.


- FacesContext context = FacesContext.getCurrentInstance();

- HttpServletRequest request = (HttpServletRequest)context.getCurrentInstance().getExternalContext().getRequest();

- HttpServletResponse response = (HttpServletResponse)context.getExternalContext().getResponse();

- ServletContext request2 = (ServletContext)context.getCurrentInstance().getExternalContext().getRequest();

- ServletContext sContext = (ServletContext)context.getExternalContext().getContext();

- ServletRequest sRequest = (ServletRequest)context.getExternalContext().getRequest();

- ServletResponse sResponse = (ServletResponse)context.getExternalContext().getResponse();

fuente: Blog Frameworks Java

LifeCycle Support

LifeCycle Support

A requirement for IoC is handling lifecycle support. In fact JSF's managed bean facility handles lifecycle support extremely well in that it is specifically geared toward defining lifecycle scope for HTTP requests as opposed to a more generic form which is common in other IoC containers. Similar to the scope parameters as specified by the JSP UseBean tag, the JSF scope sets the lifecycle with the following:

* none: A managed bean with this scope is not stored anywhere, it is created "on demand" whenever it is needed.
* request: A bean with a request scope will have it's value stored only for the duration of a single request. Upon subsequent requests on the same object, a new clean version will be instantiated.
* session: A bean with session scope will be stored onto the session meaning that the bean's properties will stay alive during multiple requests. A shopping cart bean would be set to a session scope. Objects stored onto the session are naturally threadsafe and will expire when the session times out if not cleared by the application explicitly. You wouldn't want anyone else looking in your shopping cart!
* application: Objects created with application scope will exist during the entire lifetime of the container. An example of when usage makes sense could be for a JDBC datasource object.

You may notice that the "page" scope is not available in JSF. This is by design as managed beans are not tied specifically to pages whereas in traditional JSP, you would define the scope of a bean using a UseBean tag, and in this sense it makes sense to offer a page scope since the bean originated from the page.

As you can define the lifecycle of the beans using the scope setting, you must take care to only refer to other beans which exist either the same scope or larger scope. You can not refer to another managed bean with a smaller scope.
Managed beans registered with scope: Can only refer to other managed beans with these scopes:
none none
request none, request, session, application
session none, session, application
application none, application

lunes, 31 de agosto de 2009

Business Team Game 2009

Business Team Game 2009, juego de negocios.




Reproduce mejor la realidad ya que, en cada fase, los participantes de cada equipo (empresa) deben tomar más de 500 decisiones entre más de 1000 opciones para cada plan de gestión, cuando otros modelos constan únicamente de 80 decisiones.

Este esfuerzo enriquecedor del simulador se basa en el hecho de que la realidad es altamente compleja y por ello los equipos habrán de valorar el mayor número de aspectos y decisiones posibles. El resultado que obtienen las empresas participantes depende básicamente de la política y las decisiones propias y de las que tome la competencia (equipos rivales).

Inscripciones.
1 de septiembre, ultimo día de inscripciones

lunes, 24 de agosto de 2009

Hacia donde va México???

El día jueves 20 de agosto en la "Casa Telmex" sede centro con motivo de su primer aniversario se llevó a cabo una mesa redonda de la tecnología para el desarrollo educativo. Se contó con la presencia del Centro Cultural Digital (CCD) quién lleva programas de Mochila Digital, Aula Telmex, Casas Telmex Beca digital; La Academia Mexicana de Ciencias; Servicios a la Juventud y la comunidad de Linux del CCH Naucalpan.

Todas estas entidades expusieron sus programas educativos, cuánto han crecido, ubicaciones, número de personas que atienden, etc, lo cual muestra emotivas cifras y saber todo lo que se hace por el desarrollo en la educación, sin embargo, esto no es suficiente como se ve en las evaluaciones de las distintas organizaciones mundiales a las que pertenece México.

Por otro lado la Secretaria de Educación Pública, entidad encargada de la educación básica en el país "mutilo" libros de texto gratuito, en especial temas de matemáticas y de historia de México (aprende del pasado para no cometer los mismos errores).

Por otro lado, sólo el 30% de los profesores aprobaron el examen para ocupar una plaza plaza de educación.

Para terminar de joder la educación se recortó el presupuesto, a la UNAM el 1%. ¿Hacia donde se dirige México con estas políticas?...

miércoles, 19 de agosto de 2009

Diferencias entre dos archivos

Tip:
view differences between two files or more, with linux's console:

1.- $diff file_1 file_2

2.- $vimdiff file_1 file_2 [file_n]

miércoles, 29 de julio de 2009

Edad con postgreSQL

Tip para obtener la edad en postgres:

SELECT age(timestamp '2009-07-29', timestamp '1986-10-13');

resultado: 22 years 9 mons 16 days

miércoles, 10 de junio de 2009

CONCEDEN A LA UNAM EL PREMIO PRÍNCIPE DE ASTURIAS

CONCEDEN A LA UNAM EL PREMIO PRÍNCIPE DE ASTURIAS













* La Universidad Nacional recibió la distinción en el área de Comunicación y Humanidades
* La entrega oficial del galardón será a finales de octubre en el teatro ovetense Campoamor

La Universidad Nacional Autónoma de México fue distinguida con el Premio Príncipe de Asturias en el área de Comunicación y Humanidades.

Reunidos para analizar los méritos de los contendientes hoy en el Hotel de la Reconquista de Oviedo, los miembros del jurado español fallaron en favor de la Universidad Nacional.

El presidente del jurado, Ricardo Senabre Sempere, leyó el acta respectiva en la que se establece que la UNAM a lo largo de 100 años ha sido el modelo académico de muchas generaciones de estudiantes de diversos países y ha nutrido el ámbito Iberoamericano de valiosos intelectuales y científicos.

La Universidad Nacional, añadió, acogió con generosidad a ilustres personalidades del exilio español de la posguerra y ha impulsado poderosas corrientes de pensamiento humanístico, liberal y democrático en América. Ha extendido su decisivo influjo creando una extraordinaria variedad de instituciones que amplían el mundo académico y lo entroncan en la sociedad a la que sirven.

La UNAM, que está a punto de cumplir 458 años, fue declarada en 2007, Patrimonio Cultural de la Humanidad.

Aún quedan por designar cuatro ganadores de la edición 2009 del Príncipe de Asturias en las áreas: La Concordia (10 de septiembre), de los Deportes (2 de septiembre), de Investigación Científica y Técnica (17 de junio) y de Las Letras (24 de junio).

Será a finales de octubre cuando en el Teatro Campoamor de Oviedo, la UNAM reciba la distinción de manos del heredero a la corona española, Felipe de Borbón, que consta de un diploma, una escultura de Joan Miró y 50 mil euros.

Entre los mexicanos galardonados con este premio egresados de la UNAM, figuran Marcos Moshinsky, Emilio Rosenblueth, Francisco Bolívar Zapata, Ricardo Miledi y Carlos Fuentes.

Desde que la Universidad fue propuesta como candidata el 19 de febrero en la sede mexicana de la Embajada Española ganó adeptos, como lo demostró un comunicado enviado a la Fundación Príncipe de Asturias por la International Association of University Presidents (IAUP), representativa de más de 600 instituciones educativas de África, Europa, Latinoamérica, América del Norte y diversos países de Asia, Arabia y el Pacífico.

Fuente:
http://www.dgcs.unam.mx/boletin/bdboletin/2009_348.html

martes, 2 de junio de 2009

Sonido con Amarok 2 y Ubuntu 9.04

Despues de un mes y con nada de tiempo me había conformado con escuchar música en totem donde no es tan fácil escoger lo que se desea escuchar, hace un instante dije un intento de unos minutos buscaré información y wuala!!!!
Encontré una solución :D

$ sudo aptitude install phonon-backend-xine
$ sudo aptitude purge phonon-backend-gstreamer


http://chanweiyee.blogspot.com/2009/04/ubuntu-904-amarok-2-sound-problem.html

martes, 12 de mayo de 2009

Porcinada J. Sabina




México en cuarentena y mascarilla
por culpa de una gripe mal curada
que amenaza mutar asilvestrada
como una fiebre alta y amarilla.


Del federal distrito, cual ladilla,
viaja el virus a Londres y a Granada,
a Hong Kong, a Chicago, todo es nada
cuando el sueño amanece pesadilla.


Por más que hayan saltado las alarmas,
los médicos no saben con qué armas
contener esta bíblica amargura.


La culpa no es del pobre animalito
que produce un jamón tan exquisito
sino del hombre, que no tiene cura.


Poema: Porcinada
Año: 2009, Interviú
Letra: Joaquín Sabina

martes, 21 de abril de 2009

Ubuntu, el Linux que llegó de África

http://www.elpais.com/articulo/internet/Ubuntu/Linux/llego/Africa/elpeputec/20070208elpepunet_3/Tes

a unos días de que se lance la versión 9.04 de Ubuntu. Hace cinco años salió a la luz la primera primera versión de Ubuntu en el periódico El País se publico una nota el 08/02/2007

La distribución de software libre más popular del momento es impulsada por Canonical, la empresa creada por un empresario surafricano

Has decidido pasarte al software libre y el primer cambio respecto a Windows es que en Linux las opciones se multiplican. Según el sitio DistroWatch existen más de 300 distribuciones diferentes del sistema operativo, pero la más popular es Ubuntu. Creada desde Sudáfrica por Canonical, la compañía del emprendedor y segundo turista espacial de la historia, Mark Shuttleworth, esta versión del sistema operativo Lunux destaca por su facilidad de uso e instalación, su aspecto gráfico y el soporte técnico disponible.

"Ubuntu, Linux para seres humanos", reza la página de esta distribución, alundiendo a la facilidad de uso. Hace ya tiempo que software libre no tiene por qué ser una opción sólo para expertos en informática dispuestos a comunicarse con su ordenador utilizando comandos de texto. La distribución de Linux realizada por Canonical no es la primera ni será la última que le pone las cosas fáciles al neófito, pero si pare ser la de más éxito en estos momentos.

Puede probarse incluso sin necesidad de instalar el software en el ordenador, utilizando un Live CD. Cuando se descarga Ubuntu (aprende cómo) uno puede grabar el software en un CD, introducirlo en el ordenador y arrancar éste desde el disco, de forma que lo que se cargará será Ubuntu y no el sistema que tengamos instalado. Es una buena forma de tener un primer contacto con Linux, y si te gusta, no tienes más que ponerte a instalar desde el mismo disco.

Tiene versiones para servidor y escritorio que pueden descargarse en varios idiomas, se actualiza casi dos veces por año, y en él trabaja, además de los empleados de la empresa de Mark Shuttleworth, una amplia comunidad de desarrolladores. Es la distribución elegida por ejemplo por la junta de Andalucía para desarrollar, en base a ella, su propio desarrollo, Guadalinex.

Hijos de Debian

Ubuntu no ha surgido de la nada, y como siempre pasa en el mundo del código abierto, es algo que se ha construido sobre el trabajo realizado antes por otros. El software libre tiene una gran capacidad de evolución, pues el código que hay tras los programas y sistemas operativos es publicado y cualquiera puede partir de él para crear una herramienta mejor, o para tomar idea la original y distribuirla empaquetada con software adicional.

Las distribuciones de Linux parten del sistema operativo GNU/Linux, al que se pueden añadir un entorno gráfico o gestor de ventanas para facilitar el manejo (KDE y GNOME son los más populares) y empaquetarlo todo con los programas más comunes en el usuario al que esté dirigido el producto. Uno de los sistemas GNU más populares es Debian, de que parten distribuciones populares como SUSE Linux, de Novell, Linex, realizado por la Junta de Extremadura, Linspire, o la propia Ubuntu.

Oracle adquiere Sun Microsystems por 5.710 millones

Hoy colocaré unos artículos de periódico interesantes...

En las últimas semanas se había barajado la posibilidad de que la compradora fuera IBM, pero las negociaciones han fracasado.- Oracle paga un 42% más por acción sobre el precio al que cerraron los títulos de Sun el viernes pasado.

El grupo estadounidense de software Oracle ha alcanzado un acuerdo para comprar Sun Microsystems por un montante estimado de 5.600 millones de dólares (4.320 millones de euros) en efectivo, que alcaza los 7.400 millones de dólares (5.710 millones de euros) al sumarle la deuda de Sun, según han anunciado este lunes ambas empresas. El precio por acción ha sido de 9,50 dólares, un 42% más que el cierre de la cotización de Sun el 17 de abril.

El consejero delegado de Oracle, Larry Ellison, ha mostrado su satisfacción con el acuerdo alcanzado y ha afirmado que "la compra de Sun transforma la industria de tecnologías de la información", mientras que el presidente de Sun, Scott McNealy, ha calificado la fusión como la "evolución natural de la relación entre las dos empresas" y ha afirmado que el evento supone un "hito" en la historia del sector.

De este modo, Oracle se hace con Sun Microsystems, una compañía sobre la que en las últimas semanas habían abundado los rumores, que, principalmente, señalaban el interés de IBM (gran rival de Oracle en el sector del software) en adquirir la empresa, cuya oferta pasó de 9,55 dólares iniciales a 9,40 dólares, aunque finalmente desistió de su interés el pasado 6 de abril.

Históricamente, el negocio de bases de datos de Oracle se ha realizado en conjunción con el de los servidores de Sun. En los últimos años, sin embargo, Oracle había optado por acercarse a dos de los grandes rivales de la ahora adquirida, HP y Dell. Oracle sigue así el modelo de negocio de IBM, que fabrica sus propias máquinas para vender sus programas informáticos.

La compra proporcionará a Oracle la tecnología Java de Sun y el sistema operativo Solaris. Además, Oracle se hace con el control de la base de datos de código abierto MySQL, que fue adquirida por Sun el pasado año por más de 700 millones de euros y que ha sido muy utilizada por múltiples compañías en Internet.

http://www.elpais.com/articulo/internet/Oracle/adquiere/Sun/Microsystems/5710/millones/elpeputec/20090420elpepunet_3/Tes

lunes, 13 de abril de 2009

Conociendo GDB GNU Debugger

Autor: Leandro H. Fernández
http://www.drk.com.ar/docs/development/conociendo_gdb.php

Objetivo

Introducir al lector en el uso de GDB como herramienta para inspeccionar la ejecución de un programa.

Introducción

A medida que la complejidad de un programa crece se hace más difícil predecir todos los posibles escenarios para una línea de código determinada. Los valores de cada variable en tiempo de ejecución pueden hacer que una porción del programa, que parece estar bien programada, produzca la finalización del proceso por "violación de segmento". Basta con utilizar un entero con un valor mal calculado como índice de un array o como puntero a un objeto (si trabajamos con C++) para que la violación se produzca. O lo que es peor: que no se produzca pero que la aplicación continúe corriendo con valores que definitivamente impactarán en el resultado erróneo de una operación posterior.
Como programadores estamos limitados en nuestra capacidad de reconstruir cada una de las posibles situaciones en nuestra mente. Es por ello que necesitamos una herramienta que nos ayude a ver qué ocurre durante la ejecución. Son herramientas que existen y se llaman debuggers en inglés algo así como eliminadores de insectos, ya que se utiliza la palabra bug para denominar a los insectos y también a los errores que se encuentran en un programa. Herramientas que debemos aprender a utilizar para facilitar nuestro trabajo.

¿Por qué GDB?

Porque es software de código abierto —es decir que podemos ver cómo está programado—, porque es gratis, porque nos permite realizar una serie de inspecciones y modificaciones en tiempo de ejecución que superan la capacidad de herramientas similares y porque es ampliamente utilizado —hecho que asegura su actualización constante—.
Otra ventaja que tiene GDB es que está disponible para tres plataformas ampliamente utilizadas actualmente: Linux, donde nació; MacOS X, soportado en forma nativa ya que está basado en Unix; y Windows, donde lo podemos utilizar a través de cygwin.

Funcionamiento

Para que GDB nos permita inspeccionar la ejecución de un programa, detenerlo en una línea arbitraria, que nos indique el momento en que se modifica una zona de la memoria del proceso, etcétera es necesario que se incluya, al momento de la compilación, información extra en el archivo ejecutable generado. Es decir que el compilador debe indicar cada porción del código binario que corresponde a cada línea de texto del código fuente. Así a GDB le es posible relacionar el lenguaje de máquina con el de nivel superior en el que realmente fue programado.
Es indispensable que al compilar utilicemos una herramienta que sea capaz de crear un binario con información de debug con una nomenclatura compatible con GDB. Para esto vamos a utilizar GCC y G++ en el ámbito de este artículo.

Entrando al mundo GDB

Para comenzar a empaparnos en este tema utilizaremos una estrategia altamente práctica. Por lo tanto recomiendo al lector que a partir de ahora realice en una máquina cada paso descripto en el texto para ver por sí mismo los resultados e incorporar los conocimientos más rápidamente.
En mi caso particular estaré utilizando un equipo de 32 bits con Debian (Linux), GCC 4.1.2 20061115 y GDB 6.4.90-debian. Pero deberían obtenerse los mismos resultados en Windows con cygwin.

1. Crear un directorio de trabajo y volcar en él los fuentes de éste artículo.
2. Compilar el ejemplo llamado gdbt.c ejecutando $ gcc -ggdb -O0 -o gdbt gdbt.c
Tener en cuenta que estamos indicándole a GCC que incluya información de debug para gdb [-ggdb] y que no realice optimizaciones en el código generado [-O0]
3. Ejecutar GDB indicándole que inspeccionaremos el binario generado (gdbt) $ gdb gdbt
4. GDB se ejecutará y cargará el binario en memoria lista para inspeccionar. Luego nos presentará una línea de comandos propia donde podremos, por ejemplo, indicarle que ejecute el programa simplemente. Esto lo haremos con el comando run
5. (gdb) run
6. El programa se ejecutará sin detenerse hasta el final, a menos que una violación de segmento interrumpa la ejecución. Esto no ocurrirá en este ejemplo.
7. En pantalla veremos algo como esto:

(gdb) run
Starting program: /home/leandro/gdbt
Paso 1
[12345]
Paso 2


8. Donde podemos ver la salida del programa en las líneas posteriores a la que indica que se inicia el mismo. Este comando sólo no nos es de mucha utilidad a menos que esperemos que la aplicación se detenga por sí misma. Es decir que el procedimiento mostrado hasta aquí es habitual si el programa que estamos inspeccionado estaba arrojando una advertencia de violación de segmento por parte del sistema operativo.


Supongamos que, viendo el código fuente de este ejemplo, decidimos detener la ejecución del programa en la línea 10 y continuar paso por paso hasta el final. Debemos indicarle a GDB, previo al inicio del programa, que se detenga en esa línea. Para eso utilizamos el comando br (break point, que significa punto de interrupción) y cuya función es establecer un punto en el cual se detendrá la ejecución de la aplicación cuando la inspeccionemos.

1. Ejecutar GDB como lo hicimos en el paso tres inicial. Así obtendremos la línea de comandos de GDB y tendremos el ejecutable listo para inspeciconar.
2. Establecemos un break point en la línea diez de gdbt.c (gdb) br gdbt.c:10
3. Observemos que la forma en la que indicamos el punto de interrupcion es :. Hay otras formas de indicar un punto de pausa que veremos más adelante.
4. En la pantalla vemos:
(gdb) br gdbt.c:10
Breakpoint 1 at 0x80483e1: file gdbt.c, line 10.

5. Cada break point está numerado consecutivamente desde el número uno. El número obtenido nos servirá para deshabilitarlo de ser necesario. También servirá para que GDB nos diga el motivo por el cual la ejecución se detiene. El número hexadecimal nos indica la posición de memoria a la que se asoció la línea de código en cuestión.
6. Iniciamos el programa con run
7. Automáticamente GDB se detiene al llegar a la línea diez:
Starting program: /home/leandro/gdbt
Paso 1

Breakpoint 1, main () at gdbt.c:10
10 unNivel(5, "1234567890");

8. GDB nos avisa que debido al break point uno, se detuvo en la línea diez de gdbt.c y nos muestra dicha línea de código. Ésta no fue ejecutada aún, por lo que sólo vemos la línea de texto Paso 1 en pantalla.
9. Ahora le diremos a GDB que ejecute esta línea de código exclusivamente. Es decir que deberá ejecutarla y detenerse de inmediato. Para esto usamos el comando n (next, siguiente):
10. (gdb) n
11. Vemos que GDB ejecuta la línea y se detiene nuevamente. La línea once se saltea porque no tiene código ejecutable:
[12345]
12 printf("Paso 2\n");

12. Si queremos volver a ejecutar el comando n podemos escribir n y presionar Enter o bien presionar Enter sin escribir nada. Esto repite el último comando ingresado por el usuario.
13. Vemos que nuevas líneas de código fuente en blanco son salteadas:
Paso 2
14 return 0;

14. Estamos en la última línea del programa, a punto de retornar cero como código de salida al sistema operativo. Aunque casi no tiene sentido, ahora le diremos a GDB que continúe la ejecución de la aplicación sin detenerse excepto que encuentre un punto de interrupción u otra situación que lo amerite. Utilizamos ahora el comando cont (continue, continuar)
15. El programa termina:
(gdb) cont
Continuing.

Program exited normally.

16. Si queremos salir de GDB debemos ingresar el comando quit (salir).
17. Veamos que ocurriría si en lugar de ejecutar la línea 10 deseáramos entrar en la función unNivel() y ejecutarla paso a paso. Como experimentamos en el punto diez, si utilizamos el comando n pasaremos a la línea 12 directamente.
18. Ejecutemos todos los pasos del uno al nueve pero utilicemos esta vez el comando s (step, paso) que a diferencia de n ingresará a cada función si el código fuente está disponible.
19. Ahora la línea siguiente a la 10 es la 21, dentro de la función unNivel():
(gdb) s
unNivel (c=5, str=0x804857f "1234567890") at gdbt.c:21
21 if (c >= strlen(str))

20. Si ahora avanzamos nuevamente con n:
(gdb) n
24 duplicado = strdup(str);
(gdb) n
25 duplicado[c] = 0;
(gdb) n
26 printf("[%s]\n", duplicado);
(gdb) n
[12345]
27 }
(gdb) n
main () at gdbt.c:12
12 printf("Paso 2\n");

21. Notamos que la última línea que ejecutamos dentro de la función unNivel() es la salida representada por la llave en la línea 27. Luego sí pasamos a la línea 12. Hemos regresado a la función main()
22. Así, alternando entre next y step podemos recorrer la aplicación con el nivel de profundidad deseado. Más adelante veremos otros comandos que nos permiten manejar la pila de llamadas a función.


Inspeccionando el mundo que nos rodea

Aprendimos a inspeccionar un programa, hacer que la ejecución se detenga en un punto arbitrario y luego ejecutar paso a paso. Pero hay algo fundamental que necesitamos hacer cuando detenemos la ejecución de un programa: ver el estado. Conocer los valores de las variables que intervienen y cómo estos se alteran con el avance del programa. Es la forma en la que típicamente descubrimos un error. Cuando una variable adquiere un valor que no tiene sentido para el programa.
Vamos a adquirir los conocimientos necesarios para descubrir los valores de nuestras variables e incluso modificarlos.

1. Compilamos el ejemplo variables.c con la línea de comandos gcc -ggdb -O0 -o vars variables.c
2. Lo ejecutamos con GDB y antes de iniciarlo establecemos un break point en la línea 24
3. La ejecución se detiene:
(gdb) run
Starting program: /home/leandro/gdb_article/vars
Inicio
Entero = 4433
Caracter = G

Breakpoint 1, main () at variables.c:24
24 printf("Texto = %s\n", texto);
(gdb)

4. Para inspeccionar las variables GDB cuenta con el comando p (print, imprimir) al cual le puedo pasar el nombre de una variable:
(gdb) p entero
$1 = 4433

5. Como podremos comprobar GDB nos indica que el valor de la variable llamada entero es 4433. Podemos inspeccionar el resto de las variables:
(gdb) p caracter
$2 = 71 'G'
(gdb) p str
$3 = 0x0
(gdb) p texto
$4 = 0x8048548 "Un texto."

Vale notar que en el caso de un puntero se adjunta la dirección de memoria en la salida. Y en particular 0x0 indica que el puntero es nulo.

6. GDB representará cada variable adecuadamente según el tipo. Incluso podemos preguntarle el tipo de la variable con el comando ptype (print type, imprimir tipo):
(gdb) ptype caracter
type = char
(gdb) ptype texto
type = char *
(gdb) ptype entero
type = int

7. Volviendo a las bondades del comando p es importante recordar que admite expresiones y no sólo nombres de variable. Es decir que puedo pedirle que imprima el resultado de una expresión. Probemos con un cast.
(gdb) p (int)caracter
$5 = 71
(gdb) p (char)entero
$6 = 81 'Q'

Como se observa al convertir el entero en un carácter se tomó el último byte. El valor 4433 es 0x1151 en hexadecimal y 0x51 es 81.

8. También podemos pedir la dirección de memoria de cualquier expresión:
(gdb) p &entero
$10 = (int *) 0xbfbce9a4
(gdb) p &caracter
$11 = 0xbfbce9b3 "GÐ鼿\030꼿¨îã·"

9. Las direcciones de memoria de estas variables corresponde a la pila. No confundir esta dirección con aquella a la que apunta un puntero. Éste tiene dos direcciones de memoria (por así decirlo): una es la del puntero, donde almacena su valor; y la otra es a la que él apunta, ya que el valor del puntero debe ser una dirección de memoria. Veamos la dirección de memoria donde se almacena el puntero texto:
(gdb) p &texto
$13 = (char **) 0xbfbce9ac

10. Ahora veamos la dirección a la que apunta (su propio valor):
(gdb) p texto
$14 = 0x8048548 "Un texto."

11. Vamos lo mismo para str:
$15 = (char **) 0xbfbce9a8
(gdb) p str
$16 = 0x0

12. Adicionalmente inspeccionemos la estructura llamada registro del tipo rec:
(gdb) p registro
$2 = {nombre = ".ïè·\031ëò·ô\217õ·x\025û¿ \203\004\bô\217õ·t\226\004\b\210\025",
edad = 20, sexo = 77 'M'}

13. Vemos que GDB encerró los tres valores del registro entre llaves e indicó cada valor con el nombre del miembro (nombre, edad, sexo). También podemos ver un miembro en particular utilizando el operador punto:
(gdb) p registro.edad
$3 = 20

14. Si tuviésemos un puntero a una estructura deberíamos utilizar el operador "->":
(gdb) p (®istro)->edad
$4 = 20

15. En este caso obtuve primero el puntero con el operador & (ampersand) porque no tengo un puntero a la estructura, pero la funcionalidad es idéntica si lo tengo. Claro que ya no utilizaría el ampersand.
16. Por último vamos a conocer una característica sumamente útil del comando p. La capacidad de modificar la memoria en medio del proceso. Sabemos, si le damos una mirada al código del ejemplo, que si lo dejamos correr ahora mismo con el comando cont veremos en pantalla:
Texto = Un texto.
STR = (null)
FIN

Program exited normally.

17. Pero podemos hacer que la salida cambie si, por ejemplo, hacemos que str apunta a la dirección de memoria de texto. Entonces se repetiría su impresión en la salida. Para esto escribimos:
(gdb) p str=texto
$17 = 0x8048548 "Un texto."

18. GDB ejecuta la expresión que es una asignación y la cual a su vez retorna el valor asignado. Es por esto que lo vemos impreso en la salida $17. Ahora dejamos correr el ejemplo con la variable str modificada:
(gdb) cont
Continuing.
Texto = Un texto.
STR = Un texto.
FIN

Program exited normally.

19. Ahora str apunta al mismo espacio de memoria que texto y por lo tanto la función printf() repite la salida en la línea STR...
20. Esta última característica del comando p nos habilita a realizar pruebas de ejecución con valores de variables distintos a los que el programa llegó. Muchas veces nos deja ver que la finalización del programa es correcta con el cambio. Y entonces sólo resta corregir el código que dio lugar al valor original, incorrecto.



La pila de llamadas o backtrace

Es un hecho que al momento de recurrir a GDB para solucionar un problema tendremos un código mucho más complejo. La cantidad de variables y funciones se habrá multiplicado. La línea de código donde nuestra aplicación arroje una violación de segmento estará en lo más profundo del código. En el sentido de que la llamada consecutiva de una función a otra y ésta a otra más nos dejará debajo de una "pila de funciones". O mejor dicho, de llamadas a funciones.
No es mi intención explicar qué es la pila de llamadas. Simplemente resumiremos que con cada llamada a una función se guarda el estado en la pila, se pasan también los argumentos, se ejecuta la función y cuando esta termina se retoma la ejecución de la función anterior.
Para ver cómo GDB representa esto compilaremos el ejemplo onion.c y lo ejecutaremos sin puntos de interrupción porque sabemos que provoca una violación de segmento.

1. Ejecutamos el programa con GDB y se detiene de la siguiente manera:
(gdb) run
Starting program: /home/leandro/gdb_article/onion
Failed to read a valid object file image from memory.
Inicio

Program received signal SIGSEGV, Segmentation fault.
0x080484a7 in nivel_4 (c=0xbf80c5d8, str=0xbf80c5df "1234") at onion.c:49
49 str[65535] = 123;

2. Nos indica que se produjo la violacion en la línea 49 de inion.c, tal como esperábamos. Nos muestra la línea de código en cuestión, pero más importante para este apartado es que nos dice en qué función estamos y cuales son sus parámetros. Se trata de la línea que dice "0x080484a7 in nivel_4 (c=0xbf80c5d8, str=0xbf80c5df "1234")"
La función nivel_4() recibe dos argumentos, un puntero a entero y un puntero a carácter. GDB nos muestra ambos valores, direcciones de memoria, y en el caso del puntero a carácter intenta mostrar la cadena de texto a la que apunta.
3. Si nos referimos al código fuente vemos que para haber llegado a nivel_4() debimos traspasar las llamadas a las funciones homólogas anteriores. Para pedirle a GDB esta información usamos el comando bt (backtrace):
(gdb) bt
#0 0x080484af in nivel_4 (c=0xbfe76448, str=0xbfe7644f "1234") at onion.c:51
#1 0x08048484 in nivel_3 (c=0xbfe76448, str=0xbfe7644f "1234") at onion.c:43
#2 0x0804844f in nivel_2 (c=0xbfe76448, str=0xbfe7644f "1234") at onion.c:35
#3 0x08048422 in nivel_1 (c=0xbfe76448, str=0xbfe7644f "1234") at onion.c:28
#4 0x080483ca in main () at onion.c:16

4. GDB representa la pila de llamadas en forma inversa. El nivel más profundo aparece primero y se numera con cero. Y secuencialmente las llamadas anteriores reciben números mayores hasta llegar al frame número cuatro. Y las negritas de la palabra frame están para recordarnos que es el nombre de un comando de GDB que me permite moverme hasta una de las llamadas. Se puede utilizar en conjunto con los comandos up y down que me llevan hacia arriba y abajo respectivamente.
5. Probamos ir hacia arriba:
(gdb) up
#1 0x0804847c in nivel_3 (c=0xbf80c5d8, str=0xbf80c5df "1234") at onion.c:41
43 nivel_4(c, str);

6. Ahora nos encontramos en la función nivel_3() justo en la línea que llamó a nivel_4(). Esto nos permitiría inspeccionar variables que se encuentren en el contexto de la función nivel_3() y que no puedo ver desde nivel_4(). Por ejemplo la variable dummy:
(gdb) p dummy
$1 = 3.14159203

7. En todo momento que nos encontramos en la línea de comandos de GDB y el programa está en mitad de la ejecución podemos pedir el listado del código fuente con el comando l (list):
(gdb) l
38 void nivel_3(int * c, char * str) {
39
40 float dummy = 3.141592f;
41
42 str[(*c)++]='3';
43 nivel_4(c, str);
44 }
45
46 void nivel_4(int * c, char * str) {
47

8. GDB muestra el código alrededor de la línea en la que nos encontramos (la cuarenta y tres). Ahora podemos ver que en este scope existe la variable dummy. Si queremos ver código más arriba o más abajo podemos usar la l seguida de un signo menos o más, respectivamente:
(gdb) l -
28 nivel_2(c, str);
29 }
30
31
32 void nivel_2(int * c, char * str) {
33
34 str[(*c)++]='2';
35 nivel_3(c, str);
36 }
37

9. Si queremos ver el código en una línea determinada podemos pasar el número como argumento del comando:
(gdb) l 47
42 str[(*c)++]='3';
43 nivel_4(c, str);
44 }
45
46 void nivel_4(int * c, char * str) {
47
48 str[(*c)++]='4';
49 str[(*c)]=0;
50
51 str[65535] = 123;

10. Si volvemos al frame cero con el comando frame y luego tratamos de ver la misma variable, fracasamos lógicamente:
(gdb) frame 0
#0 0x080484af in nivel_4 (c=0xbffc7d98, str=0xbffc7d9f "1234") at onion.c:51
51 str[65535] = 123;
(gdb) p dummy
No symbol "dummy" in current context.

La importancia del comando bt se hace mucho más evidente cuando en nuestra aplicación tenemos decenas de funciones que son llamadas por otras tantas y el error sólo se presenta en ciertas circunstancias. Imaginemos una funcion invertirCadena(char * str) que funciona en algunos casos y falla en otros. Es esperable suponer que la falla esté en la función que le pasa la cadena. Para encontrarla basta con utilizar GDB y el comando bt.


Otras formas de break point

Existen otras formas de indicarle a GDB el momento en que debe interrumpir la ejecución. Vimos anteriormente la forma más simple que consta de indicar el nombre de archivo fuente y el número de línea.

Nombre de función

Nos ocurre en algunas circunstancias que no sabemos el número de línea pero conocemos el nombre de una función sobre la cual queremos trabajar. Le podemos indicar a GDB directamente el nombre de la función como argumento del comando br. Veamos cómo hubiera sido en el primer ejemplo de este artículo:

(gdb) br unNivel
Breakpoint 1 at 0x8048416: file gdbt.c, line 21.

El resultado es que GDB obtiene la primer línea ejecutable del a función y coloca en ella el break point:

1.
#include
2.
#include
3.

4.
void unNivel(int c, char * str);
5.

6.
int main(int argc, char ** argv) {
7.

8.
printf("Paso 1\n");
9.

10.
unNivel(5, "1234567890");
11.

12.
printf("Paso 2\n");
13.

14.
return 0;
15.
}
16.

17.
void unNivel(int c, char * str) {
18.

19.
char * duplicado;
20.

21.
if (c >= strlen(str))
22.
return;
23.

24.
duplicado = strdup(str);
25.
duplicado[c] = 0;
26.
printf("[%s]\n", duplicado);
27.
}


Esta línea es por supuesto la veintiuno. Ya que la anterior, la diecinueve por ejemplo, sólo declara una variable pero no realiza operaciones.


Dirección de memoria

También podemos indicar una posición de memoria del segmento de código (code segment) de nuestra aplicación. Esto no es muy común, pero se puede hacer sin problemas. Veamos un ejemplo arbitrario:

(gdb) br main
Breakpoint 1 at 0x80483d5: file gdbt.c, line 8.
(gdb) br *0x80483e5
Breakpoint 2 at 0x80483e5: file gdbt.c, line 10.

Primero ponemos un break point en la primera línea de main() y así conocemos la posición de memoria 0x80483d5. Luego le decimos a GDB que coloque otro en la dirección de memoria que está diez y seis bytes más adelante. Para esto paso la dirección como argumento de br anteponiendo un asterisco.


Resumen

Repasamos los comandos más importantes de GDB a la vez que practicamos su forma de uso sobre ejemplos específicos. La cantidad de funcionalidad que dejé fuera del artículo es grande, pero no tiene sentido extenderse en variantes que sólo complicarían la comprensión. Por una lado invito a los lectores a experimentar nuevos comandos o variantes por su cuenta. Se puede recurrir al manual mismo de GDB disponible en varios sabores en la dirección: http://www.gnu.org/software/gdb/documentation/
Por otro lado, y a modo de proyecto personal, existe la posibilidad de que me siente a redactar otro artículo similar a éste. Me gustaría abordar temas como los conditional break point (puntos de interrupción condicional) que nos permiten detener la ejecución en una línea sólo bajo ciertas circunstancias, dump (volcado) de memoria que muestra en pantalla libremente partes arbitrarias de la memoria del proceso y los comandos que nos permiten realizar inspección en aplicaciones con varios hilos de ejecución (multithread).

Adjuntos
Adjuntos

El archivo con los fuentes para este artículo.