ysth me preguntó en el IRC para comentar su pregunta. He hecho una pila completa de cosas que "desmontan" perl compilado y esas cosas (solo vea mi página de CPAN [http://search.cpan.org/~jjore]).
Perl compila su fuente a un árbol de OP*
estructuras que ocasionalmente tienen punteros C a SV*
que son valores perl. Su volcado de núcleo ahora tiene un montón de esos OP*
y SV*
escondidos.
El mejor mundo posible sería tener un módulo perl como B::Deparse para que usted pueda entender la información. Se obras mediante el uso de una interfaz de luz a perl memoria en las clases B::OP
y B::SV
(documentado en B, perlguts y perlhack).Esto no es realista para usted porque un objeto B::*
es solo un puntero en la memoria con accesores para decodificar la estructura para nuestro uso . Considere:
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,
},
}
);
que cuando el funcionamiento mostró que el B::PV
objeto (es ISA B::SV
) es verdaderamente simplemente una interfaz para la representación memoria de la cadena compilado 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'};
Sin embargo, esto implica que cualquier B::*
utilizando el código debe estar efectivamente operar en memoria viva. Tye McQueen pensó que recordaba un depurador de C que podría revivir por completo un proceso de trabajo dado un volcado de memoria. Mi gdb
no puedo. gdb
puede permitirle volcar el contenido de sus estructuras OP*
y SV*
. Lo más probable es que simplemente lea las estructuras volcadas al interpretar la estructura de su programa. Si lo desea, puede usar gdb
para volcar las estructuras, luego crear sintéticamente B::*
objetos que se comportaron en la interfaz como si fueran normales y usan B::Deparse
en eso. En la raíz, nuestro deparser y otras herramientas de depuración de errores están orientadas principalmente a objetos, por lo que podría simplemente "engañarlos" por creando un montón de clases y objetos falsos B::*
.
Puede encontrar la lectura de la clase B :: Deparse coderef2text
método instructivo. Acepta una referencia de función, lo arroja a un objeto B::CV
, y lo utiliza como entrada para el método 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);
Para introducciones más suave para OP*
e ideas relacionadas, ver la actualizado PerlGuts Illustrated y Optree guts.
Josh, gracias por la respuesta detallada. Esto está muy bien con lo que esperaba. Parece un proyecto para largas noches de invierno. – otmar