El objetivo es detectar los memory leaks y la idea es que ademas de detectarlos sepamos en que archivo y en que línea están. Para ello hay que compilar con la opcion -g para ver el código fuente para cada funcion en el stack trace.
En las entradas anteriores de detección de memory leak (I y II) se recomendó setear las variables de ambiente LD_PRELOAD y LD_AUDIT en el .profile, dbx no funcionará adecuadamente si éstas 2 variables estan seteadas.
Ejemplo paso a paso: (Código fuente del archivo basic_mta.c y del Makefile al final del post)
- Remover las variables de ambiente LD_PRELOAD y LD_AUDIT.
unset LD_PRELOAD unset LD_AUDIT - Compilar utilizando la opción -g (en el Makefile del ejemplo nuestro programa se llamará basic_mta) y si no estamos compilando con gcc usar tambien la opción -O o la opcion -xO[n]
make clobber all
- Ejecutar dbx con nuestro ejecutable como parámetro:
dbx basic_mta
- En caso de que nuestro ejecutable reciba parámetros por línea de comandos:
dbx -c "runargs -param1 valor1 -parm2 valor2" basic_mta
- Ya dentro del dbx ejecutar:
check -memuse
dbxenv rtc_mel_at_exit verbose dbxenv rtc_error_log_file_name errores.txt
run
- Al finalizar la ejecución del programa en caso de haber memory leaks veremos algo así:



- En el resultado de la ejecución podemos ver el call stack de la memoria que se esta perdiendo y asi poder corregir nuestro memory leak.
Memory Leak (mel): Found leaked block of size 16 bytes at address 0x65658 At time of allocation, the call stack was: [1] _alloc_result_header() (optimized), at 0xe75aad9c (line ~367) in "pin_decimal.c" [2] pin_decimal_set_scale() (optimized), at 0xe75ae960 (line ~3545) in "pin_decimal.c" [3] pin_decimal_from_double() (optimized), at 0xe75aca28 (line ~1719) in "pin_decimal.c" [4] pbo_decimal_from_double() (optimized), at 0xe75a8bd0 (line ~165) in "pbo_decimal.c" [5] pin_mta_worker_opcode() (optimized), at 0x15628 (line ~243) in "basic_mta.c" - Ahí se ve el nombre del archivo(basic_mta.c) y la línea(243) donde esta el memory leak.
- Para ver el resto de los memory leaks hay que revisar el resto de los links en la solapa Memory leaks.
Makefile
OS=solaris
VERSION=7.5
##########
PINDIR=${PIN_HOME}
INCDIR=$(PINDIR)/include
LIBDIR=$(PINDIR)/lib
##########
CC_comp_solaris = cc
CC_link_solaris = CC
CC_comp_linux = gcc
CC_link_linux= gcc
CC_comp_hpux_ia64 = cc
CC_link_hpux_ia64 = $(CC_comp_hpux_ia64)
CC_comp_hpux = cc
CC_link_hpux = $(CC_comp_hpux)
CC_comp_aix = xlc_r
CC_link_aix = $(CC_comp_aix)
CC_comp = $(CC_comp_$(OS))
CC_link = $(CC_link_$(OS))
##########
CFLAGS_solaris= -g -xcg92 -O
CFLAGS_linux= -m32 -fPIC -g -pthread
CFLAGS_hpux_ia64= +Z
CFLAGS_hpux= -g -Ae +Z
CFLAGS_aix= -g -Drs6000 -Dunix -D__unix -D__aix
CFLAGS= $(CFLAGS_$(OS))
CPPFLAGS = -I$(INCDIR)
LDFLAGS_solaris= -R:$(LIBDIR):
LDFLAGS_linux= -m32 -Wl,--export-dynamic
LDFLAGS_hpux_ia64= -Wl,-E -Wl,+b:$(LIBDIR):
LDFLAGS_hpux= -Wl,-E -Wl,+b:$(LIBDIR):
LDFLAGS_aix=-bM:SRE -bexpall -brtl -lc
LDFLAGS = -L$(LIBDIR) $(LDFLAGS_$(OS))
OS_LIBS_solaris= -lsocket -lnsl -lgen -lposix4 -lpthread -ldl
OS_LIBS_hpux_ia64= -lsec -lrt -lpthread -lCsup -lunwind
OS_LIBS_hpux= -lsec -lrt -lpthread -lCsup
OS_LIBS_aix= -lpthread
OS_LIBS_linux= -lpthread
LDLIBS= -lportal -lmta -lpinsys $(OS_LIBS_$(OS))
##########
INCFILES= $(INCDIR)/pcm.h $(INCDIR)/pin_mta.h $(INCDIR)/pin_bill.h \
$(INCDIR)/pin_cust.h $(INCDIR)/pin_act.h \
$(INCDIR)/pin_errs.h $(INCDIR)/pinlog.h
###########
APPS= basic_mta
FILES= basic_mta.c
OBJECTS= basic_mta.o
DEP_linux=$(FILES)
DEP=$(DEP_$(OS))
###########
all: $(APPS)
clean:
rm -f $(OBJECTS) core
clobber: clean
rm -f $(APPS)
###########
$(APPS): $(OBJECTS) $(INCFILES) Makefile
$(CC_link) -o $@ $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(OBJECTS) $(LDLIBS)
$(OBJECTS): $(INCFILES) Makefile $(DEP)
$(CC_comp) -c $(CFLAGS) $(CPPFLAGS) $(FILES)
###########
FRC:
basic_mta.c
#include <stdio.h>
#include <time.h>
#include "pcm.h"
#include "pin_errs.h"
#include "pinlog.h"
#include "pin_pymt.h"
#include "pin_mta.h"
/*******************************************************************
* Configuration of application
* Called prior MTA_CONFIG policy opcode
*******************************************************************/
PIN_EXPORT void
pin_mta_config(
pin_flist_t *param_flistp,
pin_flist_t *app_flistp,
pin_errbuf_t *ebufp)
{
int32 mta_flags = 0;
void *vp = NULL;
if (PIN_ERR_IS_ERR(ebufp)) {
return;
}
PIN_ERR_LOG_FLIST (PIN_ERR_LEVEL_DEBUG, "pin_mta_config parameters flist", param_flistp);
PIN_ERR_LOG_FLIST (PIN_ERR_LEVEL_DEBUG, "pin_mta_config application info flist", app_flistp);
vp = PIN_FLIST_FLD_GET (app_flistp, PIN_FLD_FLAGS, 0,ebufp);
if(vp)
mta_flags = *((int32*)vp);
/***********************************************************
* The new flag MTA_FLAG_VERSION_NEW has been introduced to
* differentiate between new mta & old mta applications as
* only new applications have the ability to drop PIN_FLD_PARAMS
* for valid parameters . It is only for new apps that
* checking err_params_cnt is valid, otherwise for old applications
* this check without a distincion for new applications would hamper
* normal functioning.
***********************************************************/
mta_flags = mta_flags | MTA_FLAG_VERSION_NEW;
mta_flags = mta_flags | MTA_FLAG_BATCH_MODE;
PIN_FLIST_FLD_SET (app_flistp, PIN_FLD_FLAGS, &mta_flags, ebufp);
if (PIN_ERR_IS_ERR(ebufp)) {
PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR, "pin_mta_config error", ebufp);
}
}
/*******************************************************************
* Usage information for the specific app.
* Called prior MTA_USAGE policy opcode
*******************************************************************/
PIN_EXPORT void
pin_mta_usage(
char *prog)
{
pin_errbuf_t ebuf;
pin_flist_t *ext_flistp = NULL;
char *usage_str = NULL;
char *format = "\nModo de uso:\t %s\n";
PIN_ERRBUF_CLEAR (&ebuf);
usage_str = (char*)pin_malloc( strlen(format) + strlen(prog) + 1 );
if (usage_str == NULL) {
PIN_ERR_LOG_MSG(PIN_ERR_LEVEL_ERROR,"No Memory error");
return;
}
sprintf(usage_str, format ,prog);
ext_flistp = pin_mta_global_flist_node_get_no_lock(PIN_FLD_EXTENDED_INFO, &ebuf);
PIN_FLIST_FLD_SET (ext_flistp, PIN_FLD_DESCR, usage_str, &ebuf);
printf("%s \n", usage_str);
if (PIN_ERR_IS_ERR(&ebuf)) {
PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR, "pin_mta_usage error", &ebuf);
}
pin_free(usage_str);
}
/*******************************************************************
* Application defined search criteria.
* Called prior MTA_INIT_SEARCH policy opcode
*******************************************************************/
PIN_EXPORT void
pin_mta_init_search(
pin_flist_t *app_flistp,
pin_flist_t **s_flistpp,
pin_errbuf_t *ebufp)
{
pin_flist_t *s_flistp = NULL;
char *template = "select x from /account where F1 in ('ROOT') ";
int32 search_flag = 768;
poid_t *poid = NULL;
void *vp = NULL;
pin_flist_t *tmp_flistp = NULL;
if (PIN_ERR_IS_ERR(ebufp)) {
return;
}
PIN_ERR_LOG_FLIST (PIN_ERR_LEVEL_DEBUG, "pin_mta_init_search application info flist", app_flistp);
s_flistp = PIN_FLIST_CREATE(ebufp);
poid = PIN_FLIST_FLD_GET (app_flistp, PIN_FLD_POID_VAL, 0, ebufp);
PIN_FLIST_FLD_PUT(s_flistp, PIN_FLD_POID, PIN_POID_CREATE(PIN_POID_GET_DB(poid), "/search/pin", -1, ebufp), ebufp);
PIN_FLIST_FLD_SET (s_flistp, PIN_FLD_FLAGS, &search_flag, ebufp);
PIN_FLIST_FLD_SET (s_flistp, PIN_FLD_TEMPLATE, template, ebufp);
tmp_flistp = PIN_FLIST_ELEM_ADD (s_flistp, PIN_FLD_ARGS, 1, ebufp);
PIN_FLIST_FLD_SET (tmp_flistp, PIN_FLD_ACCOUNT_NO, "", ebufp);
tmp_flistp = PIN_FLIST_ELEM_ADD (s_flistp, PIN_FLD_RESULTS, 0, ebufp);
PIN_FLIST_FLD_SET (tmp_flistp, PIN_FLD_ACCOUNT_NO, "", ebufp);
if (PIN_ERR_IS_ERR(ebufp)) {
PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR, "pin_mta_init_search error", ebufp);
PIN_FLIST_DESTROY_EX (&s_flistp, NULL);
}else{
*s_flistpp = s_flistp;
PIN_ERR_LOG_FLIST (PIN_ERR_LEVEL_DEBUG, "pin_mta_init_search search flist", s_flistp);
}
}
/*******************************************************************
* Search results may be updated, modified or enriched
* Called prior MTA_TUNE policy opcode
*******************************************************************/
PIN_EXPORT void
pin_mta_tune(
pin_flist_t *app_flistp,
pin_flist_t *srch_res_flistp,
pin_errbuf_t *ebufp)
{
pin_const_poid_type_t type = 0;
pin_cookie_t s_cookie = 0;
pin_cookie_t m_cookie = 0;
pin_flist_t *multi_res_flistp = NULL;
pin_flist_t *tmp_flistp = NULL;
poid_t *pdp = 0;
poid_t *n_pdp = 0;
int64 db = 0;
int64 id = 0;
int32 i = 0;
int32 s_rec_id = 0;
int32 m_rec_id = 0;
void *vp = 0;
if (PIN_ERR_IS_ERR(ebufp)) {
return;
}
PIN_ERR_LOG_FLIST (PIN_ERR_LEVEL_DEBUG, "basic_mta application info flist", app_flistp);
PIN_ERR_LOG_FLIST (PIN_ERR_LEVEL_DEBUG, "basic_mta search results flist", srch_res_flistp);
vp = PIN_FLIST_FLD_GET (app_flistp, PIN_FLD_OPS_ERROR, MTA_OPTIONAL, ebufp);
if(vp){
i = *((int32*)vp);
}
if (i) {
while((multi_res_flistp = PIN_FLIST_ELEM_GET_NEXT(srch_res_flistp, PIN_FLD_MULTI_RESULTS, &s_rec_id, 1, &s_cookie, ebufp)) != NULL) {
m_cookie = 0;
while((tmp_flistp = PIN_FLIST_ELEM_GET_NEXT(multi_res_flistp, PIN_FLD_RESULTS, &m_rec_id, 1, &m_cookie, ebufp)) != NULL) {
vp = PIN_FLIST_FLD_TAKE (tmp_flistp, PIN_FLD_POID, 0, ebufp);
if(vp) {
pdp = (poid_t*)vp;
db = PIN_POID_GET_DB (pdp);
id = PIN_POID_GET_ID (pdp);
type = PIN_POID_GET_TYPE (pdp);
id = id * i;
n_pdp = PIN_POID_CREATE (db, type,id, ebufp);
PIN_POID_DESTROY (pdp, ebufp);
PIN_FLIST_FLD_PUT (tmp_flistp, PIN_FLD_POID, n_pdp, ebufp);
}
}
}
}
if (PIN_ERR_IS_ERR(ebufp)) {
PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR, "pin_mta_tune error", ebufp);
}
}
/*******************************************************************
* Function executed at application exit
* Called prior MTA_EXIT policy opcode
*******************************************************************/
PIN_EXPORT void
pin_mta_exit(
pin_flist_t *app_flistp,
pin_errbuf_t *ebufp)
{
PIN_ERR_LOG_FLIST (PIN_ERR_LEVEL_DEBUG, "pin_mta_exit application info flist", app_flistp);
if (PIN_ERR_IS_ERR(ebufp)) {
PIN_ERR_LOG_EBUF(PIN_ERR_LEVEL_ERROR, "pin_mta_exit error", ebufp);
printf("Error durante la ejecucion.\n");
} else {
printf("Ejecucion exitosa.\n");
}
}
/*******************************************************************
* Main application opcode is called here
*******************************************************************/
PIN_EXPORT void
pin_mta_worker_opcode(
pcm_context_t *ctxp,
pin_flist_t *srch_res_flistp,
pin_flist_t *op_in_flistp,
pin_flist_t **op_out_flistpp,
pin_flist_t *ti_flistp,
pin_errbuf_t *ebufp)
{
pin_cookie_t cookie = NULL;
pin_flist_t *app_flistp = NULL;
int32 rec_id = 0;
int32 mta_flags = 0;
void *vp = NULL;
if (PIN_ERR_IS_ERR(ebufp)) {
return;
}
app_flistp = pin_mta_global_flist_node_get_with_lock (PIN_FLD_APPLICATION_INFO, ebufp);
vp = PIN_FLIST_FLD_GET (app_flistp, PIN_FLD_FLAGS, 0,ebufp);
if(vp){
mta_flags = *((int32*)vp);
}
pin_mta_global_flist_node_release(PIN_FLD_APPLICATION_INFO, ebufp);
//memory leak agregado a proposito
pin_decimal_t *amount = pbo_decimal_from_double(90, ebufp);
//memory leak agregado a proposito
poid_t *poid = PIN_POID_CREATE(1, "/account", -1, ebufp);
//memory leak agregado a proposito
pin_flist_t *tmp_flistp = PIN_FLIST_COPY(op_in_flistp, ebufp);
//memory leak agregado a proposito
char *str = (char*)malloc(sizeof(char));
}
Martín Falconi
No hay comentarios.:
Publicar un comentario