5

I am trying to debug a Tk program for a while now. The problem seems to be with a deiconify() call from a top level window, however I am not able to locate the source file where the deiconify() sub is defined. Here is a made-up example just to illustrate what I mean:

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();
}

I first tried to grep the distribution for the sub name1:

  • 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 {} \;

Then I tried to run the script under the debugger

perl -d test.pl

and set a breakpoint just before the call to $tl->deiconify() (see above). When I pressed s at the breakpoint

  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,@_) };

it shows the line where deiconify() was defined as anonymous subroutine ( Line 37 of Tk::Submethods ), but when I press s again to step into the anonymous subroutine, it just step over it and returns to line 32 in test.pl.

I suspect the method must be defined in Tk::wm somehow (since it is related to the Window manager) maybe by the auto load mechanism or by dynaloader?

Footnotes

1. The commands was run from the toplevel directory of the Tk distribution. To set it up, run this first:

 cpan -g Tk
 tar zxvf Tk-804.033.tar.gz
 cd Tk-804.033

Håkon Hægland
  • 39,012
  • 21
  • 81
  • 174
  • That line is being shown because it's the code for the `deiconify` method: it is converted into a call to the method named by `$fn` that passes `$sub` (presumably the string `"deiconify"`) as the first parameter. It's presumably XS code if the debugger isn't showing it. What is in `$fn` at that point? – Borodin Apr 05 '17 at 21:15
  • @Borodin `$fn` is equal to `wm` as far as I can see – Håkon Hægland Apr 05 '17 at 21:16

1 Answers1

2

Grepping the source a little more liberally (specifically including *.c files) finds the string This procedure is invoked to process the "wm deiconify" Tcl command in the file pTk/mTk/win/tkWinWm.c. It's in a comment introducing the C function WmDeiconifyCmd, which certainly looks like it's the actual implementation of that functionality.

I haven't bothered to look into exactly how the Tk module XS code exposes that C function to the Perl level, but if that's what you're really interested in, you now know the endpoints and just have to fill in the middle :-)

Once the function is exposed to the Perl level, the line in Tk::Submethods that you quote above is clearly where it gets injected into the appropriate symbol table so it can be called via $tl->deiconify().

Calle Dybedahl
  • 5,228
  • 2
  • 18
  • 22