Re: Wacky crash in Clone()

Bill Deegan <[email protected]>
Newsgroups gmane.comp.programming.tools.scons.user
Message-ID <CAEyG4CFrV-PNz=8i9cM1XUTpsL=FRP8wVASFEu9LcVRUp-=LXw@mail.gmail.com>
Clone() in an Action would happen on a thread.
Environment's shouldn't be modified in a thread...
Why do that?

On Fri, Jan 21, 2022 at 2:46 PM Bill Deegan <[email protected]>
wrote:

> scons-users is the right place.
>
> So you're Clone()'ing inside an Action()?
> Yeah..that's a BAD idea...
>
> On Fri, Jan 21, 2022 at 1:39 PM Marc Branchaud via Scons-users <
> [email protected]> wrote:
>
>> (Possibly should send this to scons-dev@?)
>>
>> Hi all,
>>
>> I'm updating a complex build from 2.2.0 (Python 2.7.18) to 4.2.0 (Python
>> 3.10.1), and I've run into this crash.  Unfortunately I have been unable
>> to craft a simple reproduction example, and the code cannot be
>> published.  The crash happens inside an env.Clone() call in a function
>> being used as an Action's output, where the Action is a custom Builder.
>>
>> I'm hoping someone can point out something I'm doing that became "wrong"
>> since SCons 2.2.0.  Has there been a change in how custom Builders work?
>>
>> Or, maybe someone can point me at someplace that might help me figure
>> out the bug.
>>
>> The code is basically structured as follows.  The custom builder uses
>> functions from a "BaseBuilder" module defined in site_scons.  (I've
>> elided a lot of setup work in the real code, which is sprinkled among
>> several different files, many of which are exec()'d by the SConstruct.
>> I'm trying not to suspect the reliance on exec() to split up what would
>> otherwise be a giant SConstruct file.)
>>
>> SConstruct
>>         e1 = Environment(
>>             tools = [ 'MyBuilder' ],
>>         )
>>         e2 = e1.Clone(
>>             CCFLAGS = ['-g']
>>         )
>>         e2.MyBuilder(
>>             target="out",
>>             source="in",
>>         )
>>
>> site_scons/BaseBuilder.py
>>         def message(target, source, env):
>>             myenv = env.Clone()           # <-- This crashes
>>             print("MESSAGE")
>>
>>         def builder(target, source, env):
>>             print("BUILDER")
>>
>> site_scons/site_tools/MyBuilder.py
>>         import BaseBuilder
>>
>>         def exists(env):
>>             return True
>>
>>         def generate(env, **kwargs):
>>             env['BUILDERS']['MyBuilder'] = env.Builder(
>>                 action = env.Action(
>>                     BaseBuilder.builder,
>>                     BaseBuilder.message,
>>                 )
>>             )
>>
>> Sadly the above code works just fine.  But here's the crash from the
>> real code:
>>
>> Traceback (most recent call last):
>>    File
>> "/usr/local/lib/python3.10/site-packages/SCons-4.2.0-py3.10.egg/SCons/Taskmaster.py",
>>
>> line 235, in execute
>>      self.targets[0].build()
>>    File
>> "/usr/local/lib/python3.10/site-packages/SCons-4.2.0-py3.10.egg/SCons/Node/__init__.py",
>>
>> line 755, in build
>>      self.get_executor()(self, **kw)
>>    File
>> "/usr/local/lib/python3.10/site-packages/SCons-4.2.0-py3.10.egg/SCons/Executor.py",
>>
>> line 384, in __call__
>>      return _do_execute_map[self._do_execute](self, target, kw)
>>    File
>> "/usr/local/lib/python3.10/site-packages/SCons-4.2.0-py3.10.egg/SCons/Executor.py",
>>
>> line 117, in execute_action_list
>>      status = act(*args, **kw)
>>    File
>> "/usr/local/lib/python3.10/site-packages/SCons-4.2.0-py3.10.egg/SCons/Action.py",
>>
>> line 686, in __call__
>>      cmd = self.strfunction(target, source, env)
>>    File
>> "/usr/home/marcnarc/Code/Worktrees/python3-build/site_scons/BaseBuilder.py",
>>
>> line 77, in message
>>      myenv = env.Clone()
>>    File
>> "/usr/local/lib/python3.10/site-packages/SCons-4.2.0-py3.10.egg/SCons/Environment.py",
>>
>> line 1450, in Clone
>>      clone = copy.copy(self)
>>    File "/usr/local/lib/python3.10/copy.py", line 102, in copy
>>      return _reconstruct(x, None, *rv)
>>    File "/usr/local/lib/python3.10/copy.py", line 272, in _reconstruct
>>      if hasattr(y, '__setstate__'):
>>    File
>> "/usr/local/lib/python3.10/site-packages/SCons-4.2.0-py3.10.egg/SCons/Environment.py",
>>
>> line 2384, in __getattr__
>>      attr = getattr(self.__dict__['__subject'], name)
>> KeyError: '__subject'
>>
>> At the offending line, `self` is an OverrideEnvironment that somehow has
>> a completely empty __dict__.
>>
>> One frame up, the `y` that's being checked with hasattr() was created
>> inside copy.copy()'s _reconstruct() via a __newobj__() call.  This `y`
>> is an OverrideEnvironment but it's __dict__ is empty.
>>
>> If I set a breakpoint at the dying getattr() line, it gets called twice
>> before the crash, both with proper OverrideEnvironment objects.
>>
>> Any ideas?  Could something in the build's code have possibly mucked
>> with the OverrideEnvironment created by __newobj__()?  (What would such
>> a thing even look like?)
>>
>> My next step will be to bisect this using different Python and SCons
>> versions.  Whee!
>>
>>                 M.
>> _______________________________________________
>> Scons-users mailing list
>> [email protected]
>> https://pairlist4.pair.net/mailman/listinfo/scons-users
>>
>

_______________________________________________
Scons-users mailing list
[email protected]
https://pairlist4.pair.net/mailman/listinfo/scons-users
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.