terryyin / lizard

A simple code complexity analyser without caring about the C/C++ header files or Java imports, supports most of the popular languages.
Other
1.85k stars 250 forks source link

Crash when parsing Linux kernel #51

Closed tholin closed 9 years ago

tholin commented 9 years ago

Parsing the Linux kernel will crash with an error like this:

Traceback (most recent call last):
  File "/home/cocobo/repository/lizard/lizard", line 6, in <module>
    lizard_main(sys.argv)
  File "/home/cocobo/repository/lizard/lizard.py", line 923, in lizard_main
    printer(result, options)
  File "/home/cocobo/repository/lizard/lizard.py", line 800, in print_result
    code_infos, option.extensions, scheme)
  File "/home/cocobo/repository/lizard/lizard.py", line 768, in print_and_save_modules
    for module_info in all_modules:
  File "/home/cocobo/repository/lizard/lizard.py", line 624, in __call__
    filename, open(filename, 'rU').read())
  File "/home/cocobo/repository/lizard/lizard.py", line 635, in analyze_source_code
    for _ in tokens:
  File "/home/cocobo/repository/lizard/lizard.py", line 611, in token_processor_for_function
    reader.state(token)
  File "/home/cocobo/repository/lizard/lizard.py", line 323, in state
    self._state(token)
  File "/home/cocobo/repository/lizard/lizard.py", line 437, in _state_template_in_name
    if self.bracket_stack.pop() != "<":
IndexError: pop from empty list

The problem is in the file drivers/isdn/hardware/avm/avmcard.h Here is a small cutout

#define SEND_POLL       0x72    /*
                     * after load <- RECEIVE_POLL
                     */
#define SEND_INIT       0x11    /*
                     * first message <- RECEIVE_INIT
                     * int32 NumApplications  int32
                     * NumNCCIs int32 BoardNumber
                     */
#define RECEIVE_POLL        0x32    /*
                     * <- after SEND_POLL
                     */
#define RECEIVE_INIT        0x27    /*
                     * <- after SEND_INIT int32 length
                     * byte total length b1struct board
                     * driver revision b1struct card
                     * type b1struct reserved b1struct
                     * serial number b1struct driver
                     * capability b1struct d-channel
                     * protocol b1struct CAPI-2.0
                     * profile b1struct capi version
                     */
#define RECEIVE_MESSAGE     0x21    /*
                     * <- after SEND_MESSAGE int32
                     * AppllID int32 Length capi-data
                     * ....
                     */
static inline void b1_put_word(unsigned int base, unsigned int val)
{
    b1_put_byte(base, val & 0xff);
    b1_put_byte(base, (val >> 8) & 0xff);
    b1_put_byte(base, (val >> 16) & 0xff);
    b1_put_byte(base, (val >> 24) & 0xff);
}

The crash seems to be caused by those <- in the comment sections.

terryyin commented 9 years ago

Thanks for the bug report. I've fixed it.

The bug wasn't because of the content of the comment, but the macro definition. Lizard tried to read until the end of the line with it starts with #,

I've made a new release in pypi.

Please kindly verify the fix and close the issue. Thanks:-)

tholin commented 9 years ago

The fix works for avmcard.h but now I get another crash in lib/div64.c Here is another cutout.

uint32_t __attribute__((weak)) __div64_32(uint64_t *n, uint32_t base)
{
    uint64_t rem = *n;
    uint64_t b = base;
    uint64_t res, d = 1;
    uint32_t high = rem >> 32;

    while ((int64_t)b > 0 && b < rem) {
        b = b+b;
        d = d+d;
    }

    do {
        if (rem >= b) {
            rem -= b;
            res += d;
        }
        b >>= 1;
        d >>= 1;
    } while (d);
}
Traceback (most recent call last):
  File "/home/cocobo/repository/lizard/lizard", line 6, in <module>
    lizard_main(sys.argv)
  File "/home/cocobo/repository/lizard/lizard.py", line 942, in lizard_main
    printer(result, options)
  File "/home/cocobo/repository/lizard/lizard.py", line 819, in print_result
    code_infos, option.extensions, scheme)
  File "/home/cocobo/repository/lizard/lizard.py", line 787, in print_and_save_modules
    for module_info in all_modules:
  File "/home/cocobo/repository/lizard/lizard.py", line 643, in __call__
    filename, open(filename, 'rU').read())
  File "/home/cocobo/repository/lizard/lizard.py", line 654, in analyze_source_code
    for _ in tokens:
  File "/home/cocobo/repository/lizard/lizard.py", line 630, in token_processor_for_function
    reader.state(token)
  File "/home/cocobo/repository/lizard/lizard.py", line 323, in state
    self._state(token)
  File "/home/cocobo/repository/lizard/lizard.py", line 456, in _state_template_in_name
    if self.bracket_stack.pop() != "<":
IndexError: pop from empty list
terryyin commented 9 years ago

Ok. Fixed and I've tested it against the linux kernel myself. It took like 3 minutes with a -t8 option on my computer.

thanks!

terryyin commented 9 years ago
==========================================================================================
Total nloc  Avg.nloc  Avg CCN  Avg token  Fun Cnt  Warning cnt   Fun Rt   nloc Rt
------------------------------------------------------------------------------------------
   9849441        20     4.38     136.23   357394        14824      0.04    0.22
tholin commented 9 years ago

Thanks for the quick fix. Problem resolved.