News:

Accounts with zero posts and zero activity during the last months will be deleted periodically to fight SPAM!

Main Menu

Bug report. Infinite loop in ParserThread::SkipBlock

Started by alnik, September 10, 2015, 02:26:35 PM

Previous topic - Next topic

alnik

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

#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!

ollydbg

#1
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:

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.
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.

ollydbg

#2
OK, fixed in rev10499. Thanks.

BTW: your test code has exceed the macro expansion limit level value(5). :)
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.

alnik

Thank you!
Is it possible to increase the limit value, for example, up to 8? ;)

ollydbg

Quote from: alnik on September 11, 2015, 01:47: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.

MortenMacFly

Quote from: ollydbg on September 11, 2015, 02:48:41 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: [url="https://www.codeblocks.org/docs/main_codeblocks_en.html"]https://www.codeblocks.org/docs/main_codeblocks_en.html[/url]
C::B FAQ: [url="https://wiki.codeblocks.org/index.php?title=FAQ"]https://wiki.codeblocks.org/index.php?title=FAQ[/url]