ethereum / solidity

Solidity, the Smart Contract Programming Language
https://soliditylang.org
GNU General Public License v3.0
23.29k stars 5.77k forks source link

Segfault when trying to call the AST #502

Closed VoR0220 closed 8 years ago

VoR0220 commented 8 years ago

Might be related to #486

While trying to figure out what part of the AST I was hitting, I also found that I hit a seg fault for this contract as well:

contract test {
            bytes x;
            function f(uint a) returns (uint b) {
                x.length = a;
                for (; a < 200; ++a) {
                    x[a] = 9;
                    b = a * a;
                }
                return f(a - 1);
            }
        }

produces

vor0220@CaptainNumNutz:solidity/build ‹fixSegFault›$ solc --ast test.sol
[1]    6034 segmentation fault  solc --ast test.sol
vor0220@CaptainNumNutz:solidity/build ‹fixSegFault›$ solc --ast-json test.sol
[1]    6055 segmentation fault  solc --ast-json test.sol
chriseth commented 8 years ago

Unable to reproduce on ubuntu. Can you provide a stack trace?

VoR0220 commented 8 years ago
vor0220@CaptainNumNutz:solidity/build ‹fixedDataType›$ lldb solc -- --ast test.sol
(lldb) target create "solc"
Current executable set to 'solc' (x86_64).
(lldb) settings set -- target.run-args  "--ast" "test.sol"
(lldb) run
Process 39574 launched: '/Users/vor0220/webthree-umbrella/solidity/build/solc/solc' (x86_64)
Process 39574 stopped
* thread #1: tid = 0x2145e4, 0x000000010000c28f solc`dev::solidity::CommandLineInterface::handleAst(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) [inlined] std::__1::__tree<std::__1::__value_type<dev::solidity::ASTNode const*, dev::eth::GasMeter::GasConsumption>, std::__1::__map_value_compare<dev::solidity::ASTNode const*, std::__1::__value_type<dev::solidity::ASTNode const*, dev::eth::GasMeter::GasConsumption>, std::__1::less<dev::solidity::ASTNode const*>, true>, std::__1::allocator<std::__1::__value_type<dev::solidity::ASTNode const*, dev::eth::GasMeter::GasConsumption> > >::__move_assign(this=<unavailable>) + 86 at __tree:1350, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
    frame #0: 0x000000010000c28f solc`dev::solidity::CommandLineInterface::handleAst(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) [inlined] std::__1::__tree<std::__1::__value_type<dev::solidity::ASTNode const*, dev::eth::GasMeter::GasConsumption>, std::__1::__map_value_compare<dev::solidity::ASTNode const*, std::__1::__value_type<dev::solidity::ASTNode const*, dev::eth::GasMeter::GasConsumption>, std::__1::less<dev::solidity::ASTNode const*>, true>, std::__1::allocator<std::__1::__value_type<dev::solidity::ASTNode const*, dev::eth::GasMeter::GasConsumption> > >::__move_assign(this=<unavailable>) + 86 at __tree:1350
   1347         __end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__end_node());
   1348         __t.__begin_node() = __t.__end_node();
   1349         __t.__end_node()->__left_ = nullptr;
-> 1350         __t.size() = 0;
   1351     }
   1352 }
   1353
(lldb) bt
* thread #1: tid = 0x2145e4, 0x000000010000c28f solc`dev::solidity::CommandLineInterface::handleAst(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) [inlined] std::__1::__tree<std::__1::__value_type<dev::solidity::ASTNode const*, dev::eth::GasMeter::GasConsumption>, std::__1::__map_value_compare<dev::solidity::ASTNode const*, std::__1::__value_type<dev::solidity::ASTNode const*, dev::eth::GasMeter::GasConsumption>, std::__1::less<dev::solidity::ASTNode const*>, true>, std::__1::allocator<std::__1::__value_type<dev::solidity::ASTNode const*, dev::eth::GasMeter::GasConsumption> > >::__move_assign(this=<unavailable>) + 86 at __tree:1350, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
  * frame #0: 0x000000010000c28f solc`dev::solidity::CommandLineInterface::handleAst(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) [inlined] std::__1::__tree<std::__1::__value_type<dev::solidity::ASTNode const*, dev::eth::GasMeter::GasConsumption>, std::__1::__map_value_compare<dev::solidity::ASTNode const*, std::__1::__value_type<dev::solidity::ASTNode const*, dev::eth::GasMeter::GasConsumption>, std::__1::less<dev::solidity::ASTNode const*>, true>, std::__1::allocator<std::__1::__value_type<dev::solidity::ASTNode const*, dev::eth::GasMeter::GasConsumption> > >::__move_assign(this=<unavailable>) + 86 at __tree:1350
    frame #1: 0x000000010000c239 solc`dev::solidity::CommandLineInterface::handleAst(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) [inlined] std::__1::__tree<std::__1::__value_type<dev::solidity::ASTNode const*, dev::eth::GasMeter::GasConsumption>, std::__1::__map_value_compare<dev::solidity::ASTNode const*, std::__1::__value_type<dev::solidity::ASTNode const*, dev::eth::GasMeter::GasConsumption>, std::__1::less<dev::solidity::ASTNode const*>, true>, std::__1::allocator<std::__1::__value_type<dev::solidity::ASTNode const*, dev::eth::GasMeter::GasConsumption> > >::operator=(this=<unavailable>) at __tree:1409
    frame #2: 0x000000010000c239 solc`dev::solidity::CommandLineInterface::handleAst(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) [inlined] std::__1::map<dev::solidity::ASTNode const*, dev::eth::GasMeter::GasConsumption, std::__1::less<dev::solidity::ASTNode const*>, std::__1::allocator<std::__1::pair<dev::solidity::ASTNode const* const, dev::eth::GasMeter::GasConsumption> > >::operator=(this=<unavailable>) at map:961
    frame #3: 0x000000010000c239 solc`dev::solidity::CommandLineInterface::handleAst(this=0x00007fff5fbff848, _argStr="ast") + 985 at CommandLineInterface.cpp:722
    frame #4: 0x000000010000ddca solc`dev::solidity::CommandLineInterface::outputCompilationResults(this=0x00007fff5fbff848) + 58 at CommandLineInterface.cpp:873
    frame #5: 0x000000010002922c solc`main(argc=<unavailable>, argv=<unavailable>) + 236 at main.cpp:38
    frame #6: 0x00007fff997c25ad libdyld.dylib`start + 1
    frame #7: 0x00007fff997c25ad libdyld.dylib`start + 1
chriseth commented 8 years ago

Did you run that in a debug build?

VoR0220 commented 8 years ago

@chriseth no...let me try rerunning it. Will post it up here soon.

VoR0220 commented 8 years ago
vor0220@CaptainNumNutz:solidity/build ‹develop›$ lldb solc -- --ast test.sol
(lldb) target create "solc"
Current executable set to 'solc' (x86_64).
(lldb) settings set -- target.run-args  "--ast" "test.sol"
(lldb) run
Process 40199 launched: '/Users/vor0220/webthree-umbrella/solidity/build/solc/solc' (x86_64)
Process 40199 stopped
* thread #1: tid = 0xa8c2b, 0x000000010000c28f solc`dev::solidity::CommandLineInterface::handleAst(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) [inlined] std::__1::__tree<std::__1::__value_type<dev::solidity::ASTNode const*, dev::eth::GasMeter::GasConsumption>, std::__1::__map_value_compare<dev::solidity::ASTNode const*, std::__1::__value_type<dev::solidity::ASTNode const*, dev::eth::GasMeter::GasConsumption>, std::__1::less<dev::solidity::ASTNode const*>, true>, std::__1::allocator<std::__1::__value_type<dev::solidity::ASTNode const*, dev::eth::GasMeter::GasConsumption> > >::__move_assign(this=<unavailable>) + 86 at __tree:1350, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
    frame #0: 0x000000010000c28f solc`dev::solidity::CommandLineInterface::handleAst(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) [inlined] std::__1::__tree<std::__1::__value_type<dev::solidity::ASTNode const*, dev::eth::GasMeter::GasConsumption>, std::__1::__map_value_compare<dev::solidity::ASTNode const*, std::__1::__value_type<dev::solidity::ASTNode const*, dev::eth::GasMeter::GasConsumption>, std::__1::less<dev::solidity::ASTNode const*>, true>, std::__1::allocator<std::__1::__value_type<dev::solidity::ASTNode const*, dev::eth::GasMeter::GasConsumption> > >::__move_assign(this=<unavailable>) + 86 at __tree:1350
   1347         __end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__end_node());
   1348         __t.__begin_node() = __t.__end_node();
   1349         __t.__end_node()->__left_ = nullptr;
-> 1350         __t.size() = 0;
   1351     }
   1352 }
   1353
(lldb) bt
* thread #1: tid = 0xa8c2b, 0x000000010000c28f solc`dev::solidity::CommandLineInterface::handleAst(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) [inlined] std::__1::__tree<std::__1::__value_type<dev::solidity::ASTNode const*, dev::eth::GasMeter::GasConsumption>, std::__1::__map_value_compare<dev::solidity::ASTNode const*, std::__1::__value_type<dev::solidity::ASTNode const*, dev::eth::GasMeter::GasConsumption>, std::__1::less<dev::solidity::ASTNode const*>, true>, std::__1::allocator<std::__1::__value_type<dev::solidity::ASTNode const*, dev::eth::GasMeter::GasConsumption> > >::__move_assign(this=<unavailable>) + 86 at __tree:1350, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
  * frame #0: 0x000000010000c28f solc`dev::solidity::CommandLineInterface::handleAst(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) [inlined] std::__1::__tree<std::__1::__value_type<dev::solidity::ASTNode const*, dev::eth::GasMeter::GasConsumption>, std::__1::__map_value_compare<dev::solidity::ASTNode const*, std::__1::__value_type<dev::solidity::ASTNode const*, dev::eth::GasMeter::GasConsumption>, std::__1::less<dev::solidity::ASTNode const*>, true>, std::__1::allocator<std::__1::__value_type<dev::solidity::ASTNode const*, dev::eth::GasMeter::GasConsumption> > >::__move_assign(this=<unavailable>) + 86 at __tree:1350
    frame #1: 0x000000010000c239 solc`dev::solidity::CommandLineInterface::handleAst(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) [inlined] std::__1::__tree<std::__1::__value_type<dev::solidity::ASTNode const*, dev::eth::GasMeter::GasConsumption>, std::__1::__map_value_compare<dev::solidity::ASTNode const*, std::__1::__value_type<dev::solidity::ASTNode const*, dev::eth::GasMeter::GasConsumption>, std::__1::less<dev::solidity::ASTNode const*>, true>, std::__1::allocator<std::__1::__value_type<dev::solidity::ASTNode const*, dev::eth::GasMeter::GasConsumption> > >::operator=(this=<unavailable>) at __tree:1409
    frame #2: 0x000000010000c239 solc`dev::solidity::CommandLineInterface::handleAst(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) [inlined] std::__1::map<dev::solidity::ASTNode const*, dev::eth::GasMeter::GasConsumption, std::__1::less<dev::solidity::ASTNode const*>, std::__1::allocator<std::__1::pair<dev::solidity::ASTNode const* const, dev::eth::GasMeter::GasConsumption> > >::operator=(this=<unavailable>) at map:961
    frame #3: 0x000000010000c239 solc`dev::solidity::CommandLineInterface::handleAst(this=0x00007fff5fbff798, _argStr="ast") + 985 at CommandLineInterface.cpp:722
    frame #4: 0x000000010000ddca solc`dev::solidity::CommandLineInterface::outputCompilationResults(this=0x00007fff5fbff798) + 58 at CommandLineInterface.cpp:873
    frame #5: 0x000000010002922c solc`main(argc=<unavailable>, argv=<unavailable>) + 236 at main.cpp:38
    frame #6: 0x00007fff96c6b5ad libdyld.dylib`start + 1
    frame #7: 0x00007fff96c6b5ad libdyld.dylib`start + 1
(lldb)
gcolvin commented 8 years ago
For sure not related to the ethvm segfault.

On 4/19/16 7:57 PM, RJ wrote:

  vor0220@CaptainNumNutz:solidity/build ‹develop›$ lldb solc -- --ast test.sol

(lldb) target create "solc" Current executable set to 'solc' (x86_64). (lldb) settings set -- target.run-args "--ast" "test.sol" (lldb) run Process 40199 launched: '/Users/vor0220/webthree-umbrella/solidity/build/solc/solc' (x86_64) Process 40199 stopped

chriseth commented 8 years ago

@VoR0220 that seems to be exactly the same trace. Can you try to recompile with cmake -DCMAKE_BUILD_TYPE=Debug .. && make -j 3 solc?

VoR0220 commented 8 years ago

:00000 that did it! Bug closed!

bobsummerwill commented 8 years ago

Reopened, because this isn't a fix, it's a workaround.

If Release is broken but Debug works then we have a nasty issue which might be an optimizer issue.

VoR0220 commented 8 years ago

okay...bug is back with the latest update...this time the debug mode it is still dying at the same points. The stack trace is the same either way :/

bobsummerwill commented 8 years ago

Yeah. It clearly wasn't "fixed". Adding @gcolvin to.

If you are seeing it in Debug as well then it cannot be an optimizer issue.

Maybe it's an uninitialized variable (not necessarily global uninitialized, but maybe some container or subsystem needs to be re-initialized per something, and we're not doing it).

Or maybe it's a multi-threading issue of some kind.

Or maybe (please no) it's a memory overwrite.

Is the actual failure a null pointer reference?

bobsummerwill commented 8 years ago

Maybe it's time to get valgrind working again? https://github.com/ethereum/webthree-umbrella/issues/222

We also have an awful lot of suppressed warnings.

We could also do runs with tools like Coverity. https://github.com/ethereum/webthree-umbrella/issues/170

VoR0220 commented 8 years ago

@bobsummerwill there is definitely that possibility. That's what came up every time I tried to build it in Xcode (which is strange, because it builds just fine everywhere else)

bobsummerwill commented 8 years ago

As in "build in xcode IDE", or "build on OS X make command-line"?

VoR0220 commented 8 years ago

build in xcode IDE

bobsummerwill commented 8 years ago

Are you saying that you were seeing a difference in runtime behaviour between OS X makefile builds on the command-line and OS X IDE builds? That is entirely feasible.

VoR0220 commented 8 years ago

Yes.

bobsummerwill commented 8 years ago

Closed as dupe of "The Heisenbug" - https://github.com/ethereum/webthree-umbrella/issues/565. We can reopen if we later find there is anything unique here.