Trouble writing a simple tracer using the DB package (loops endlessly)
1 direct reply — Read more / Contribute
|
by clueless newbie
on Oct 10, 2025 at 11:18
|
|
|
Greeting Monks,
I’m experimenting with using the built-in `DB` package to build a lightweight call tracer. I’ve previously done something similar using **Hook::LexWrap** and **Module::Info**, but this time I’d like to catch **entry and exit** events for subroutines directly through Perl’s built-in debugging interface.
Here’s the minimal prototype I’ve tried:
+
package Devel::Lite;
use strict;
use warnings;
use Time::HiRes ();
our $IN_TRACE = 0;
sub DB::sub {
return &$DB::sub(@_) if $IN_TRACE;
local $IN_TRACE = 1;
my $sub = $DB::sub;
my @args = @_;
print STDERR ">> entering $sub\n";
my @ret;
eval { @ret = &$sub(@args); };
print STDERR "<< leaving $sub\n";
die $@ if $@;
return wantarray ? @ret : $ret[0];
}
1;
Then I run it like this:
perl -I. -d:TobyLite -e "sub x { print qq{okay\n}; } x();"
…but it loops endlessly and never reaches my test sub.
If I insert a print inside the loop, I see repeated `"Time::HiRes::time"`, suggesting recursion into the debugger hook itself.
I’ve tried things like skipping `Devel::Lite` and `Time::HiRes` calls explicitly, and guarding with `$IN_TRACE`, but the loop persists.
What I’d like to understand is:
1. Why is `DB::sub` being triggered recursively despite the guard?
2. What’s the correct minimal pattern for tracing sub entry/exit safely?
3. Bonus: how best to distinguish user code from CPAN/core subs to keep the trace clean?
Environment:
This is perl 5.38.x built for MSWin32-x64-multi-thread
Running on Windows 10.
Any insight or examples would be appreciated — I’m not trying to build a full debugger, just a simple tracer that logs the call tree.
TIA
PS: So far this has stumped (in no order) ChatGPT, claude, and Gemini.
|
Are beheaded strings known to be slow?
3 direct replies — Read more / Contribute
|
by Anonymous Monk
on Oct 09, 2025 at 13:57
|
|
|
I know Perl maintains a pointer (offset), within an SV, of where actual data in PV buffer starts, -- is this "beheading" the reason for the slowdown as demonstrated?
use strict;
use warnings;
use Benchmark 'cmpthese';
my $str = ' ' x 1e5;
sub test1 {
my $s = shift;
my $copy = substr $str, 1;
1 while $copy =~ /./g;
_:
}
sub test2 {
my $s = shift;
substr $s, 0, 1, '';
1 while $s =~ /./g;
_:
}
cmpthese -1, {
test1 => sub { test1( $str )},
test2 => sub { test2( $str )},
};
# (warning: too few iterations for a reliable count)
# Rate test2 test1
# test2 2.79/s -- -93%
# test1 41.0/s 1372% --
|
What do I use for the callback function in Net::LDAP::Control::Paged?
1 direct reply — Read more / Contribute
|
by adamsj
on Oct 07, 2025 at 16:20
|
|
|
|
|
CygPerl question: what to expect from update when Cygwin releases 5.42
1 direct reply — Read more / Contribute
|
by Intrepid
on Oct 06, 2025 at 13:44
|
|
|
Hello perMonks and perlNuns.
As my Subject indicates, I am thinking ahead to when the cygwin project upgrades
Perl to 5.42. What I am asking isn't about the Perl language but rather about
systems administration. I got badly burned by doing something ignorant awhile back,
as discussed weeks ago in Nooo!... Have I trashed my Strawberry?.
When I update using cygwin setup.exe, I think I remember that the core language modules will
not update, but rather are updated as a separate package from cygwin.com (is this right?).
And what about the vendor modules? But mostly, what about the modules in site_perl
locations, modules I've built and installed myself? I think one answer will be
to autobundle using cpan, but there are other possible solutions. Any advice would
be welcomed.
CygwinPerl on my system:
$ /usr/bin/perl -le 'print $^V'
v5.40.3
My @INC looks like this:
$ perl -le 'print for @INC'
/usr/local/lib/perl5/site_perl/5.40/x86_64-cygwin-threads
/usr/local/share/perl5/site_perl/5.40
/usr/lib/perl5/vendor_perl/5.40/x86_64-cygwin-threads
/usr/share/perl5/vendor_perl/5.40
/usr/lib/perl5/5.40/x86_64-cygwin-threads
/usr/share/perl5/5.40
So when one autobundles, are modules selected from all dirs in @INC or only from
the site_perl dirs, which are in my case (and presumably in all CygwinPerl users cases):
/usr/local/lib/perl5/site_perl/5.40/x86_64-cygwin-threads
/usr/local/share/perl5/site_perl/5.40
Or does autobundle select everything, including core modules and vendor modules? If it
does, I want a better solution.
Answers I got to that posting about trashing StrawberryPerl included this notable
one: Re: Nooo!... Have I trashed my Strawberry?. I am going to look
into the recommended UrBackup while I am awaiting advice here.
Oct 06, 2025 at 17:34 UTC
A just machine to make big decisions
Programmed by fellows (and gals) with compassion and vision
We'll be clean when their work is done
We'll be eternally free yes, and eternally young
Donald Fagen —> I.G.Y.
(Slightly modified for inclusiveness)
|
Help taking over maintainership of a CPAN module
1 direct reply — Read more / Contribute
|
by MADS
on Oct 06, 2025 at 07:40
|
|
|
Hello
I’m seeking help and guidance regarding taking over maintainership of a CPAN module. I’ve been in contact with the current maintainer, and the module is no longer maintained and has stopped working due to code drift. The original maintainer has given me written consent to take over the module. However, there’s a problem — his CPAN account is registered under his old university email address, which he no longer has access to. Because of this, he can’t confirm the transfer through the usual channels.
I’ve already emailed the PAUSE administrators for assistance but haven’t received a response yet.
Does anyone have any suggestions on how to proceed?
Regards
|
Win32::OLE reading word file with tables
1 direct reply — Read more / Contribute
|
by chafelix
on Oct 04, 2025 at 15:12
|
|
|
I am reading a word file which has tables, using Win32::OLE. I am only interested in the tables. The code I use is shown below
use Win32::OLE qw(in);
use Win32::OLE::Const 'Microsoft Word';
sub print_tables {
my $word =Win32::OLE->new('Word.Application','Quit'); # shift;
my $word_file = file(abs_path(shift));
my $doc = $word->{Documents}->Open("$word_file");
my $tables = $word->ActiveDocument->{Tables};
for my $table (in $tables) {
my $numrows=$table->Rows->Count;
my $rownum=1;
while($rownum<=$table->Rows->Count){
...
$main::numcols=$table->Columns->Count;
my $cell5=$table->Cell($rownum,$main::numcols);#this is the last colum
+n
.....
}
}
}
The problem arises when the tables have merged columns, so that the number of columns is < $main::numcols
In that case I need to check and essantially say either
"if $actual_number_of_columns_in_present_row <$main::numcols){...}" or catch the exception
"(If ! $cell5 ){...}"
So the question is how do I say either of these?
|
Name a method that exposes a secret
1 direct reply — Read more / Contribute
|
by NERDVANA
on Sep 30, 2025 at 12:50
|
|
|
I have a module Crypt::SecretBuffer which prevents a scalar from being seen "unless you really want to" (ideally passing it directly to an XS function to prevent copies from being made). Right now the API for viewing the secret is using 'local' on an attribute 'stringify_mask' and an overloaded stringification on the object:
$password= secret(...);
...
local $password->{stringify_mask}= undef if ref($password) eq 'Crypt::
+SecretBuffer';
$db= DBI->connect($dsn, $user, $password, \%attr);
On Github, robrwo [suggested a new more functional-programming-like API, namely that a method of SecretBuffer would pass the secret to a callback. My thought on the matter was that the *real* missing feature is a duck-typing API that doesn't need to be specific to SecretBuffer, which should provide an easy and convenient recipe for code that doesn't have a hard dependency on SecretBuffer to gain access to secrets.
I'd like to conduct an informal poll of which design people like the best:
- "apply", a method which takes a callback of one argument:
if ($password isa 'Crypt::SecretBuffer') {
$db= $password->apply(sub { DBI->connect($dsn, $user, $_[0], \%attr)
+ });
else {
$db= DBI->connect($dsn, $user, $password, \%attr);
}
- A more distinct method name that could be used for duck-typing and apply to other types of object:
if (blessed $password && $password->can("unmask_secret_to")) {
$db= $password->unmask_secret_to(\&DBI::connect, 'DBI', $dsn, $user,
+ $password, \%attr);
} else {
$db= DBI->connect($dsn, $user, $password, \%attr);
}
- reveal_secret_to
- unmask_secret_to
- call_with_secret
- call_unmasked
- Use a scalar-ref overload:
$db= DBI->connect($dsn, $user, ref $password? $$password : $password,
+\%attr);
I just came up with that scalar-ref idea, and seems pretty safe because no code would normally scalar-dereference a ref unless the ref type was 'SCALAR'. Still, that's drastically lowering the bar for leaking the secret, and isn't advertising that it has this capability...
While pondering your preference, also consider the question "If someone contributed a patch to a module I maintain that added support for receiving secrets via SecretBuffer, how much boilerplate would I be willing to accept?"
|
google drive
3 direct replies — Read more / Contribute
|
by frank1
on Sep 25, 2025 at 16:25
|
|
|
I need help with my script uploading files to google drive
i have tried to read some modules like LWP::Authen::OAuth2, and many examples on internet but they all pointing out to 'URL for user to go to to start the process in browser', but for me am using this script in server as a background process
Anyone who can help i really appreciate
#!/usr/bin/perl - wT
use strict;
use warnings;
use LWP::UserAgent;
use LWP::Authen::OAuth2;
my $ua = LWP::UserAgent->new;
my $oauth2 = LWP::Authen::OAuth2->new(
client_id => 'client_id',
client_secret => 'client_secret',
site => 'https://accounts.google.com/o/oauth2/token',
+ # Token endpoint
authorize_url => 'https://accounts.google.com/o/oauth2/auth',
+# Authorization endpoint
redirect_uri => 'my_url_used_in_google_console_when_creating_
+client_id_and_client_secret',
);
# Use the access token to make API requests
$ua->default_header( 'Authorization' => 'Bearer ' . $oauth2->acces
+s_token );
my $url = 'https://www.googleapis.com/upload/drive/v3/files';
my $metadata = {
name => '/var/www/.../filename.sql', # Path to file in server
mimeType => 'application/txt',
};
my $response = $ua->post(
$url,
'Authorization' => 'Bearer ' . $oauth2->access_token,
'Content-Type' => 'application/json; charset=UTF-8',
'X-Upload-Content-Type' => 'application/txt',
Content => encode_json($metadata),
);
if ($response->is_success) {
print $res->decoded_content;
} else {
print $response->decoded_content;
print $response->status_line, "n";
}
|
create-modulino.pl appears in a CPAN module Makefile.PL, and nukes the install retval
1 direct reply — Read more / Contribute
|
by Intrepid
on Sep 24, 2025 at 17:11
|
|
|
Hi Monks. I would like some help gaining insight on this one. I've just been
installing dependency dists for a CPAN module and one of them
fails the make install step. Tracing the action, I see this dangling off the end of
the usual processing:
Appending installation info to D:/AllSBP\lib\perl5\MSWin32-x64-multi-t
+hread/perllocal.pod
destdir=; \
test -n "$destdir" && destdir="-d $destdir"; \
create-modulino.pl -m Module::ScanDeps::FindRequires \
-a find-requires $destdir -b D:/AllSBP\bin
'destdir' is not recognized as an internal or external command,
operable program or batch file.
gmake: *** [makefile:1006: install] Error 1
The Makefile statements that generate that look like this:
# --- MakeMaker postamble section:
#-*- mode:makefile; -*-
postamble ::
install::
destdir=$(DESTDIR); \
test -n "$$destdir" && destdir="-d $$destdir"; \
create-modulino.pl -m Module::ScanDeps::FindRequires \
-a find-requires $$destdir -b $(INSTALLSITESCRIPT)
# End.
Oh, you'd like to know which distribution this is? Of course. It's
Module::ScanDeps::Static v1.7.6.
I imagine this is a very cool thing when it works (haven't tried it on
Gnu/Linux yet). My perl setup is:
osname=MSWin32
osvers=10.0.26100.4652
archname=MSWin32-x64-multi-thread
uname='Win32 strawberry-perl 5.42.0.1 # 05:37:25 Fri August 01 2025 x64'
I know the "blah blah is not recognized as an internal or external ..." is classic
Windows, often useless in diagnosing what's really going on. This scrap of shell
script has me confused though, especially destdir="-d $$destdir". Dunno what that
does.
Although we don't see the absence of the create-modulino.pl command in the
output, it isn't in the package files and isn't installed anywhere on my
PATH.
Hope I am not wasting anyone's time. :-)
Sep 24, 2025 at 21:09 UTC
A just machine to make big decisions
Programmed by fellows (and gals) with compassion and vision
We'll be clean when their work is done
We'll be eternally free yes, and eternally young
Donald Fagen —> I.G.Y.
(Slightly modified for inclusiveness)
|
Connect to a *secure* websocket server (wss)
2 direct replies — Read more / Contribute
|
by bliako
on Sep 24, 2025 at 09:20
|
|
|
Estimado Monjees
I am looking for guidance on how to connect to a server via secure websocket (wss) using perl, at as high level as possible, using a module preferably. My browser initiates this connection with this header Sec-WebSocket-Key: which is base64-encoded binary data. My interaction with it would be mostly reading what it periodically sends.
I have looked AnyEvent::WebSocket::Connection and Net::Async::WebSocket::Client but they do not mention wss. Am I wrong?
Whereas Mojo::UserAgent does support wss (it says), and allows for headers to be passed on but alas it fails. I used something like this:
use strict;
use warnings;
use Mojo::UserAgent;
my $URI = 'wss://echo.websocket.org';
my $ua = Mojo::UserAgent->new;
my $tx = $ua->build_websocket_tx($URI);
$tx->req->headers->user_agent('Mozilla/5.0 (X11; Linux x86_64) AppleWe
+bKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36');
print $tx->req->headers->to_string."\n";
$ua->start(
$tx => sub {
my ($ua, $tx) = @_;
print "Headers: ".$tx->req->headers->to_string."\n";
print "WebSocket handshake failed!\n" and
return unless $tx->is_websocket
;
print "Got a handshake\n";
$tx->on(message => sub {
my ($ua, $msg) = @_;
print "WebSocket message: $msg\n";
$tx->finish;
});
}
);
print "waiting ...\n";
outputs this:
waiting ...
UA: Mojo::UserAgent
TX: Mojo::Transaction::HTTP
WebSocket handshake failed!
I am using a test site for the target (https://ws-playground.netlify.app/) which works on the browser and I have checked it does not need extra headers/cookies. But above code fails.
10min Edit: this works (nodejs client):
wscat -c wss://echo.websocket.org -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36'
this does not (waits...) :
curl -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36' 'wss://echo.websocket.org'
|
|