Mostrando entradas con la etiqueta programacion. Mostrar todas las entradas
Mostrando entradas con la etiqueta programacion. Mostrar todas las entradas

viernes, 8 de agosto de 2014

Automatizar TortoiseSVN con fichero por lotes

Si necesitamos automatizar ciertas tareas en cada commit/update de nuestro proyecto gestionado con TortoiseSVN en windows podemos realizar estos sencillos ficheros por lotes .bat para simplificar la tarea.
Dejo aquí dos ejemplos básicos que he visto en este blog en inglés.

Ejemplo para Commit:
@echo off
echo.
echo. [ SVN Committer ]
:: The two lines below should be changed to suit your system.
set SOURCE=C:\Users\Administrador\Desktop\repoCodesk
set SVN=C:\Program Files\TortoiseSVN\bin
echo.
echo. Committing %SOURCE% to SVN...
"%SVN%\TortoiseProc.exe" /command:commit /path:"%SOURCE%" /closeonend:0
echo. done.
echo.
echo. Operation complete.
Ejemplo para Update:
@echo off
echo.
echo. [ SVN Updater ]
set SOURCE=C:\Users\Administrador\Desktop\repoCodesk
set SVN=C:\Program Files\TortoiseSVN\bin
:: The SOURCEj below should be already set to fit your system.
echo. Updating %SOURCE%\ from SVN...
"%SVN%\TortoiseProc.exe" /command:update /path:"%SOURCE%\" /closeonend:2
echo.        done.

Nota:  Utilizamos el parámetro closeonend según nuestras necesidad. En el caso del Commit mostramos el diálogo de selección de ficheros, para el update en este caso lo omitimos.

lunes, 25 de marzo de 2013

A la caza de leaks en Embarcadero C++


Los desarrolladores que utilizamos Codegear RAD Studio no disponemos de tantas herramientas como nos gustaría, la mayor parte de éstas están orientadas a VisualStudio.
Recientemente he necesitado realizar tareas de debug intensivo en una aplicación servidor debido a la existencia de varios leaks de memoria difíciles de encontrar.  Hasta la fecha me había bastado con el socorrido CodeGuard que viene de serie con el IDE, pero al parecer esta herramienta tan sólo puede encontrar ciertos tipos concretos de fugas, inicializaciones erróneas o acceso a objetos de memoria inválidos.

En mi búsqueda de herramientas alternativas he topado con un código que puede ser de utilidad, lo he probado y funcionar funciona (aunque todavía no he hecho pruebas intensivas). Es una adaptación de la herramienta IMallocSpy escrita originalmente para MSVC, que encontré en este blog adaptada a BCB. He tenido que arreglar alguna función para que compilara. Aquí os la dejo, esperando que sea de utilidad y os ahorre algún  quebradero de cabeza. Estos son los pasos:

1) Necesitamos descargar los archivos stdafx.cpp y leaker.cpp de esta dirección: http://comcorba.tripod.com/comleaks.htm

2) Crea la unidad IMallocSpyUnit.h con el siguiente contenido:

#ifndef IMallocSpyUnit
#ifndef IMallocSpyUnit
#define IMallocSpyUnit

// IMallocSpyUnit.h
class CMallocSpy : public IMallocSpy
{
 public:
 CMallocSpy(void);
 ~CMallocSpy(void);
 virtual HRESULT STDMETHODCALLTYPE QueryInterface();
 virtual ULONG STDMETHODCALLTYPE AddRef( void);
 virtual ULONG STDMETHODCALLTYPE Release( void);

 // IMallocSpy methods
 virtual SIZE_T STDMETHODCALLTYPE PreAlloc(
 /* [in] */ SIZE_T cbRequest);
 virtual void *STDMETHODCALLTYPE PostAlloc(
 /* [in] */ void *pActual);
 virtual void *STDMETHODCALLTYPE PreFree(
 /* [in] */ void *pRequest,
 /* [in] */ BOOL fSpyed);
 virtual void STDMETHODCALLTYPE PostFree(
 /* [in] */ BOOL fSpyed);
 virtual SIZE_T STDMETHODCALLTYPE PreRealloc(
 /* [in] */ void *pRequest,
 /* [in] */ SIZE_T cbRequest,
 /* [out] */ void **ppNewRequest,
 /* [in] */ BOOL fSpyed);
 virtual void *STDMETHODCALLTYPE PostRealloc(
 /* [in] */ void *pActual,
 /* [in] */ BOOL fSpyed);
 virtual void *STDMETHODCALLTYPE PreGetSize(
 /* [in] */ void *pRequest,
 /* [in] */ BOOL fSpyed);
 virtual SIZE_T STDMETHODCALLTYPE PostGetSize(
 /* [in] */ SIZE_T cbActual,
 /* [in] */ BOOL fSpyed);
 virtual void *STDMETHODCALLTYPE PreDidAlloc(
 /* [in] */ void *pRequest,
 /* [in] */ BOOL fSpyed);
 virtual int STDMETHODCALLTYPE PostDidAlloc(
 /* [in] */ void *pRequest,
 /* [in] */ BOOL fSpyed,
 /* [in] */ int fActual)
 virtual void STDMETHODCALLTYPE PreHeapMinimize( void);
 virtual void STDMETHODCALLTYPE PostHeapMinimize( void);

 void Clear();
 void Dump();
 void SetBreakAlloc(int allocNum);

 protected:
 enum
 {
   HEADERSIZE = 4,
   MAX_ALLOCATIONS = 100000 // cannot handle more than max
 };

 ULONG m_cRef;
 ULONG m_cbRequest;
 int m_counter;
 int m_breakAlloc;
 char *m_map;
 size_t m_mapSize;
};

#endif
  
3) Añade este código donde quieras debuguear en busca de leaks:
 typedef void WINAPI (*SETOANOCACHE)();
 HINSTANCE hDLL = LoadLibrary(L"oleaut32.dll");
 if(!hDLL) throw Exception("Unable to load oleaut32.dll");
 SETOANOCACHE SetOaNoCachePtr = (SETOANOCACHE) GetProcAddress(hDLL,"SetOaNoCache");
 if (!SetOaNoCachePtr) throw Exception("Unable to get SetOaNoCache");
 SetOaNoCachePtr();
 // Initialize COM.
 ::CoInitialize(NULL);
 // Initialize the COM memory checker …
 CMallocSpy* pMallocSpy = new CMallocSpy;
 pMallocSpy->AddRef();
 ::CoRegisterMallocSpy(pMallocSpy);
 pMallocSpy->Clear();
 test_com_allocs(); // CAMBIA ESTO POR LA FUNCIÓN A TESTEAR
 pMallocSpy->Dump();
 ::CoRevokeMallocSpy();
 pMallocSpy->Release();
 ::CoUninitialize();
Si se da algún leak en el código contenido por la función de ejemplo "test_com_allocs()" nos aparecerá el aviso en el output del IDE.

viernes, 16 de noviembre de 2012

Migrar de Indy9 a Indy10 en Codegear C++

Hace algunos años que utilizo este componentse desde que empecé a trabajar con el viejo Borland C++ Builder ( Indy8 ). El problema es que, cuando quieres actualizarte a Indy10, te encuentras con que en esa versión han reorganizado la mayoría de las clases y han reescrito parte de los interfaces… además la documentación clara escasea y más aún los ejemplos en C++.

En mis periplos para traducir clientes y servidores escritos en Indy9 tuve que consultar gran variedad de foros y recursos on-line, pero hubo uno que me resultó especialmente útil ya que enumeraba los principales cambios de una versión a otra.

Por si resulta de utilidad a alguien, dejo aquí el  resumen de diferencias principales:

  • POP3->MaxLineLength  ahora es Pop->IOHandler->MaxLineLength 
  • wsOK movido, ahora se usa IdIMap4  
  • Pop3.Connect(Timeout) se divide en dos nuevos comandos ( ya no permite indicar timeout en el constructor ), ahora se usa Pop3->ConnectTimeout = TimeOut; y Pop3->Connect() 
  • StoredPathName desaparece, camgiado TIdAttachment to TIdAttachmentFile
  • POP->Capture(Dest) ahora es POP->IOHandler->Capture(Dest) 
  • Parámetros de OnWork y OnProcessWork cambiados, cambiado el parámetro const int a int64 ( no const)
  • EIDSocketError desaparece , usar IdStack 
  • CommaSepaeratedToStringList desaparece, ahora se usa IdGlobalProtocols
  • TIdText desaparece, añadido IdText
  •  Dentro de TIdTCPServer los eventos OnConnect y OnExecute cambian sus parámetros TIdPeerThread a TIdContext ( un concepto distinto )

Quien quiera puede leer el artículo original aquí ( he añadido algúa nota que no aparecía en él ): Artículo original ( en inglés )


viernes, 14 de septiembre de 2012

Supresión de errores en PHP empeora el rendimiento

Cualquier desarrollador PHP sabe que el rendimiento no es el punto fuerte e este lenguaje, no obstante la comunidad ha ido aportando grandes mejoras versión tras versión ( precompilado, optimización, etc ).

No es cuestión de derrochar recursos porque sí... es bueno estar abiertos a esos pequeños tips que nos enseñan con poco esfuerzo a ahorrar preciosos ciclos de reloj que en un proyecto grande pueden significar la diferencia entre algo razonable y algo insoportable.

Y he aquí la curiosidad: el magnífico sistema de supresión de errores en PHP ( incluir una arroba "@" antes de la instrucción que se desea silenciar )  es un auténtico caníbal silencioso de CPUs.  En algunos artículos acusan a esta directiva de provocar hasta un 40% de retardo adicional.

En este otro enlace muestran una sencilla prueba de 10.000 iteraciones con y sin prefijo "@", el resultado parece muy claro, hasta 10 veces más lento:


0.010571002960205 microsegundos con supresión de errores ( @instrucción )
0.002446174621582 microsegundos en ejecución normal

Desde que conozco esta información, como es de esperar, he eliminado la supresión de errores de mis algoritmos, no he percibido la diferencia de forma subjetiva, pero no pongo en duda lo que parece claro.

Y ahora queda una duda ¿qué hacemos con los posibles errores que pueden surgir si no hacemos uso de la supresión de errores?. Creo que sólo hay una respuesta... aplicar un control de errores más estricto prestando especial atención a las excepciones inesperadas en instrucciones básicas. Las buenas prácticas lo requieren.

miércoles, 11 de abril de 2012

Codegear XE : Compilar sin librerías dinámicas

Hoy en un foro de C++ Builer que suelo visitar he encontrado una duda muy habitual de cualquier programador que empieza con este IDE.

Cuando genera una aplicación win32 el compilardor por defecto lo hace usando librerías dinámicas, de tal forma que ese ejecutable queda muy liviano pero no funcionará en ninguna máquina si no se adjuntan dichas librerías ( ningún Windows las trae de serie ).  El resultado es que la aplicación no se ejecuta y a cambio nos obsequia con una colección de molestos mensajes pidiendo nosecuantas librerías .bpl

Normalmente queremos generar ejecutables que funcionen de forma autónoma, por lo menos en producción. Para ello debemos modificar las siguientes opciones:

- Project > Options > C++ Linker > ( Desmarca la opción "Link with Dynamic RTL" )

- Project > Options > Packages > ( Desmarca la opción "Build with runtime packages" )


Así el ejecutable resultante aumentará de tamaño considerablemente, pero funcionará
en todas las plataformas windows sin necesidad de librerías especiales de builder.

jueves, 2 de febrero de 2012

Dudas resueltas: C++ FAQ

Mi trabajo me obliga a compaginar muchas tareas y roles distintos (si estás en el sector del desarrollo de aplicaciones esto te resultará familiar).

Por esa razón cuando toca picar código es necesario tener siempre a mano información de consulta rápida para el lenguaje o la disciplina de turno.  Es vital si tu cabeza está en varios asuntos a la vez y además necesitas producir código aceptable en cortos periodos de tiempo.

Hoy he encontrado una página fantástica para añadir a mi colección, se trata de un FAQ de C++ al que he llegado de casualidad.  Me ha parecido una lista muy completa, bien explicada y además está ilustrada con cientos de ejemplos.

Enlace en inglés: C++ FAQ (click aquí)

martes, 31 de enero de 2012

Patrones de diseño en programación orientada a objetos

Hoy me he topado con un recurso bastante útil. Se trata de una página en inglés que recopila los patrones de diseño más utilizados (como los que se enseñan en la universidad en ingeniería del software o estructura de datos). Me ha parecido interesante guardar la dirección:

Link (inglés)
Design Patterns | Object Oriented Design

viernes, 27 de enero de 2012

Limpiar archivos .svn de carpetas de repositorios (win)


Si trabajas con repositorios (como p.ej. TortoiseSVN) puede que te hayas encontrado con este caso alguna vez...

Estamos trabajando en nuestra aplicación y en un momento dado necesitamos extraer parte del código fuente y guardarlo sin esas dichosas carpetas .svn repartidas por todos los subdirectorios.  ¿Cómo puedo hacer esto?  En pequeños proyectos no supondrá un problema hacerlo a mano pero si se trata de una "criatura" de gran embergadura la cosa se complica, y puede resultar tedioso recorrer todo el árbol de directorios para dejarlo como una patena.

¿Solución? (encontrado en SNIPPLR): Editando el registro de windows (inicio > ejecutar > regedit) podemos añadir un sencillo comando recursivo de limpieza en cuatro pasos:

1. Crear una nueva Clave en el registro y llamarla DeleteSVN:
\HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN  

2. En REG_SZ de nuestra clave escribir:
Eliminar carpetas SVN

3. Crear otra nueva clave dentro de DeleteSVN llamada command, así:
\HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN\command

4. En REG_SZ de la nueva clave poner:
cmd.exe /C  "TITLE Removing SVN Folders in %1 && FOR /r "%1" %%f IN (.svn) DO RD /s /q "%%f" "


A partir de ahora cada vez que se muestre nuestro menú del botón derecho del ratón al pulsarlo sobre una carpeta, aparecerá la nueva opción "Eliminar carpetas SVN" la cual lanzará un shell fugaz que hará el trabajo por nosotros.