Ответ 1
ysth попросил меня в IRC прокомментировать ваш вопрос. Я сделал целый куча вещей "разобрать" скомпилированные perl и прочее (просто посмотри мой Страница CPAN [http://search.cpan.org/~jjore]).
Perl компилирует ваш источник в дерево OP*
structs, которое
иногда имеют C-указатели на SV*
, которые являются perl-значениями. Ваше основное
Теперь у дампа есть куча этих OP*
и SV*
.
Самый лучший мир - это иметь модуль perl, например
B:: Deparse выполняет работу по пониманию информации. Это
работает с использованием легкого интерфейса для perl-памяти в B::OP
и
B::SV
(задокументировано в B, perlguts и
perlhack). Это нереально для вас, потому что объект B::*
просто указатель на память с помощью аксессуаров для декодирования структуры для наших
использовать. Рассмотрим:
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,
},
}
);
который при запуске показал, что объект B::PV
(это ISA B::SV
) является
это просто интерфейс для представления памяти
скомпилированная строка 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'};
Это, однако, означает, что любой B::*
с использованием кода должен фактически работать
на живой памяти. Тай Маккуин думал, что он вспомнил отладчик С, который
может полностью оживить рабочий процесс с учетом дампа ядра. Мой gdb
не может. gdb
может позволить вам сбросить содержимое вашего OP*
и
SV*
. Вы, скорее всего, просто прочитали сбрасываемые структуры для
интерпретировать вашу структуру программы. Вы могли бы, если хотите, использовать
gdb
, чтобы сбрасывать структуры, затем синтетически создавать объекты B::*
которые вели себя в интерфейсе, как если бы они были обычными и использовали
B::Deparse
. У корня, наш депаратор и другое отладочное захоронение
инструменты в основном ориентированы на объекты, поэтому вы можете просто "обмануть" их
создавая кучу поддельных классов и объектов B::*
.
Вы можете найти метод B:: Deparse class coderef2text
поучительно. Он принимает ссылку на функцию, отбрасывает ее на B::CV
объект и использует это для ввода метода 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 );
Для более мягких представлений о OP*
и связанных с ними идеях см. обновленный
PerlGuts Illustrated и Оптимальные кишки.