Memória e debugação Ricardo Rabelo 25/08/2003. Roteiro Debugação de Código Debugação de...
Transcript of Memória e debugação Ricardo Rabelo 25/08/2003. Roteiro Debugação de Código Debugação de...
Memória e debugação
Ricardo Rabelo25/08/2003
Roteiro
Debugação de Código Debugação de Memória Economia de Memória
OTcl Versus C++
Granularidade do código/script pode ser ajustada para compensar extensibilidade por performance.
Tamanho do programacomplexidade
C/C++ OTcl
grande pequeno
split objects
Escalabilidade vs Flexibilidade
Escrever todo o código em OTcl é tentador Benficio: prototipagem rápida Custo: memória + runtime
Solução Controle da granuliridade do slipt object migrando os
métodos de Otcl para C++
Debugação Código
Duas linguagens mescladas == debugação mesclada
Uso de printf (C/C++) e puts (OTcl) Problemas: recompilar o código e gerar novos
cenários a cada execução. Mas é simples Uso do gdb
Acompanhar a execução passo a passo do código. Complica quando mescla os diferentes ambientes:
C/C++ e OTcl
Debugação Código
No arquivo Makefile.in, adicionar a compilação do código objeto com o fonte
CFLAGS = $(CCOPT) $(DEFINE) –ggdb
Executar o ./configure gdb ns <nome-do-arquivo-de-script.tcl>
Debugação Código
Setar os breakpoints:(gdb) b classifier-addr.cc:47 (gdb) b AddressClassifier::AddressClassifier
Executar o programa(gdb) run
Starting program: /ns/ns-2/ns ...
Breakpoint 1, AddressClassifier::AddressClassifier (this=0x12fbd8) at classifier-addr.cc:47 (gdb)
Debugação Código
Comandos básicos gdb b -> coloca um breakpoint list -> mostra as próximas 10 linhas de código display -> watch nas variáveis help -> listar todos os outros comandos
Debugação Código
Debugação do Otcl Ferramenta Expect:
Compilada junto com o NS, no mesmo diretório Chamada através do comando “debug 1” dentro do
script que está sendo executado
http://expect.nist.gov/tcl-debug/tcl-debug.tar.gz
http://expect.nist.gov/tcl-debug/tcl-debug.ps.Z
Debugação Código
Debugação mesclada: gdb e expect Chamar a debugação Tcl a partir do ambiente
do gdb
Debugação Código(gdb) run
Starting program: /ns/ns-2/ns ...
Breakpoint 1, AddressClassifier::AddressClassifier (this=0x12fbd8) at classifier-addr.cc:47
(gdb) p this->name_
$1 = 0x2711e8 "_o73“
(gdb) call Tcl::instance().eval("debug 1")
15: lappend auto_path $dbg_library
dbg15.3> w
*0: application
15: lappend auto_path /usr/local/lib/dbg
dbg15.4> Simulator info instances
o1
dbg15.5> _o1 now
0
dbg15.6> _o73 info class
Classifier/Addr
dbg15.7> _o73 info vars
slots_ shift_ off_ip_ offset_ off_flags_ mask_ off_cmn_
dbg15.8> c
(gdb) w
Ambiguous command "w": while, whatis, where, watch.
(gdb) where
#0 AddressClassifier::AddressClassifier (this=0x12fbd8) at classifier-addr.cc:47
#1 0x5c68 in AddressClassifierClass::create (this=0x10d6c8, argc=4, argv=0xefffcdc0) at classifier-addr.cc:63 ...
(gdb)
Debugação Memória
Otcl Tcl, TclCL não possuem garbage collector. Novos objetos perdidos na memória podem causar memory leaks. Mesmo ferramentas de auxilio a alocação de memória não auxiliam
set ns [new Simulator] for {set i 0} {$i < 500} {incr i} { set a [new RandomVariable/Constant] }
Objetos perdidos após a execução do for Para lidar com isso, todos os objetos alocados em Otcl
devem ser desalocados explicitamente, no fim da simulação
Debugação Memória
Purify Set PURIFY macro in ns Makefile Usually, put -colloctor=<ld_path>
dmalloc http://www.dmalloc.com make distclean ./configure --with-dmalloc=<dmalloc_path> Resultados: dmalloc_summarize
Debugação Memória Uso do dmalloc: 1. Definir um alias
1. (csh: alias dmalloc 'eval `\dmalloc -C \!*`', bash: function dmalloc { eval `command dmalloc -b $*` })
2. Ativar a debugação1. dmalloc -l logfile low
3. Executar o programa 4. Intepretar o logfile com o script
1. dmalloc_summarize ns <logfile (dmalloc_summarize :
http://www.isi.edu/~johnh/SOFTWARE/dmalloc_summarize)5. Um relatório do uso de memória é gerado6. Em algumas plataformas é necessário fazer a lincagem
do código estática
Debugação Memória
Exemplons-2/tcl/ex/newmcast/cmcast-100.tcl
script com um comando de sair após a criação do duplex-link de número 200
size function 6358277 total 1000426 TclObject::bind(char const *, int *) 968416 StringCreate 742472 NewVar
Ns aloca ~6MB de memória. ~1MB is devido a TclObject::bind ~900KB de StringCreate~700KB de NewVar
Debugação Memória
dmalloc com gdb: colocar um breakpoint na função
dmalloc_error(). Se o código possui bibliotecas compartilhadas, é necessário dar o comando
(gdb) sharedlibrary
(gdb) add-shared-symbol-files
Debugação Memória
Dmalloc_summarize mapeia o nome das funções a as respectias areás de memória. Para a identificaçãod dos nomes, é necessário compliar de maneira estatíca.
Programas com dmalloc tendem a gastar muito mais memória, devido a inserção do código.
Dmalloc também pode verificar diversos tipos de erros de memória (“free”s duplicados, buffer overruns, etc.).
Documentação:http://dmalloc.com/docs/5.1.0/online/dmalloc.html
Economia de Memória
A memória é um fator vital numa simulação no NS
O consumo pode chegar a uma ordem exponencial
Melhor otimizar o código do que ter mais memória
C++ versus OTcl
Economia de Memória
Evitar trace-all O comando $ns trace-all $f faz com que
todos os objetos, nodos e links gerem eventos para o trace. Caso o interesse da análise esteja em um ou poucos links, não é necessário utilizar tantos. A economia de memória é em torno de 14 KB/link.
Uso de vetores para sequência de variáveis.
Ao invés de set n$i [$ns node]
Usar set n($i) [$ns node]
Economia de aproximadamente 50 Bytes/variável.
Economia de Memória Maximizar o uso do C++
sempre que possivel portar o código para C++. E evitar o uso de bind() de variaveis devido ao alto custo de alocação.
Evitar o uso de variáveis desnecessárias
Ao invés de set cmcast(1) [new CtrMcast $ns $n(1) $ctrmcastcomp [list
1 1]]
Usar new CtrMcast $ns $n(1) $ctrmcastcomp [list 1 1]
A economia é de 80 Byte/variável
Economia de Memória Uso de dynamic binding O uso do bind() em C++ consome muita memória e tempo
de execução. E fica muito mais caro se uma grande quantidade de objetos do mesmo tipo forem instanciados. Mudando os bind()'s para delay_bind() muda os requerimentos de memória por classes.
Cabeçalho dos pacotesPor padrão, em todas as simulações todos os cabeçalhos
de pacotes são carregados. Nesse caso é uma grande economia de memória remover todos os pacotes e adicionar apenas os necessários:
remove-all-packet-headers ;# removes all except common
add-packet-header IP Message ;# hdrs reqd for cbr traffic
Economia de Memória Exemplo de economia de memória com o
remove-all-packet (Pentium-II, 448 MHz 1GB RAM 4GB hd Linux redhat-7.0.)
Cenários com 2 nodos conectados por um link de grande atraso e banda passante (~ns/tcl/ex/pkts.tcl)
BW = 1Gbps, Delay=100ms,Agent= UDP, traffic source=CBR, pacotes de 210 a uma taxa de 1Gbps:
109 * 100 * 10-6
8 * 210
= ~59,500 pacotes no link O uso de memória é em torno de 140MB, ~2KB/pkt.
Economia de Memória
Removendo todos os cabeçalhos e adicionando apenas os do trafego CBR, o uso de memória vai para ~30MB, 500bytes/pacote.
Toda a informação sobre os pacotes adicionados
~ns/tcl/lib/ns-packet.tcl. Mais informações na seção" Including
Packet Headers in Your Simulation" no capitulo 12 do manual.
Tempo de execução
Evitar trace-all e trace-nam Utilizar endereçamento hierarquico
Diminui a quantidade de classifiers alocados
Diminui o tempo de montagem das tabelas de rotas
Uso de manual routing, em cenários com muitos links (~ns/tcl/ex/many_tcp.tcl )