| Bug #33268 | Gcov offsets one line in sql_yacc.yy rules | ||
|---|---|---|---|
| Submitted: | 16 Dec 2007 13:20 | Modified: | 31 Jan 2014 13:04 |
| Reporter: | Ingo Strüwing | Email Updates: | |
| Status: | Won't fix | Impact on me: | |
| Category: | MySQL Server: Compiling | Severity: | S3 (Non-critical) |
| Version: | 5.1.23 | OS: | Linux (Debian x86_64) |
| Assigned to: | CPU Architecture: | Any | |
[31 Jul 2008 16:53]
Ingo Strüwing
The cause of the problem seems to be that bison (yacc) adds a line with "break;" to most executable blocks in sql_yacc.yy when it creates sql_yacc.cc.
For example these lines in sql_yqcc.yy
10569: | HASH_SYM {}
10570: | HIT_LIMIT_SYM {}
10571: | HOSTS_SYM {}
become in sql_yacc.cc:
case 1907:
#line 10569 "sql_yacc.yy"
{}
break;
case 1908:
#line 10570 "sql_yacc.yy"
{}
break;
case 1909:
#line 10571 "sql_yacc.yy"
{}
break;
This means that the break statements are accounted to the next line number in sql_yacc.yy by gcov.
It would be great if bison had an option to put the break statements on the same lines as the last line of each block.
Or if we had a tool that edits sql_yacc.cc after the bison run, at least when building for coverage testing.

Description: After a syntax change with new keywords, I found new keywords uncovered in the grammar rules "keyword:" and "keyword_sp:" (non-reserverd keywords). So I added test statements that cover these lines: TEST SYNCHRONIZE NOW SIGNAL TEST; TEST SYNCHRONIZE NOW SIGNAL CLEAR; Here the token after SIGNAL can be identifier or string. I used the non-reserverd keywords TEST and CLEAR. Now the DGcov output showed: File: sql/sql_yacc.yy ------------------------------------------------------------------------------- . +++++:10259: | SONAME_SYM {} . +++++:10260: | START_SYM {} . +++++:10261: | STOP_SYM {} | #####:10262: | TEST_SYM {} . 1:10263: | TRUNCATE_SYM {} . +++++:10264: | UNICODE_SYM {} . +++++:10265: | UNINSTALL_SYM {} . +++++:10297: | CHAIN_SYM {} . +++++:10298: | CHANGED {} . +++++:10299: | CIPHER_SYM {} | #####:10300: | CLEAR_SYM {} . 1:10301: | CLIENT_SYM {} . +++++:10302: | COALESCE {} . +++++:10303: | CODE_SYM {} So it correctly noticed that the lines with TEST_SYM and CLEAR_SYM are new, but counted their use wrongly to one line below the new lines. To find out how other places in sql_yacc.yy are counted, I added some non-sense code. The test result suggests that [D]Gcov has an offset error for YACC rules, but not for embedded C code: In the test file, the "test_sync_signal_wait test_sync_execute" rule was executed 55 times, the CLEAR rule 3 times, the "CLEAR TIMEOUT" rule never. | -:12411: test_sync_signal_wait test_sync_execute | -:12412: { | 55:12413: if (!Lex->test_sync_req.timeout) | #####:12414: Lex->test_sync_req.timeout= 777; | -:12415: } | 55:12416: | CLEAR_SYM | -:12417: { | 3:12418: Lex->test_sync_req.activation_count= 0; | 3:12419: if (Lex->test_sync_req.activation_count) | #####:12420: Lex->test_sync_req.activation_count= 0; | -:12421: } | 3:12422: | CLEAR_SYM TIMEOUT_SYM | -:12423: { | #####:12424: Lex->test_sync_req.activation_count= 0; | -:12425: } | #####:12426: ; | -:12427: | -:12428:test_sync_signal_wait: | -:12429: SIGNAL_SYM ident_or_text You can see that the embedded C code lines have the expected counts, while in every case the next YACC rule takes the count that applies to its predecessor. How to repeat: See description.