This came up after #12036 and #12014 while trying to implement the proposed solution for those issues. The solution to those issues will, ostensibly, involve liberal calls to Import-Module within modules during module loading to shadow the names of commands such that name resolution occurs in module and not global scope. In practice I have found that there are scenarios where such liberal use of Import-Module causes stack overflows. Some such stack overflows are the result of straightforward cyclic calls to Import-Module. This one is slightly different as it is apparently acyclic.
One module affected by this is (a later, internal version of) StructuredResource. The culprit seems to be these lines which validate that the DSC resource module imports without error. A DSC resource that requires StructuredResource is also tested by and therefore imported by StructuredResource. I suspect this is an unusual perhaps inadvisable use case, but I'd still like to understand what is happening so I can conclusively work around the stack overflow.
This leaves me with the following questions:
- Why isn't this acyclic? Why does this cause a stack overflow?
- Is there some other way to cross-import without stack overflow?
Referring to the repro below, here is what I would have expected to happen:
p1 is called which results in imported module p then p1 is invoked
p1 outputs p1 then imports module m into p1's scope
- import of module
m includes a call to Import-Module p so module p is imported a second time, this time into module m's scope
- the second import of module
p does not result in any more imports or calls and the whole stack unwinds (*)
(*) In (4) the call to Import-Module m is within the p1 scriptblock and so should not be invoked by the module import.
This is not, however, what happens. Stack overflow seems to occur after (3) but before (4) is reached.
Steps to reproduce
Create two well-formed modules m and p in $Env:PSModulePath:
# m.psm1
Write-Host 'import m'
Import-Module p
# p.psm1
Write-Host 'import p'
function p1 { Write-Host 'p1'; Import-Module m}
Invoke the following:
Expected behavior
import p
p1
import m
import p
Actual behavior
import p
p1
import m
Stack overflow.

Environment data
Name Value
---- -----
PSVersion 7.0.0
PSEdition Core
GitCommitId 7.0.0
OS Microsoft Windows 6.3.9600
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
This came up after #12036 and #12014 while trying to implement the proposed solution for those issues. The solution to those issues will, ostensibly, involve liberal calls to
Import-Modulewithin modules during module loading to shadow the names of commands such that name resolution occurs in module and not global scope. In practice I have found that there are scenarios where such liberal use ofImport-Modulecauses stack overflows. Some such stack overflows are the result of straightforward cyclic calls toImport-Module. This one is slightly different as it is apparently acyclic.One module affected by this is (a later, internal version of) StructuredResource. The culprit seems to be these lines which validate that the DSC resource module imports without error. A DSC resource that requires
StructuredResourceis also tested by and therefore imported byStructuredResource. I suspect this is an unusual perhaps inadvisable use case, but I'd still like to understand what is happening so I can conclusively work around the stack overflow.This leaves me with the following questions:
Referring to the repro below, here is what I would have expected to happen:
p1is called which results in imported modulepthenp1is invokedp1outputsp1then imports modulemintop1's scopemincludes a call toImport-Module pso modulepis imported a second time, this time into modulem's scopepdoes not result in any more imports or calls and the whole stack unwinds (*)(*) In (4) the call to
Import-Module mis within thep1scriptblock and so should not be invoked by the module import.This is not, however, what happens. Stack overflow seems to occur after (3) but before (4) is reached.
Steps to reproduce
Create two well-formed modules
mandpin$Env:PSModulePath:Invoke the following:
Expected behavior
Actual behavior
Environment data