为什么%main ::符号表中有几个c文件?

时间:2011-06-25 03:56:59

标签: perl

'_<perlmain.c' => *{'::_<perlmain.c'},
'_</usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi/auto/Data/Dumper/Dumper.so' => *{'::_</usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi/auto/Data/Dumper/Dumper.so'},
'_<universal.c' => *{'::_<universal.c'},
'_<xsutils.c' => *{'::_<xsutils.c'},
...

为什么它们在%main::的符号表中,它们何时有用?

2 个答案:

答案 0 :(得分:2)

要重复问题的输出,请运行

#! /usr/bin/env perl
use Data::Dumper;
print Dumper \%main::;

您看到的条目会插入gv_fetchfile_flags

/* This is where the debuggers %{"::_<$filename"} hash is created */
tmpbuf[0] = '_';
tmpbuf[1] = '<';
memcpy(tmpbuf + 2, name, namelen);
gv = *(GV**)hv_fetch(PL_defstash, tmpbuf, tmplen, TRUE);
if (!isGV(gv)) {
    gv_init(gv, PL_defstash, tmpbuf, tmplen, FALSE);
#ifdef PERL_DONT_CREATE_GVSV
    GvSV(gv) = newSVpvn(name, namelen);
#else
    sv_setpvn(GvSV(gv), name, namelen);
#endif
}

newXS作为boot process in S_parse_body的一部分,通过Debugger Internals多次调用。

boot_core_PerlIO();
boot_core_UNIVERSAL();
boot_core_mro();

请注意,您还会在输出中看到perlio.cuniversal.cmro.c的条目。

perldebguts documentationperlvar部分解释了它们的使用:

  

例如,每当从包DB调用Perl的内置调用函数时,调用相应堆栈帧的参数将被复制到@DB::args数组。通过使用-d开关调用Perl来启用这些机制。具体而言,启用了以下附加功能(参见{{3}}中的$^P):

     
      
  • ...
  •   
  • 每个数组@{"_<$filename"}都包含由{Perl编译的文件的$filename行。对于包含子例程或当前正在执行的字符串的evaled字符串也是如此。变形字符串的$filename看起来像(eval 34)。正则表达式中的代码断言看起来像(re_eval 19)
  •   
  • 每个哈希%{"_<$filename"}包含由行号键入的断点和操作。单个条目(与整个哈希相对)是可设置的。虽然perl5db.pl使用的值的格式为"$break_condition\0$action",但Perl在此处仅关注布尔值true。   对于包含子例程的计算字符串或当前正在执行的字符串,这同样适用。 evaled字符串的$ filename看起来像(eval 34)或(re_eval 19)。
  •   
  • 每个标量${"_<$filename"}都包含"_<$filename"。对于包含子例程或当前正在执行的子例程的计算字符串也是如此。已证实字符串的$filename看起来像(eval 34)(re_eval 19)
  •   
  • 在编译每个所需文件之后,但在执行之前,如果子例程DB::postponed(*{"_<$filename"})存在,则调用DB::postponed。在此处,$filename是所需文件的扩展名称,可在%INC的值中找到。
  •   
  • ...
  •   

答案 1 :(得分:1)

由于perl是一种基于解释器的语言,因此需要他的解释器,即perl二进制文件。这个二进制文件只读取perl脚本,并通过在机器代码中进行转换来执行代码。

您的perl解释器是使用调试符号编译的,因此它包含有关其构建的源文件的信息。您还可以在示例中看到已加载模块Data::Dumper的对象。

希望有所帮助