ltcmelo / psychec

A compiler frontend for the C programming language
BSD 3-Clause "New" or "Revised" License
535 stars 39 forks source link

Segfault in SyntaxNode::kind() on Else-If-Statement #125

Closed lorenz9314 closed 10 months ago

lorenz9314 commented 1 year ago

Description

Trying to compile the appended code snippet with ./cnip --C-infer causes the program to segfault in SyntaxNode::kind() as the node appears to be a null pointer. I also appended a full stack trace.

static void ccid3_hc_tx_update_x(struct sock *sk, ktime_t *stamp)
{
 struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk);
 __u64 min_rate = 2 * hc->tx_x_recv;
 const __u64 old_x = hc->tx_x;
 ktime_t now = stamp ? *stamp : ktime_get_real();

 if (ccid3_hc_tx_idle_rtt(hc, now) >= 2) {
  min_rate = rfc3390_initial_rate(sk);
  min_rate = max(min_rate, 2 * hc->tx_x_recv);
 }

 if (hc->tx_p > 0) {

  hc->tx_x = min(((__u64)hc->tx_x_calc) << 6, min_rate);
  hc->tx_x = max(hc->tx_x, (((__u64)hc->tx_s) << 6) / TFRC_T_MBI);

 } else if (ktime_us_delta(now, hc->tx_t_ld) - (s64)hc->tx_rtt >= 0) {

  hc->tx_x = min(2 * hc->tx_x, min_rate);
  hc->tx_x = max(hc->tx_x,
          scaled_div(((__u64)hc->tx_s) << 6, hc->tx_rtt));
  hc->tx_t_ld = now;
 }

 if (hc->tx_x != old_x) {
  ccid3_pr_debug("X_prev=%u, X_now=%u, X_calc=%u, "
          "X_recv=%u\n", (unsigned int)(old_x >> 6),
          (unsigned int)(hc->tx_x >> 6), hc->tx_x_calc,
          (unsigned int)(hc->tx_x_recv >> 6));

  ccid3_update_send_interval(hc);
 }
}

Full stack trace below:

#0  0x00007ffff7cd3b1c in psy::C::SyntaxNode::kind (this=0x0) at /home/user/psychec/C/syntax/SyntaxNode.cpp:47
#1  0x00007ffff7d242df in psy::C::Disambiguator::visitMaybeAmbiguousStatement<psy::C::StatementSyntax> (this=0x7fffffffc6d0, node=@0x5555556dca58: 0x0)
    at /home/user/psychec/C/reparser/Disambiguator.cpp:87
#2  0x00007ffff7d23bc9 in psy::C::Disambiguator::visitIfStatement (this=0x7fffffffc6d0, node=0x5555556dca10) at /home/user/psychec/C/reparser/Disambiguator.cpp:373
#3  0x00007ffff7d1ff94 in psy::C::IfStatementSyntax::dispatchVisit (this=0x5555556dca10, visitor=0x7fffffffc6d0) at /home/user/psychec/C/syntax/SyntaxNodes_Statements.h:185
#4  0x00007ffff7cd4302 in psy::C::SyntaxNode::acceptVisitor (this=0x5555556dca10, visitor=0x7fffffffc6d0) at /home/user/psychec/C/syntax/SyntaxNode.cpp:129
#5  0x00007ffff7cdbd1f in psy::C::SyntaxNode::acceptVisitor (node=0x5555556dca10, visitor=0x7fffffffc6d0) at /home/user/psychec/C/syntax/SyntaxNode.h:96
#6  0x00007ffff7cdb4c1 in psy::C::SyntaxVisitor::visit (this=0x7fffffffc6d0, node=0x5555556dca10) at /home/user/psychec/C/syntax/SyntaxVisitor.cpp:39
#7  0x00007ffff7d24438 in psy::C::Disambiguator::visitMaybeAmbiguousStatement<psy::C::StatementSyntax> (this=0x7fffffffc6d0, node=@0x5555556dd0d0: 0x5555556dca10)
    at /home/user/psychec/C/reparser/Disambiguator.cpp:114
#8  0x00007ffff7d23ade in psy::C::Disambiguator::visitCompoundStatement (this=0x7fffffffc6d0, node=0x5555556dbed8) at /home/user/psychec/C/reparser/Disambiguator.cpp:345
#9  0x00007ffff7d1f60c in psy::C::CompoundStatementSyntax::dispatchVisit (this=0x5555556dbed8, visitor=0x7fffffffc6d0) at /home/user/psychec/C/syntax/SyntaxNodes_Statements.h:79
#10 0x00007ffff7cd4302 in psy::C::SyntaxNode::acceptVisitor (this=0x5555556dbed8, visitor=0x7fffffffc6d0) at /home/user/psychec/C/syntax/SyntaxNode.cpp:129
#11 0x00007ffff7cd4201 in psy::C::SyntaxNode::visitChildren (this=0x5555556dbe88, visitor=0x7fffffffc6d0) at /home/user/psychec/C/syntax/SyntaxNode.cpp:107
#12 0x00007ffff7cd431e in psy::C::SyntaxNode::acceptVisitor (this=0x5555556dbe88, visitor=0x7fffffffc6d0) at /home/user/psychec/C/syntax/SyntaxNode.cpp:131
#13 0x00007ffff7cdbd1f in psy::C::SyntaxNode::acceptVisitor (node=0x5555556dbe88, visitor=0x7fffffffc6d0) at /home/user/psychec/C/syntax/SyntaxNode.h:96
#14 0x00007ffff7cdb4c1 in psy::C::SyntaxVisitor::visit (this=0x7fffffffc6d0, node=0x5555556dbe88) at /home/user/psychec/C/syntax/SyntaxVisitor.cpp:39
#15 0x00007ffff7d24526 in psy::C::SyntaxCorrelationDisambiguator::visitTranslationUnit (this=0x7fffffffc6d0, node=0x5555556dba20) at /home/user/psychec/C/reparser/Disambiguator_SyntaxCorrelation.cpp:47
#16 0x00007ffff7cf7834 in psy::C::TranslationUnitSyntax::dispatchVisit (this=0x5555556dba20, visitor=0x7fffffffc6d0) at /home/user/psychec/C/syntax/SyntaxNodes_Declarations.h:600
#17 0x00007ffff7cd4302 in psy::C::SyntaxNode::acceptVisitor (this=0x5555556dba20, visitor=0x7fffffffc6d0) at /home/user/psychec/C/syntax/SyntaxNode.cpp:129
#18 0x00007ffff7cdbd1f in psy::C::SyntaxNode::acceptVisitor (node=0x5555556dba20, visitor=0x7fffffffc6d0) at /home/user/psychec/C/syntax/SyntaxNode.h:96
#19 0x00007ffff7cdb4c1 in psy::C::SyntaxVisitor::visit (this=0x7fffffffc6d0, node=0x5555556dba20) at /home/user/psychec/C/syntax/SyntaxVisitor.cpp:39
#20 0x00007ffff7d2353a in psy::C::Disambiguator::disambiguate (this=0x7fffffffc6d0) at /home/user/psychec/C/reparser/Disambiguator.cpp:41
#21 0x00007ffff7d2aa83 in psy::C::Reparser::reparse (this=0x7fffffffc760, tree=0x5555556d3340) at /home/user/psychec/C/reparser/Reparser.cpp:65
#22 0x00007ffff7cb6c38 in psy::C::SyntaxTree::buildFor (this=0x5555556d3340, syntaxCategory=psy::C::SyntaxTree::SyntaxCategory::UNSPECIFIED) at /home/user/psychec/C/SyntaxTree.cpp:290
#23 0x00007ffff7cb6447 in psy::C::SyntaxTree::parseText (text=..., textPPState=psy::C::TextPreprocessingState::Preprocessed, textCompleteness=psy::C::TextCompleteness::Fragment, parseOptions=..., 
    filePath="test.c", syntaxCategory=psy::C::SyntaxTree::SyntaxCategory::UNSPECIFIED) at /home/user/psychec/C/SyntaxTree.cpp:136
#24 0x0000555555634883 in cnip::CCompilerFrontend::constructSyntaxTree (this=0x5555556d5130, 
    srcText="# 1 \"<stdin>\"\n# 1 \"<built-in>\"\n# 1 \"<command-line>\"\n# 31 \"<command-line>\"\n# 1 \"/usr/include/stdc-predef.h\" 1 3 4\n\n# 1 \"/usr/include/stdc-predef.h\" 3 4\n/* Copyright (C) 1991-2020 Free Software Foundati"..., fi=...) at /home/user/psychec/cnippet/CompilerFrontend_C.cpp:158
#25 0x0000555555634539 in cnip::CCompilerFrontend::preprocess (this=0x5555556d5130, 
    srcText="static void ccid3_hc_tx_update_x(struct sock *sk, ktime_t *stamp)\n{\n struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk);\n __u64 min_rate = 2 * hc->tx_x_recv;\n const __u64 old_x = hc->tx_x;\n ktime_t n--Type <RET> for more, q to quit, c to continue without paging--
ow "..., fi=...) at /home/user/psychec/cnippet/CompilerFrontend_C.cpp:128
#26 0x0000555555633cdc in cnip::CCompilerFrontend::run (this=0x5555556d5130, 
    srcText="static void ccid3_hc_tx_update_x(struct sock *sk, ktime_t *stamp)\n{\n struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk);\n __u64 min_rate = 2 * hc->tx_x_recv;\n const __u64 old_x = hc->tx_x;\n ktime_t now "..., fi=...) at /home/user/psychec/cnippet/CompilerFrontend_C.cpp:65
#27 0x000055555566751c in cnip::Driver::execute (this=0x7fffffffd4d7, argc=1, argv=0x7fffffffd5e8) at /home/user/psychec/cnippet/Driver.cpp:131
#28 0x00005555556104ca in main (argc=3, argv=0x7fffffffd5e8) at /home/user/psychec/cnippet/Main.cpp:32

Version

fe1dabb6e85c4cabf0c623721d82f665b7d94216

Expected behavior

Ideally cnip should be able to process else-if-statements, as they are covered by the C-Standard, but at least terminate gracefully if this kind of error cannot be recovered from.

Thank you very much!

ltcmelo commented 1 year ago

Thanks for the report @lorenz9314 .

ltcmelo commented 10 months ago

Fixed by @ludanpr in PR https://github.com/ltcmelo/psychec/pull/129.