Skip to content

rustc runs out of memory after reporting faulty macro #33136

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

Closed
Mixthos opened this issue Apr 21, 2016 · 3 comments
Closed

rustc runs out of memory after reporting faulty macro #33136

Mixthos opened this issue Apr 21, 2016 · 3 comments
Labels
A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@Mixthos
Copy link

Mixthos commented Apr 21, 2016

Rustc runs out of memory when parsing this (faulty) code:

#[macro_export]
macro_rules! self_referencing {
    ($sname:ty, { $( $field:ident = $val:expr; )* }) => {{
        use std::ptr;
        use std::mem;
        use std::sync::Arc;

        let mut arc = Arc::new($sname {
            $( $field: unsafe { mem::uninitialized() } ),*
        });

        let mut pointer: *mut $sname = Arc::get_mut(&mut arc).unwrap();

        {$(
            println!("m1 {}", stringify!($field));
            let $field = $val;
            println!("m2");
            unsafe { ptr::write(&mut (*pointer).$field, $field); }
            println!("m3");
            let $field = & unsafe { &(*pointer).$field };
            println!("m4");
        )*}

        arc
    }};
}


#[cfg(test)]
#[allow(dead_code)]
#[allow(unused_variables)]
#[allow(unused_mut)]
mod tests {
    #[test]
    fn struct_names() {
        struct S1 {}
        struct S2 {}

        self_referencing!(S1, {});
        self_referencing!(S2, {});
    }
}

I ran this command:

$ RUST_BACKTRACE=1 cargo test
   Compiling self-ref v0.1.1 (file:///D:/Programming/Projects/Mine/self-ref)
src\lib.rs:8:32: 8:38 error: unexpected token: `S1`
src\lib.rs:8         let mut arc = Arc::new($sname {
                                            ^~~~~~
src\lib.rs:8:39: 8:40 error: expected one of `.`, `;`, `?`, or an operator, found `{`
src\lib.rs:8         let mut arc = Arc::new($sname {
                                                   ^

Then it allocated extreme amounts of memory and after a few minutes this happened:

fatal runtime error: out of memory
error: Could not compile `self-ref`.

Meta

rustc 1.10.0-nightly (ed7c56796 2016-04-17)
binary: rustc
commit-hash: ed7c56796ef17f13227a50dc1a72a018b1d5e33f
commit-date: 2016-04-17
host: x86_64-pc-windows-gnu
release: 1.10.0-nightly

The same thing happens on 1.8 stable GNU, though.

@steveklabnik
Copy link
Member

Can confirm that this reproduces on

rustc 1.12.0-nightly (34f35ed29 2016-07-17)
binary: rustc
commit-hash: 34f35ed29c8acdbe1e3c172786fc41d6f4fb6090
commit-date: 2016-07-17
host: x86_64-unknown-linux-gnu
release: 1.12.0-nightly

@TimNN
Copy link
Contributor

TimNN commented Oct 17, 2016

I did a bit of debugging and think that something like the following happens:

The parser encounters an error while parsing the expanded macro and enters recovery mode: It recovers until the closing brace but does not consume it. That brace is not considered the EOF, thus the expander repeatedly attempts to parse another statement / item.

Logfiles for all three cases end in endless lines of DEBUG:syntax::parse::attr: parse_outer_attributes: self.token=CloseDelim(Brace), a backtrace of the small example from #37234 is provided below.

cc @nrc, I think this is your area of expertise.

* thread #2: tid = 0x13e07bf, 0x0000000103d8a47a libsyntax-6eb85298.dylib`syntax::parse::parser::Parser::parse_item_::hd45ad4c7b92b0207 + 7418
  * frame #0: 0x0000000103d8a47a libsyntax-6eb85298.dylib`syntax::parse::parser::Parser::parse_item_::hd45ad4c7b92b0207 + 7418
    frame #1: 0x0000000103d72690 libsyntax-6eb85298.dylib`syntax::parse::parser::Parser::parse_stmt_without_recovery::he0ba5443013bdaf6 + 2320
    frame #2: 0x0000000103d71b7a libsyntax-6eb85298.dylib`syntax::parse::parser::Parser::parse_stmt_::hdf5f69e1800c32ad + 42
    frame #3: 0x0000000103d75c56 libsyntax-6eb85298.dylib`syntax::parse::parser::Parser::parse_full_stmt::hd11716e3359a7818 + 38
    frame #4: 0x0000000103df72ad libsyntax-6eb85298.dylib`syntax::ext::expand::_$LT$impl$u20$syntax..parse..parser..Parser$LT$$u27$a$GT$$GT$::parse_expansion::h8c1627ae52debed0 + 669
    frame #5: 0x0000000103e1e5aa libsyntax-6eb85298.dylib`syntax::ext::tt::macro_rules::ParserAnyMacro::make::hfe157ca05d8b40d4 + 74
    frame #6: 0x0000000103e4de35 libsyntax-6eb85298.dylib`syntax::ext::expand::_$LT$impl$u20$syntax..ext..base..MacResult$u20$for$u20$syntax..ext..tt..macro_rules..ParserAnyMacro$LT$$u27$a$GT$$GT$::make_stmts::h790644120b41cd96 + 37
    frame #7: 0x0000000103e3d6f1 libsyntax-6eb85298.dylib`syntax::ext::expand::ExpansionKind::make_from::hc049eb22fc5e17d1 + 209
    frame #8: 0x0000000103df500b libsyntax-6eb85298.dylib`syntax::ext::expand::MacroExpander::expand::h737d7f1635448d5d + 7179
    frame #9: 0x0000000103df2fe6 libsyntax-6eb85298.dylib`syntax::ext::expand::MacroExpander::expand_crate::hd89d06b7a6333976 + 502
    frame #10: 0x0000000103dfe09e libsyntax-6eb85298.dylib`syntax::ext::expand::expand_crate::h80012253cfa7f1f5 + 142
    frame #11: 0x00000001000f3e6c librustc_driver-6eb85298.dylib`rustc_driver::driver::phase_2_configure_and_expand::_$u7b$$u7b$closure$u7d$$u7d$::hc795707fb140075e + 428
    frame #12: 0x00000001000ac336 librustc_driver-6eb85298.dylib`rustc_driver::driver::phase_2_configure_and_expand::h04526112c643cb41 + 8166
    frame #13: 0x00000001000a6d13 librustc_driver-6eb85298.dylib`rustc_driver::driver::compile_input::h5b63ccd49eeeb98b + 1555
    frame #14: 0x00000001000cf1aa librustc_driver-6eb85298.dylib`rustc_driver::run_compiler::h98c7274e7cb1d11d + 3098
    frame #15: 0x000000010000dff9 librustc_driver-6eb85298.dylib`std::panicking::try::do_call::h99ed0da044e497c3 + 873
    frame #16: 0x00000001041beb3b libstd-6eb85298.dylib`__rust_maybe_catch_panic + 27
    frame #17: 0x000000010002d000 librustc_driver-6eb85298.dylib`_$LT$F$u20$as$u20$alloc..boxed..FnBox$LT$A$GT$$GT$::call_box::hbdd5a14cd8e33b97 + 144
    frame #18: 0x00000001041bac75 libstd-6eb85298.dylib`std::sys::thread::Thread::new::thread_start::h50b05608a499d2b2 + 37
    frame #19: 0x00007fff9cd4b99d libsystem_pthread.dylib`_pthread_body + 131
    frame #20: 0x00007fff9cd4b91a libsystem_pthread.dylib`_pthread_start + 168
    frame #21: 0x00007fff9cd49351 libsystem_pthread.dylib`thread_start + 13

@nrc nrc added the A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) label Oct 17, 2016
@steveklabnik steveklabnik added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. and removed A-compiler labels Mar 24, 2017
@Mark-Simulacrum
Copy link
Member

Closing, this compiles without errors today.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants