perl - 调试复杂的 CPAN 发行版时如何定位子程序调用的源文件?

标签 perl debugging tk

我正在尝试调试 Tk 程序一段时间。问题似乎与来自顶级窗口的 deiconify() 调用有关,但是我无法找到定义 deiconify() 子的源文件。这是一个虚构的例子,只是为了说明我的意思:

test.pl :

use strict;
use warnings;
use Tk;

my $mw = MainWindow->new( -title => "Main Window" );
$mw->Label(-text => "Debugging", -font => "Times 20")->pack( );
$mw->Button(
    -text    => 'Quit',
    -command => sub { exit },
)->pack;
$mw->Button(
    -text    => 'Show window',
    -command => \&show_window,
)->pack;

my $tl = $mw->Toplevel( -title => "Toplevel 1" );
$tl->Button(
    -text    => 'Quit',
    -command => sub { exit },
)->pack;
$tl->withdraw();
MainLoop;

sub show_window {
    #$DB::single = 1;
    $tl->deiconify();  # <--- Where is this sub defined??
    $tl->raise();
}

我首先尝试 grep 子名称 1 的分布:
  • find . -name '*.pm' -exec grep -Hn deiconify {} \;
  • find . -name '*.xs' -exec grep -Hn deiconify {} \;
  • find . -name '*.al' -exec grep -Hn deiconify {} \;
  • find . -name '*.h' -exec grep -Hn deiconify {} \;

  • 然后我尝试在调试器下运行脚本
    perl -d test.pl
    

    并在调用 $tl->deiconify() 之前设置一个断点(见上文)。当我在断点处按下 s
      DB<1> s
    Tk::Submethods::CODE(0x56245540c658)(/home/hakon/perlbrew/perls/perl-5.24.1/lib/site_perl/5.24.1/x86_64-linux/Tk/Submethods.pm:37):
    37:      *{$package.'::'.$sub} = sub { shift->$fn($sub,@_) };
    

    它显示了 deiconify() 被定义为匿名子例程的行(第 37 行 Tk::Submethods ),但是当我再次按 s 进入匿名子例程时,它只是跳过它并返回到 test.pl 中的第 32 行。

    我怀疑该方法必须以某种方式在 Tk::wm 中定义(因为它与窗口管理器有关)可能是通过自动加载机制还是通过 dynaloader?

    脚注

    1. 命令是从 Tk 发行版的顶级目录运行的。要设置它,首先运行它:
     cpan -g Tk
     tar zxvf Tk-804.033.tar.gz
     cd Tk-804.033
    

    最佳答案

    更自由地查找源代码(特别包括 *.c 文件)找到字符串 This procedure is invoked to process the "wm deiconify" Tcl command在文件 pTk/mTk/win/tkWinWm.c .在介绍 C 函数的评论中 WmDeiconifyCmd ,这看起来肯定是该功能的实际实现。

    我没有费心去研究 Tk 模块 XS 代码是如何将 C 函数暴露给 Perl 级别的,但如果这是你真正感兴趣的,你现在知道端点并且只需要填写中间:- )

    一旦函数暴露于 Perl 级别,Tk::Submethods 中的行您在上面引用的内容显然是它被注入(inject)适当符号表的位置,因此可以通过 $tl->deiconify() 调用它.

    关于perl - 调试复杂的 CPAN 发行版时如何定位子程序调用的源文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43241579/

    相关文章:

    perl - 有条件地将元素包含在列表中的最佳方法是什么?

    c - 将 Zed Shaw 的调试宏移植到 MSVC

    java - JBoss 4.2 - 同一 JBoss 上的多个应用程序处于 Debug模式?

    tcl - 在 tcl/tk 子窗口中,我无法为我的条目小部件设置默认值

    PHP/Perl 代码从任意 TSV 文件创建 mysql 表

    apache - 无法在 @INC 中找到模块 main 的可加载对象

    windows - 我发现了 Windows 错误吗?

    perl - 限制滚动条长度

    perl - 如何将Cygwin的perl版本从5.22降级到5.14?