Author Topic: Bug report. Infinite loop in ParserThread::SkipBlock  (Read 2950 times)

Offline alnik

  • Single posting newcomer
  • *
  • Posts: 2
Bug report. Infinite loop in ParserThread::SkipBlock
« on: September 10, 2015, 02:26:35 pm »
Hello!

- What is the problem?
Infinite loop in ParserThread::SkipBlock - tokenazer infinitly expand macro.
- What did you do to when it happened?
Open next source file (attached):

cc_test.cpp
Code: [Select]
#define AA__( x ) #x
#define AA_( x ) AA__( prefix##x )
#define AA( x ) AA_( x )

#define BB 42

struct CC { int member; };
struct DD { CC cc; };

#define EE() g( AA(BB) )

#define FF (EE()->cc)

#define member FF.member

DD* g(const char*);

int f()
{
    return member; // "member" expand to " (g(AA__)->cc).member" infinitly
}


- Can you reproduce it? How?
Yes. Open attached source file.
- What release of Code::Blocks are you using?
Bug reproduced in trunk after revision number 10459.
- Which was the latest release that did not have this problem?
Trunk revision 10495.

Thank you!

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5247
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Bug report. Infinite loop in ParserThread::SkipBlock
« Reply #1 on: September 11, 2015, 02:17:47 am »
Thanks for the report, I can confirm this bug.
The reason I found is that, the anchor point(m_TokenIndex) when we first start macro expansion was wrongly reset, so that
"member" is expanded infinite times.

I don't have a clean way to fix this issue......

EDIT:
Code: [Select]
bool Tokenizer::ReplaceBufferText(const wxString& target, const Token* macro)
{
    if (target.IsEmpty())
        return true; // the token is removed from the buffer, return true, so we need to fetch another token

    if (m_ExpandedMacros.size() >= s_MaxMacroReplaceDepth)
    {
        // clear the macro expansion stack
        m_ExpandedMacros.clear();

        m_PeekAvailable = false;
        return true; // NOTE: we have to skip the problem token by returning true.
    }
    ...

The problem is here, when (m_ExpandedMacros.size() >= s_MaxMacroReplaceDepth) happens, the m_ExpandedMacros stack get cleaned up, so that the "anchor point" saved in the deepest use macro is lost.
« Last Edit: September 11, 2015, 02:25:39 am by ollydbg »
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5247
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Bug report. Infinite loop in ParserThread::SkipBlock
« Reply #2 on: September 11, 2015, 02:58:03 am »
OK, fixed in rev10499. Thanks.

BTW: your test code has exceed the macro expansion limit level value(5). :)
« Last Edit: September 11, 2015, 02:59:37 am by ollydbg »
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline alnik

  • Single posting newcomer
  • *
  • Posts: 2
Re: Bug report. Infinite loop in ParserThread::SkipBlock
« Reply #3 on: September 11, 2015, 01:47:41 pm »
Thank you!
Is it possible to increase the limit value, for example, up to 8? ;)

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5247
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Bug report. Infinite loop in ParserThread::SkipBlock
« Reply #4 on: September 11, 2015, 02:48:41 pm »
Thank you!
Is it possible to increase the limit value, for example, up to 8? ;)
1,The recently added feature(macro check on every identifier like token, around rev10438 to rev10474) does not works 100% like what a C preprocessor does. Actual C preprocessor is more complex, and has more expansion rules.

2, I don't have a strong option about what the expansion level limit it should be, 5 is OK as I can see, but may a larger is better? I would like see any one's suggestion.
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline MortenMacFly

  • Administrator
  • Lives here!
  • *****
  • Posts: 9508
Re: Bug report. Infinite loop in ParserThread::SkipBlock
« Reply #5 on: September 25, 2015, 12:19:05 pm »
2, I don't have a strong option about what the expansion level limit it should be, 5 is OK as I can see, but may a larger is better? I would like see any one's suggestion.
Sounds to me like simply make it an option... it strongly depends on the code and macro-foo the user uses, so the is no "best" value. Using 5 as the default seems OK though.
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: http://www.codeblocks.org/docs/main_codeblocks_en.html
C::B FAQ: http://wiki.codeblocks.org/index.php?title=FAQ