Source-Changes archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

CVS commit: src/usr.bin/make/unit-tests



Module Name:    src
Committed By:   rillig
Date:           Tue Feb 23 14:17:21 UTC 2021

Modified Files:
        src/usr.bin/make/unit-tests: var-class-cmdline.exp var-class-cmdline.mk
            varmod-loop.exp varmod-loop.mk

Log Message:
make: demonstrate how to undefine variables during evaluation

For a very long time now, I had thought that it would be impossible to
undefine global variables during the evaluation of variable expressions.
This is something that the memory management in Var_Parse relies upon,
see the comment 'the value of the variable must not change'.

After several unsuccessful attempts at referring to an already freed
previous value of a variable, today I discovered how to unset a global
variable while evaluating an expression, which has the same effect.  To
demonstrate that this use-after-free can reliably crash make, it would
need a memory allocator with a debug mode that never re-allocates the
same memory block after it has been used once.  This is something that
jemalloc cannot do at the moment.  Valgrind would be another idea, but
that has not been ported to NetBSD.

Undefining a global variable while evaluating an expression is made
possible by an implementation detail of the modifier ':@'.  That
modifier undefines the loop variable, without restoring its previous
value, see ApplyModifier_Loop.

By the very old conventions of ODE Make, these loop variables are named
'.V.' and thus do not conflict with variables from other naming
conventions.  In NetBSD and pkgsrc, these loop variables are typically
called 'var', sometimes '_var' with a leading underscore, which also
doesn't conflict with the typical form 'VAR' of variables in the global
namespace.  Therefore, in practice these loop variables don't interfere
with other variables.

One case that can practically arise is when an outer variable has a
modifier ':@word@${VAR.${word}}@' and one of the referenced variables
uses the same variable name in the modifier, see varmod-loop.mk 1.10
line 91 for a detailed explanation.

By using the ${:@VAR@@} modifier in a place that is evaluated with
cmdline scope, it is not only possible to undefine global variables, it
is possible to undefine cmdline variables as well.  When evaluated in a
specific make target, the expression ${:@\@@@} can even be used to
undefine the variable '.TARGET', which will probably crash make with an
assertion failure.


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/usr.bin/make/unit-tests/var-class-cmdline.exp
cvs rdiff -u -r1.3 -r1.4 src/usr.bin/make/unit-tests/var-class-cmdline.mk
cvs rdiff -u -r1.5 -r1.6 src/usr.bin/make/unit-tests/varmod-loop.exp
cvs rdiff -u -r1.9 -r1.10 src/usr.bin/make/unit-tests/varmod-loop.mk

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.




Home | Main Index | Thread Index | Old Index