Skip to content

An integer overflow occurred during the Executing AUTONAME pass. #4983

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
sdjasj opened this issue Apr 2, 2025 · 1 comment · May be fixed by #5081
Open

An integer overflow occurred during the Executing AUTONAME pass. #4983

sdjasj opened this issue Apr 2, 2025 · 1 comment · May be fixed by #5081
Labels
error handling Error handling and reporting fix pending PR with a fix is pending Fuzzer Fuzzer generated issue

Comments

@sdjasj
Copy link
Contributor

sdjasj commented Apr 2, 2025

Version

Yosys 0.50+49 (git sha1 05c81b3, clang++ 14.0.0-1ubuntu1.1 -Og -fPIC -O1 -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize=address,undefined)

On which OS did this happen?

Linux

Reproduction Steps

The following is the Verilog code file bug.v that triggers the bug. I have already minimized it as much as possible.

module a(input b, input [83 : 10] c, d, e, output f);
    reg g;
    always @(*) begin
        f <= g;
        g = d / b;
        if (d / g) begin
            g = b ? b / e / c : 0;
        end
    end 
endmodule

Running the following script will trigger the bug.

yosys -p "read_verilog bug.v; synth_nexus"

I discovered this bug while testing Yosys using a fuzzing tool I am developing. While reviewing historical issues, I found that #4509 reported a similar problem. However, the code snippet that caused the error in that issue is different from the one in the current case, so I believe they might be different issues. Specifically, the code snippet that leads to the integer overflow is in passes/cmds/autoname.cc:80:17:

for (auto &it : proposed_wire_names) {
	if (best_score*2 < it.second.first)
		continue;
	IdString n = module->uniquify(IdString(it.second.second));
	log_debug("Rename wire %s in %s to %s.\n", log_id(it.first), log_id(module), log_id(n));
	module->rename(it.first, n);
}

The issue was triggered by the line if (best_score*2 < it.second.first).

Expected Behavior

The synthesis process should either succeed or fail due to an error; integer overflows and other abnormal behaviors (such as OOM) should not occur.

Actual Behavior

The synthesis process hangs during Executing AUTONAME pass. After some time, it triggers a runtime error:
passes/cmds/autoname.cc:80:17: runtime error: signed integer overflow: 1136330020 * 2 cannot be represented in type 'int'.
Later, it results in: AddressSanitizer: Out of memory. The process has exhausted 65536MB for size class 32.
The detailed log is as follows:

2.49. Executing SETUNDEF pass (replace undef values with defined constants).

2.50. Executing HILOMAP pass (mapping to constant drivers).
Removed 0 unused cells and 71632 unused wires.

2.51. Executing AUTONAME pass.
passes/cmds/autoname.cc:80:17: runtime error: signed integer overflow: 1136330020 * 2 cannot be represented in type 'int'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior passes/cmds/autoname.cc:80:17 in 
AddressSanitizer: Out of memory. The process has exhausted 65536MB for size class 32.
=================================================================
==3159236==ERROR: AddressSanitizer: allocator is out of memory trying to allocate 0x4 bytes
    #0 0x55c744e7fde3 in strdup (/usr/local/bin/yosys+0x1c75de3) (BuildId: bad06cfe5b0c7051344047df9ec204002aba65ee)
    #1 0x55c745177848 in Yosys::log_id(Yosys::RTLIL::IdString const&) (/usr/local/bin/yosys+0x1f6d848) (BuildId: bad06cfe5b0c7051344047df9ec204002aba65ee)
    #2 0x55c745a49638 in (anonymous namespace)::autoname_worker(Yosys::RTLIL::Module*, Yosys::hashlib::dict<Yosys::RTLIL::Wire*, int, Yosys::hashlib::hash_ops<Yosys::RTLIL::Wire*> > const&) (/usr/local/bin/yosys+0x283f638) (BuildId: bad06cfe5b0c7051344047df9ec204002aba65ee)
    #3 0x55c745a481be in (anonymous namespace)::AutonamePass::execute(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, Yosys::RTLIL::Design*) (/usr/local/bin/yosys+0x283e1be) (BuildId: bad06cfe5b0c7051344047df9ec204002aba65ee)
    #4 0x55c744f8498d in Yosys::Pass::call(Yosys::RTLIL::Design*, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >) (/usr/local/bin/yosys+0x1d7a98d) (BuildId: bad06cfe5b0c7051344047df9ec204002aba65ee)
    #5 0x55c744f8405f in Yosys::Pass::call(Yosys::RTLIL::Design*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (/usr/local/bin/yosys+0x1d7a05f) (BuildId: bad06cfe5b0c7051344047df9ec204002aba65ee)
    #6 0x55c744f86af4 in Yosys::ScriptPass::run(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (/usr/local/bin/yosys+0x1d7caf4) (BuildId: bad06cfe5b0c7051344047df9ec204002aba65ee)
    #7 0x55c746ebd70c in (anonymous namespace)::SynthNexusPass::script() (/usr/local/bin/yosys+0x3cb370c) (BuildId: bad06cfe5b0c7051344047df9ec204002aba65ee)
    #8 0x55c744f874bc in Yosys::ScriptPass::run_script(Yosys::RTLIL::Design*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (/usr/local/bin/yosys+0x1d7d4bc) (BuildId: bad06cfe5b0c7051344047df9ec204002aba65ee)
    #9 0x55c746eb7932 in (anonymous namespace)::SynthNexusPass::execute(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, Yosys::RTLIL::Design*) (/usr/local/bin/yosys+0x3cad932) (BuildId: bad06cfe5b0c7051344047df9ec204002aba65ee)
    #10 0x55c744f8498d in Yosys::Pass::call(Yosys::RTLIL::Design*, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >) (/usr/local/bin/yosys+0x1d7a98d) (BuildId: bad06cfe5b0c7051344047df9ec204002aba65ee)
    #11 0x55c744f8405f in Yosys::Pass::call(Yosys::RTLIL::Design*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (/usr/local/bin/yosys+0x1d7a05f) (BuildId: bad06cfe5b0c7051344047df9ec204002aba65ee)
    #12 0x55c7451a34b3 in Yosys::shell(Yosys::RTLIL::Design*) (/usr/local/bin/yosys+0x1f994b3) (BuildId: bad06cfe5b0c7051344047df9ec204002aba65ee)
    #13 0x55c744edc1c9 in main (/usr/local/bin/yosys+0x1cd21c9) (BuildId: bad06cfe5b0c7051344047df9ec204002aba65ee)
    #14 0x14e77a42ed8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16

Below is the call stack I obtained using GDB at the point when the integer overflow occurred:

#0  0x00005555571e199d in __asan_region_is_poisoned ()
#1  0x00005555571de6fa in __asan_memcpy ()
#2  0x000055555724dd8a in void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*>(char const*, char const*, std::forward_iterator_tag) ()
#3  0x000055555722f124 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<std::allocator<char> >(char const*, std::allocator<char> const&) ()
#4  0x00005555572da9bc in Yosys::RTLIL::IdString::str[abi:cxx11]() const ()
#5  0x0000555557d936cd in (anonymous namespace)::autoname_worker(Yosys::RTLIL::Module*, Yosys::hashlib::dict<Yosys::RTLIL::Wire*, int, Yosys::hashlib::hash_ops<Yosys::RTLIL::Wire*> > const&) ()
#6  0x0000555557d921bf in (anonymous namespace)::AutonamePass::execute(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, Yosys::RTLIL::Design*) ()
#7  0x00005555572ce98e in Yosys::Pass::call(Yosys::RTLIL::Design*, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >) ()
--Type <RET> for more, q to quit, c to continue without paging--
#8  0x00005555572ce060 in Yosys::Pass::call(Yosys::RTLIL::Design*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) ()
#9  0x00005555572d0af5 in Yosys::ScriptPass::run(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) ()
#10 0x000055555920770d in (anonymous namespace)::SynthNexusPass::script() ()
#11 0x00005555572d14bd in Yosys::ScriptPass::run_script(Yosys::RTLIL::Design*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) ()
#12 0x0000555559201933 in (anonymous namespace)::SynthNexusPass::execute(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, Yosys::RTLIL::Design*) ()
#13 0x00005555572ce98e in Yosys::Pass::call(Yosys::RTLIL::Design*, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >) ()
#14 0x00005555572ce060 in Yosys::Pass::call(Yosys::RTLIL::Design*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) ()
#15 0x00005555574ec4d9 in Yosys::run_pass(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, Yosys::RTLIL::Design*) ()
#16 0x000055555722603c in main ()
@sdjasj sdjasj added the pending-verification This issue is pending verification and/or reproduction label Apr 2, 2025
@KrystalDelusion KrystalDelusion added the Fuzzer Fuzzer generated issue label Apr 22, 2025
@KrystalDelusion
Copy link
Member

For the example given with synth_nexus, this explodes out to 64k cells, 16k wires, and 185k wire bits. The highest "wire_score" (which I think corresponds to the fanout of a wire, as a number of bits) is $auto$hilomap.cc:39:hilomap_worker$945986 with 113633. The score for using that wire in the name of a cell then becomes score = 10000*score + new_name.size();, which in this case appears to be the 1136330020 in your runtime error, and is more than half of intmax (2,147,483,647). I'm not sure how likely such a high fanout would ever be in practice, but this does seem fairly straightforward to check for and raise an error.

@KrystalDelusion KrystalDelusion linked a pull request May 1, 2025 that will close this issue
@KrystalDelusion KrystalDelusion added fix pending PR with a fix is pending error handling Error handling and reporting and removed pending-verification This issue is pending verification and/or reproduction labels May 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
error handling Error handling and reporting fix pending PR with a fix is pending Fuzzer Fuzzer generated issue
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants