below find a patch for dynaloader that stores the names of the shared objects that are
loaded into perl. Its intended for use with PAR (for run time detection of shared objects
rather than compile time analysis)
If its unacceptable, let me know either what it dups, or a preferred method of getting
this info..
Thanks,
Ed
----
apply with patch -p1 -d :perldir: < patch
----
diff -rc perl-5.8.1/ext/DynaLoader/DynaLoader_pm.PL perl-5.8.1.new/ext/DynaLoader/DynaLoader_pm.PL
*** perl-5.8.1/ext/DynaLoader/DynaLoader_pm.PL Sat Sep 13 10:14:41 2003
--- perl-5.8.1.new/ext/DynaLoader/DynaLoader_pm.PL Tue Nov 18 23:39:39 2003
***************
*** 80,85 ****
--- 80,86 ----
my $Mac_FS;
$Mac_FS = eval { require Mac::FileSpec::Unixish } if $Is_MacOS;
+ @dl_shared_objects = (); # shared objects for symbols we have
@dl_require_symbols = (); # names of symbols we need
@dl_resolve_using = (); # names of files to link with
@dl_library_path = (); # path to look for files
***************
*** 328,335 ****
boot:
my $xs = dl_install_xsub("${module}::bootstrap", $boot_symbol_ref, $file);
-
# See comment block above
&$xs(@args);
}
--- 329,338 ----
boot:
my $xs = dl_install_xsub("${module}::bootstrap", $boot_symbol_ref, $file);
# See comment block above
+
+ push(@dl_shared_objects, $file); # record files loaded
+
&$xs(@args);
}
***************
*** 548,553 ****
--- 551,557 ----
$dl_debug
@dl_librefs
@dl_modules
+ @dl_shared_objects
Implemented in:
bootstrap($modulename) Perl
@filepaths = dl_findfile(@names) Perl
***************
*** 622,627 ****
--- 626,635 ----
=item @dl_modules
An array of module (package) names that have been bootstrap'ed.
+
+ =item @dl_shared_objects
+
+ An array of file names for the shared objects that were loaded.
=item dl_error()
> *** perl-5.8.1/ext/DynaLoader/DynaLoader_pm.PL Sat Sep 13 10:14:41 2003
> --- perl-5.8.1.new/ext/DynaLoader/DynaLoader_pm.PL Tue Nov 18 23:39:39 2003
> ***************
> *** 80,85 ****
> --- 80,86 ----
> my $Mac_FS;
> $Mac_FS = eval { require Mac::FileSpec::Unixish } if $Is_MacOS;
>
> + @dl_shared_objects = (); # shared objects for symbols we have
Shouldn't this be :shared among threads ?
Or better : to avoid the overhead of loading attributes.pm on non-threaded
perls, shouldn't this be :shared only for threaded perls ? (as DynaLoader.pm
is generated at compile time and installed into archlib)
Hopefully all those vars are documented :)
Another problem : your patch doesn't record the shared objects loaded via XSLoader.
I just followed the coding conventions inside of DynaLoader_pm.PL as they stood..
None of the other globals in that are :shared, so I was assuming that this one wasn't.
Perhaps a revisit of DynaLoader_pm.PL is in order (by someone who has a little more
knowledge in the ins and outs of threaded perl)..
Ed
Does not look too bad.
How do you use these paths?
There is already @dl_librefs for finding by symbol.
Also you can get the file names like this (which is messy):
foreach my $mod (@DynaLoader::dl_modules)
{
require strict;
strict::->unimport('refs');
next if $mod eq 'B';
if (defined &{$mod.'::bootstrap'})
{
my $boot = \&{$mod.'::bootstrap'};
my $cv = B::svref_2object($boot);
# Copied from XSLoader
my @modparts = split(/::/,$mod);
my $modfname = $modparts[-1];
my $modpname = join('/',@modparts);
my $modlibname = $INC{"$modpname.pm"};
my $c = @modparts;
$modlibname =~ s,[\\/][^\\/]+$,, while $c--; # Q&D basename
my $file = "$modlibname/auto/$modpname/$modfname.$Config{'dlext'}";
unless (-r $file)
{
foreach my $dir (@INC)
{
$file = "$dir/auto/$modpname/$modfname.$Config{'dlext'}";
last if -r $file;
}
}
print "#Load $mod $file\n";
}
You may be able to get file from CvFILE or GvFILE which results from
the newXSUB() in dl_install_xsub the compiler module B::C used to do that.
Apache::Status gets the filename via:
my $obj = B::svref_2object(*$name{CODE});
my $file = $obj->can('FILEGV') ? $obj->FILEGV->SV->PV : $obj->FILE;
Though in some cases for bootstrap() inherited from Dynaloader $obj->FILE
returns a corrupted filename (some garbage).
__________________________________________________________________
Stas Bekman JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide ---> http://perl.apache.org
mailto:st...@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org http://ticketmaster.com
I wondered if that is what you were doing.
>
>>
>> foreach my $mod (@DynaLoader::dl_modules) { require strict; print "#Load
>> $mod $file\n"; }
>
>I'm not sure - is this truly equivalent to what the patch does?
Not exactly - but it is close.
I use it in my module which "packs files into a standalone executable".
>I'm thinking
>of Inline which gets loadable module names on the fly.. In any case, IMO its a
>bit cleaner to just look at an array..
Cleaner perhaps - but scheme I posted works with stock perl back to
to at least perl5.005_03.
Thanks - now I see that I can see why I didn't remember the incantation.
>
>Though in some cases for bootstrap() inherited from Dynaloader $obj->FILE
>returns a corrupted filename (some garbage).
I recall that too - which is why I switched to the code which replicates
DynaLoader's search for the loadable.
This may explain why:
http://nntp.perl.org/group/perl.perl5.porters/79650
(and of course, there's not only the spot in toke.c where that happens)
I gave up when I became aware that any real fix will break
binary compatibility.
Fortunately this an ithreads-only issue :-)
Regards,
Adi
Are you sure? -
>
>Regards,
>Adi
well, if you want to pack up files into a standalone executable (by observing what
happens at runtime), the easiest thing to note what you find, and store it in an
array for later usage.
>
> foreach my $mod (@DynaLoader::dl_modules)
> {
> require strict;
> strict::->unimport('refs');
> next if $mod eq 'B';
> if (defined &{$mod.'::bootstrap'})
> {
> my $boot = \&{$mod.'::bootstrap'};
> my $cv = B::svref_2object($boot);
>
> # Copied from XSLoader
> my @modparts = split(/::/,$mod);
> my $modfname = $modparts[-1];
> my $modpname = join('/',@modparts);
> my $modlibname = $INC{"$modpname.pm"};
> my $c = @modparts;
> $modlibname =~ s,[\\/][^\\/]+$,, while $c--; # Q&D basename
> my $file = "$modlibname/auto/$modpname/$modfname.$Config{'dlext'}";
> unless (-r $file)
> {
> foreach my $dir (@INC)
> {
> $file = "$dir/auto/$modpname/$modfname.$Config{'dlext'}";
> last if -r $file;
> }
> }
> print "#Load $mod $file\n";
> }
I'm not sure - is this truly equivalent to what the patch does? I'm thinking of Inline
which gets loadable module names on the fly.. In any case, IMO its a bit cleaner
to just look at an array..
Ed
I don't see how that could happen on a non-ithreaded perl.
There CopFILE_free decrements the reference count of a global variable
in the stash (the one pointed by cop_filegv and got with gv_fetchfile).
But that shouldn't be freed until the stash itself is destroyed.
And so the gp_file from any GV should always point to valid data (the
xpv_pv field from the SV of that global variable).
Am I missing something ?
Regards,
Adi