summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/spack/spack/main.py2
-rw-r--r--lib/spack/spack/util/environment.py41
2 files changed, 29 insertions, 14 deletions
diff --git a/lib/spack/spack/main.py b/lib/spack/spack/main.py
index 5224f42345..484ba4553d 100644
--- a/lib/spack/spack/main.py
+++ b/lib/spack/spack/main.py
@@ -43,6 +43,7 @@ import spack.repo
import spack.spec
import spack.store
import spack.util.debug
+import spack.util.environment
import spack.util.executable as exe
import spack.util.path
from spack.error import SpackError
@@ -478,6 +479,7 @@ def setup_main_options(args):
spack.error.debug = True
spack.util.debug.register_interrupt_handler()
spack.config.set('config:debug', True, scope='command_line')
+ spack.util.environment.tracing_enabled = True
if args.timestamp:
tty.set_timestamp(True)
diff --git a/lib/spack/spack/util/environment.py b/lib/spack/spack/util/environment.py
index 398af5f018..a0a6c4a3aa 100644
--- a/lib/spack/spack/util/environment.py
+++ b/lib/spack/spack/util/environment.py
@@ -21,6 +21,7 @@ from six.moves import shlex_quote as cmd_quote
import llnl.util.tty as tty
from llnl.util.lang import dedupe
+import spack.config
import spack.platforms
import spack.spec
import spack.util.executable as executable
@@ -45,6 +46,9 @@ _shell_unset_strings = {
}
+tracing_enabled = False
+
+
def is_system_path(path):
"""Predicate that given a path returns True if it is a system path,
False otherwise.
@@ -365,14 +369,17 @@ class EnvironmentModifications(object):
* 'context' : line of code that issued the request that failed
"""
- def __init__(self, other=None):
+ def __init__(self, other=None, traced=None):
"""Initializes a new instance, copying commands from 'other'
if it is not None.
Args:
other (EnvironmentModifications): list of environment modifications
to be extended (optional)
+ traced (bool): enable or disable stack trace inspection to log the origin
+ of the environment modifications.
"""
+ self.traced = tracing_enabled if traced is None else bool(traced)
self.env_modifications = []
if other is not None:
self.extend(other)
@@ -393,7 +400,12 @@ class EnvironmentModifications(object):
raise TypeError(
'other must be an instance of EnvironmentModifications')
- def _get_outside_caller_attributes(self):
+ def _maybe_trace(self, kwargs):
+ """Provide the modification with stack trace info so that we can track its
+ origin to find issues in packages. This is very slow and expensive."""
+ if not self.traced:
+ return
+
stack = inspect.stack()
try:
_, filename, lineno, _, context, index = stack[2]
@@ -402,8 +414,7 @@ class EnvironmentModifications(object):
filename = 'unknown file'
lineno = 'unknown line'
context = 'unknown context'
- args = {'filename': filename, 'lineno': lineno, 'context': context}
- return args
+ kwargs.update({'filename': filename, 'lineno': lineno, 'context': context})
def set(self, name, value, **kwargs):
"""Stores a request to set an environment variable.
@@ -412,7 +423,7 @@ class EnvironmentModifications(object):
name: name of the environment variable to be set
value: value of the environment variable
"""
- kwargs.update(self._get_outside_caller_attributes())
+ self._maybe_trace(kwargs)
item = SetEnv(name, value, **kwargs)
self.env_modifications.append(item)
@@ -425,7 +436,7 @@ class EnvironmentModifications(object):
value: value to append to the environment variable
Appends with spaces separating different additions to the variable
"""
- kwargs.update(self._get_outside_caller_attributes())
+ self._maybe_trace(kwargs)
kwargs.update({'separator': sep})
item = AppendFlagsEnv(name, value, **kwargs)
self.env_modifications.append(item)
@@ -436,7 +447,7 @@ class EnvironmentModifications(object):
Args:
name: name of the environment variable to be unset
"""
- kwargs.update(self._get_outside_caller_attributes())
+ self._maybe_trace(kwargs)
item = UnsetEnv(name, **kwargs)
self.env_modifications.append(item)
@@ -450,7 +461,7 @@ class EnvironmentModifications(object):
value: value to remove to the environment variable
sep: separator to assume for environment variable
"""
- kwargs.update(self._get_outside_caller_attributes())
+ self._maybe_trace(kwargs)
kwargs.update({'separator': sep})
item = RemoveFlagsEnv(name, value, **kwargs)
self.env_modifications.append(item)
@@ -462,7 +473,7 @@ class EnvironmentModifications(object):
name: name o the environment variable to be set.
elements: elements of the path to set.
"""
- kwargs.update(self._get_outside_caller_attributes())
+ self._maybe_trace(kwargs)
item = SetPath(name, elements, **kwargs)
self.env_modifications.append(item)
@@ -473,7 +484,7 @@ class EnvironmentModifications(object):
name: name of the path list in the environment
path: path to be appended
"""
- kwargs.update(self._get_outside_caller_attributes())
+ self._maybe_trace(kwargs)
item = AppendPath(name, path, **kwargs)
self.env_modifications.append(item)
@@ -484,7 +495,7 @@ class EnvironmentModifications(object):
name: name of the path list in the environment
path: path to be pre-pended
"""
- kwargs.update(self._get_outside_caller_attributes())
+ self._maybe_trace(kwargs)
item = PrependPath(name, path, **kwargs)
self.env_modifications.append(item)
@@ -495,7 +506,7 @@ class EnvironmentModifications(object):
name: name of the path list in the environment
path: path to be removed
"""
- kwargs.update(self._get_outside_caller_attributes())
+ self._maybe_trace(kwargs)
item = RemovePath(name, path, **kwargs)
self.env_modifications.append(item)
@@ -506,7 +517,7 @@ class EnvironmentModifications(object):
Args:
name: name of the path list in the environment.
"""
- kwargs.update(self._get_outside_caller_attributes())
+ self._maybe_trace(kwargs)
item = DeprioritizeSystemPaths(name, **kwargs)
self.env_modifications.append(item)
@@ -517,7 +528,7 @@ class EnvironmentModifications(object):
Args:
name: name of the path list in the environment.
"""
- kwargs.update(self._get_outside_caller_attributes())
+ self._maybe_trace(kwargs)
item = PruneDuplicatePaths(name, **kwargs)
self.env_modifications.append(item)
@@ -843,6 +854,8 @@ def validate(env, errstream):
Args:
env: list of environment modifications
"""
+ if not env.traced:
+ return
modifications = env.group_by_name()
for variable, list_of_changes in sorted(modifications.items()):
set_or_unset_not_first(variable, list_of_changes, errstream)