ysth mi ha chiesto su IRC di commentare la sua domanda. Ho fatto un intero mucchio di roba perl per "smontare" compilato perl e roba da (leggi la mia pagina CPAN [http://search.cpan.org/~jjore]).
Perl compila la sorgente su un albero delle strutture OP*
che a occasionalmente ha puntatori C su SV*
che sono valori perl. Il tuo core dump ora ha un mucchio di quelli OP*
e SV*
nascosti.
Il miglior mondo possibile sarebbe avere un modulo perl come B::Deparse fare il lavoro di comprensione delle informazioni per voi. Si funziona utilizzando un'interfaccia luce perl memoria nelle classi B::OP
e B::SV
(documentato in B, perlguts e perlhack).Questo non è realistico per te perché un oggetto B::*
è solo un puntatore in memoria con gli accessori per decodificare la struttura per il nostro uso di . Considerare:
require Data::Dumper;
require Scalar::Util;
require B;
my $value = 'this is a string';
my $sv = B::svref_2object(\ $value);
my $address = Scalar::Util::refaddr(\ $value);
local $Data::Dumper::Sortkeys = 1;
local $Data::Dumper::Purity = 1;
print Data::Dumper::Dumper(
{
address => $address,
value => \ $value,
sv => $sv,
sv_attr => {
CUR => $sv->CUR,
LEN => $sv->LEN,
PV => $sv->PV,
PVBM => $sv->PVBM,
PVX => $sv->PVX,
as_string => $sv->as_string,
FLAGS => $sv->FLAGS,
MAGICAL => $sv->MAGICAL,
POK => $sv->POK,
REFCNT => $sv->REFCNT,
ROK => $sv->ROK,
SvTYPE => $sv->SvTYPE,
object_2svref => $sv->object_2svref,
},
}
);
che quando viene eseguito ha mostrato che l'oggetto B::PV
(è ISA B::SV
) è veramente solo un'interfaccia alla rappresentazione memoria della stringa compilato this is a string
.
$VAR1 = {
'address' => 438506984,
'sv' => bless(do{\(my $o = 438506984)}, 'B::PV'),
'sv_attr' => {
'CUR' => 16,
'FLAGS' => 279557,
'LEN' => 24,
'MAGICAL' => 0,
'POK' => 1024,
'PV' => 'this is a string',
'PVBM' => 'this is a string',
'PVX' => 'this is a string',
'REFCNT' => 2,
'ROK' => 0,
'SvTYPE' => 5,
'as_string' => 'this is a string',
'object_2svref' => \'this is a string'
},
'value' => do{my $o}
};
$VAR1->{'value'} = $VAR1->{'sv_attr'}{'object_2svref'};
Ciò implica, tuttavia, che qualsiasi B::*
utilizzando il codice deve essere effettivamente operare sulla memoria dal vivo. Tye McQueen ha pensato di ricordare un debugger C che potrebbe far rivivere completamente un processo di lavoro dato un core dump. Il mio gdb
non può. gdb
può consentire di scaricare il contenuto delle strutture OP*
e SV*
. Molto probabilmente leggerete semplicemente le strutture scaricate su interpretando la struttura del vostro programma. Se lo desideri, puoi utilizzare gdb
per eseguire il dump delle strutture, quindi creare sinteticamente gli oggetti B::*
che si comportano nell'interfaccia come se fossero ordinari e utilizzare B::Deparse
su quello. Alla radice, il nostro depharger e altri strumenti di debugging sono per lo più orientati agli oggetti in modo da poterli "ingannare" da creando una pila di classi e oggetti falsi B::*
.
È possibile trovare istruttivo il metodo coderef2text
della classe B :: Deparse . Si accetta un riferimento alla funzione, l'inserisce in un oggetto B::CV
, e lo utilizza per l'ingresso al metodo deparse_sub
:
require B;
require B::Deparse;
sub your_function { ... }
my $cv = B::svref_2object(\ &your_function);
my $deparser = B::Deparse->new;
print $deparser->deparse_sub($cv);
Per introduzioni più delicato di OP*
e idee correlate, vedere la versione aggiornata PerlGuts Illustrated e Optree guts.
Josh, grazie per la risposta dettagliata. Questo praticamente un jive con quello che mi aspettavo. Sembra un progetto per lunghe notti invernali. – otmar