ysth попросил меня прокомментировать ваш вопрос в IRC. Я сделал целый
куча вещей "разборка" скомпилированных Perl и прочее (только посмотрите мой
CPAN страница [http://search.cpan.org/~jjore]).
Perl компилирует ваш источник в дерево OP*
структур, которые
иногда есть указатели 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::*
, использующий код, должен действительно работать
на живую память. Тай МакКвин думал, что он помнил отладчик C, который
может полностью восстановить рабочий процесс с учетом дампа ядра. Мой gdb
не может. gdb
может позволить вам сбросить содержимое вашего OP*
и
SV*
структуры. Скорее всего, вы просто прочитали бы
интерпретировать структуру вашей программы. Вы могли бы, если хотите, использовать
gdb
чтобы выгрузить структуры, затем синтетически создать B::*
объекты
который вел себя в интерфейсе, как будто они были обычными и используют
B::Deparse
на этом. В корне наш депарсер и прочий отладочный дамп
инструменты в основном объектно-ориентированные, так что вы можете просто "обмануть" их
создание кучи поддельных B::*
классов и предметов.
Вы можете найти чтение метода coderef2text
класса B :: Deparse
поучительно. Он принимает ссылку на функцию, приводит ее к 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 и Optree Guts .