Skip to content

Add Config::DEBUGGING to test perl was built with DEBUGGING defined - #24784

Merged
tonycoz merged 2 commits into
Perl:bleadfrom
tonycoz:internals-debugging
Sep 23, 2026
Merged

tonycoz merged 2 commits into
Perl:bleadfrom
tonycoz:internals-debugging

Conversation

@tonycoz

@tonycoz tonycoz commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

This is one possible implementation, others might be:

  • builtin::is_debug_build (or some other name)
  • ${^DEBUGGING}

both of which use a more public namespace, but Internals::DEBUGGING seemed the least disruptive for now.

This was inspired by #24762, but it's an issue that has come up before - someone writes a test conditional on whether perl was built with -DDEBUGGING or its platform specific invocation (MSWin32, VMS), and that conditional is incomplete or incorrect.

The idea here is to add an authoritative and always correct way to check whether perl itself was builtin with DEBUGGING enabled - by checking whether universal.c has the DEBUGGING macro defined. This should also work where a debugging build perl binary is parallel installed with a non-debugging build, as with debugperl binary installed by the perl-debug package on Debian.

We could suggest parsing Internals::V, and the test code for this change does that, but Internals::V is subject to any changes needed for Config::_V() so it's fragile.

The main type of feedback in addition to the implementation that I'm looking for, is should this be public? If public, what shape should that public-ness take - a builtin:: name? a ^ variable? Or document Internals::DEBUGGING?

I'm not fond of putting this into builtin:: - those names are intended to become builtins at some point, and this doesn't seem suitable for that.


  • This set of changes may require a perldelta entry, depending on whether we add a public interface.

@jkeenan

jkeenan commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Given that right now I can type perldoc Internals and read about various functions, it seems to me that Internals::<anything> is just as public now as builtin:: or `${^DEBUGGING}.

OTOH, farther down perldoc Internals says this:

BEWARE: This module is DANGEROUS!

DO NOT attempt to unlock Perl's built-in variables!

DO NOT manipulate reference counts unless you know exactly what you're
doing!

ANYTHING might happen! Hell might break loose! ":-)"

YOU HAVE BEEN WARNED!

... which sounds like, "We're showing you the rope with which you can hang yourself, but if you use it the Secretary will disavow all knowledge of your activity."

I know that as a person working on the tests found in the core distribution, I need a definitive way to determine whether a given executable is a debugging perl or not, and I need that to work with miniperl and inside programs where the tests are run via t/test.pl. But do non-core Perl users need it?

@xenu

xenu commented Sep 1, 2026 •

Copy link
Copy Markdown
Member

Why not put this in a %Config key? e.g. $Config{debugging}

@xenu

xenu commented Sep 1, 2026

Copy link
Copy Markdown
Member

Nevermind, Debian's debugperl wouldn't be compatible with it. What an odd setup to support, BTW.

@haarg

haarg commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

It feels like this would make more sense as a %Config entry. Config_heavy.pl already has code to update %Config entries based on Internals::V.

@richardleach

Copy link
Copy Markdown
Contributor

I like the correctness of the implementation; not sure about if/how to expose it publicly.

If it is useful to people, then might we end up exposing more build details in the future? If so, not sure we'll want to ^ variables for each of them.

If it does go into Internals (or builtin), is this a good time to consider second level namespaces?

@tonycoz

tonycoz commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

It feels like this would make more sense as a %Config entry. Config_heavy.pl already has code to update %Config entries based on Internals::V.

Config seems like a good place to put it, assuming the value depends on the perl binary rather than the canned config.

Rather than a %Config entry (I tend to think of these as mirroring config.sh), how about as a constant sub in Config::?

and I need that to work with miniperl

Do you need it before Config.pm is built? Since that isn't necessarily available for minitest for example.

and inside programs where the tests are run via t/test.pl.

I'm not sure if you meant this to be "where tests are not run via t/test.pl" in addition to use in t/test.pl tests.

But do non-core Perl users need it?

I think it could be useful for XS authors

@jkeenan

jkeenan commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

The following test files are all run during make minitest -- i.e., they
are not skipped -- and they all have code that asks if they're being run by
a debugging build of perl.

  • t/op/aassign.t
272 SKIP: {
273     use Config;
274     # debugging builds will detect this failure and panic
275     skip "DEBUGGING build" if $::Config{ccflags} =~ /(?<!\S)-DDEBUGGING(?!\S)/
276                               or $^O eq 'VMS' && $::Config{usedebugging_perl} eq 'Y';
  • t/op/glob.t
  9 use Config;
 10 my $is_debugging_build = $Config{config_args} =~ /\bDDEBUGGING\b(*nla:=none)/;
...
154 SKIP: {
155     skip "Debugging builds on Linux and Cygwin still problematic: GH 16869", 1
156         if (
157             ($Config{osname} eq 'linux' or $Config{osname} eq 'cygwin') and
158             $is_debugging_build
159         );
  • t/op/signatures.t
1611 SKIP: {
1612     use Config;
1613     skip "DEBUGGING build required", 1
1614         unless $Config{ccflags} =~ /(?<!\S)-DDEBUGGING(?!\S)/
1615             || $^O eq "VMS" && $Config{usedebugging_perl} eq "Y";
1616 
  • t/run/runenv_hashseed.t
250         SKIP: {
251             # skip these tests if we are not running in a DEBUGGING perl.
252             skip "$descr not testing rand bits, not a DEBUGGING perl", 3
253                 if @$rand_bits1 + @$rand_bits2 == 0;
254 
  • t/run/todo.t
106 my $is_debugging_build = $Config{config_args} =~ /\bDDEBUGGING\b(*nla:=none)/;
...
296 TODO: {
297     todo_skip "Test needs -DDEBUGGING", 1 unless $is_debugging_build;
298     local $::TODO = 'GH 16522';
...
306 TODO: {
307     todo_skip "Test needs -DDEBUGGING", 1 unless $is_debugging_build;
308     local $::TODO = 'GH 16863';
...
322 TODO: {
323     todo_skip "Test needs -DDEBUGGING on Linux and on Cygwin, no miniperl", 1
324         unless (
325             $is_debugging_build and
326             ($Config{osname} eq 'linux' or $Config{osname} eq 'cygwin') and
327             ! is_miniperl()
328         ); 
329     local $::TODO = 'GH 16869';
...
337 TODO: {
338     todo_skip "Test needs -DDEBUGGING", 1 unless $is_debugging_build;
339     local $::TODO = 'GH 16876';

There may be others. I didn't look at tests under dist/, ext/ or lib/.

@tonycoz

tonycoz commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

The following test files are all run during make minitest -- i.e., they
are not skipped -- and they all have code that asks if they're being run by
a debugging build of perl.

The thing is: minitest isn't meant to require that Config.pm ls loadable, minitest_prep:

minitest_prep: $(MINIPERL_EXE)
        -@test -f lib/Config.pm || $(MAKE) lib/Config.pm $(unidatafiles)
        @echo " "
        @echo "You may see some irrelevant test failures if you have been unable"
        @echo "to build lib/Config.pm, or the Unicode data files."
        @echo " "
        cd t && (rm -f $(PERL_EXE); $(LNS) ../$(MINIPERL_EXE) $(PERL_EXE))

will try to build Config.pm, but even if that fails it will try to run the tests.

So ideally tests in MINITEST_TESTS:

MINITEST_TESTS = base/*.t comp/*.t cmd/*.t run/*.t io/*.t re/*.t opbasic/*.t op/*.t uni/*.t perf/*.t

should avoid a hard requirement on Config.pm.

Though we don't follow that well except for base, comp and cmd.

From what you've listed it looks like we don't really need it before Config.pm.

Comment thread configpm Outdated
@demerphq

Copy link
Copy Markdown
Collaborator

I vote that you rename it and put it in builtin.

Internals should only be for things we really dont want people to use and which we expect to remove or change in the future (even if that future might be distant).

IMO something like this will always be useful so put it in builtin.

@richardleach

Copy link
Copy Markdown
Contributor

I vote that you rename it and put it in builtin.

Internals should only be for things we really dont want people to use and which we expect to remove or change in the future (even if that future might be distant).

IMO something like this will always be useful so put it in builtin.

I still wonder if there should be a sub-namespace, making it builtin::<something>::DEBUGGING, rather than having to worry about having a crowded top-level some years hence?

@Grinnz

Grinnz commented Sep 16, 2026 •

Copy link
Copy Markdown
Contributor

A sub-namespace would essentially be a core module with different rules; though it could follow the conventions of builtin intuitively.

Personally I think one clearly-named function for this in builtin would be fine, there is little chance of it being confusing. I don't think "these names are intended to become builtins at some point" is correct, builtin.pm is where they are intended to live for the forseeable future because the core namespace cannot gain new keywords. The only future implication would be if they get added to a 'builtin bundle', which for a function like this is unnecessary.

But Config seems like an appropriate place for this sort of thing as well.

@tonycoz tonycoz changed the title Add Internals::DEBUGGING to test perl was built with DEBUGGING defined Add Config::DEBUGGING to test perl was built with DEBUGGING defined Sep 16, 2026
@tonycoz

tonycoz commented Sep 16, 2026

Copy link
Copy Markdown
Contributor Author

Internals should only be for things we really dont want people to use and which we expect to remove or change in the future (even if that future might be distant).

The title was out of date, I moved it to Config later.

As to builtin - the names defined in builtin are intended to be included in a later version bundle once they become non-experimental, from perldoc builtin:

Version Bundles

The entire set of builtin functions that were considered non-experimental by a version of perl can be imported all at once, by requesting a version bundle. This is done by giving the perl release version (without its subversion suffix) after a colon character:

   use builtin ':5.40';

which means they become part of any package namespace that does:

use v5.48.0; # some version, maybe not this one

Though perhaps we be inconsistent and skip that for DEBUGGING.

I still wonder if there should be a sub-namespace, making it builtin::<something>::DEBUGGING, rather than having to worry about having a crowded top-level some years hence?

It doesn't really work with the way builtin names are intended to be promoted to being directly visible under some use v... in the future.

As to builtin, I wouldn't mind a way to use v5.xx and not get the builtin bundle imported - for line of business code I'm unlikely to use any of blessed, reftype, created_as_string/number, is_tainted, export_lexically, is_bool, unweaken, is_weak, load_module. But that should probably be discussed elsewhere.

@richardleach

Copy link
Copy Markdown
Contributor

It doesn't really work with the way builtin names are intended to be promoted to being directly visible under some use v... in the future.

As to builtin, I wouldn't mind a way to use v5.xx and not get the builtin bundle imported - for line of business code I'm unlikely to use any of blessed, reftype, created_as_string/number, is_tainted, export_lexically, is_bool, unweaken, is_weak, load_module. But that should probably be discussed elsewhere.

Fair enough.

(That promotion model does make picking-names-to-minimize-collisions more difficult. ☹️ )

@Grinnz

Grinnz commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Internals should only be for things we really dont want people to use and which we expect to remove or change in the future (even if that future might be distant).

The title was out of date, I moved it to Config later.

As to builtin - the names defined in builtin are intended to be included in a later version bundle once they become non-experimental, from perldoc builtin:

Version Bundles

The entire set of builtin functions that were considered non-experimental by a version of perl can be imported all at once, by requesting a version bundle. This is done by giving the perl release version (without its subversion suffix) after a colon character:

   use builtin ':5.40';

which means they become part of any package namespace that does:

use v5.48.0; # some version, maybe not this one

Though perhaps we be inconsistent and skip that for DEBUGGING.

I suppose we could decide whether this is acceptable at a future time if it comes up. I think it's consistent with feature.pm to leave some builtins "optional".

I still wonder if there should be a sub-namespace, making it builtin::<something>::DEBUGGING, rather than having to worry about having a crowded top-level some years hence?

It doesn't really work with the way builtin names are intended to be promoted to being directly visible under some use v... in the future.

As to builtin, I wouldn't mind a way to use v5.xx and not get the builtin bundle imported - for line of business code I'm unlikely to use any of blessed, reftype, created_as_string/number, is_tainted, export_lexically, is_bool, unweaken, is_weak, load_module. But that should probably be discussed elsewhere.

I view it as part of the use VERSION contract: you are asking for a new "version" of perl, which has these keywords and functions available. I think it is straightforward enough to piecemeal the parts you want (since they are all default invocations), especially as part of something like Import::Base. But I would probably not be opposed to more options if there's an elegant way to do it. But now we're getting very off topic.

@demerphq

demerphq commented Sep 17, 2026 via email

Copy link
Copy Markdown
Collaborator

@Grinnz

Grinnz commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

To avoid continuing this off topic discussion, I will just note that builtin::compat does exist, and "use VERSION" working that way is a tradeoff not specific to builtin.pm, which I think is the correct one.

@tonycoz
tonycoz force-pushed the internals-debugging branch from 019d4eb to 8729493 Compare September 21, 2026 22:52
@tonycoz
tonycoz merged commit f9bdd9d into Perl:blead Sep 23, 2026
33 checks passed
Comment thread lib/unicore/mktables
sub DEBUG () { 0 } # Set to 0 for production; 1 for development
$| = 1 if DEBUG;
my $debugging_build = $Config{"ccflags"} =~ /-DDEBUGGING/;
my $debugging_build = Config::DEBUGGING;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does mean that mktables currently doesn't can't run with an older perl, and it does look like it was meant to be able to do that (it explicitly requires only 5.10.1)

@khwilliamson

khwilliamson commented Sep 25, 2026 via email

Copy link
Copy Markdown
Contributor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants