Skip to content

Conversation

@deardeng
Copy link
Contributor

@deardeng deardeng commented Feb 4, 2026

Problem:
When running ./run-be-ut.sh without the --coverage flag using Clang compiler, the build fails with duplicate symbol errors:

ld.lld: error: duplicate symbol: __gcov_fork

defined in libgcov.a(libgcov-interface.o)
defined in libclang_rt.profile-x86_64.a(GCDAProfiling.o)

Root cause analysis:
PR #59543 introduced a condition in be/CMakeLists.txt to guard GCC-style coverage flags (-fprofile-arcs -ftest-coverage -lgcov):

if (NOT (ENABLE_CLANG_COVERAGE STREQUAL "ON" AND COMPILER_CLANG))

The intent was to skip GCC coverage when Clang coverage is active. However, this condition has a logic flaw. When using Clang without --coverage:

  • ENABLE_CLANG_COVERAGE = OFF (default, set in run-be-ut.sh line 88)
  • COMPILER_CLANG = true

The condition evaluates as:
NOT (OFF AND true) = NOT (false) = true

So GCC coverage flags are still added even when using Clang. Clang then implicitly links libclang_rt.profile (which provides its own implementation of __gcov_fork, __gcov_reset, etc.), causing duplicate symbol conflicts with the explicitly linked libgcov.a.

Before PR #59543, coverage flags were unconditionally added for all compilers in MAKE_TEST mode — which also had the same issue with Clang.

Fix:
Replace the condition with if (COMPILER_GCC) so that GCC-style coverage flags are only added when actually using GCC compiler. This cleanly separates the two coverage mechanisms:

  • GCC compiler → automatic GCC coverage via -fprofile-arcs + libgcov
  • Clang compiler → no coverage by default; use --coverage flag to enable Clang coverage via -fprofile-instr-generate
Scenario Before #59543 After #59543 (bug) This fix
GCC, no --coverage GCC coverage GCC coverage GCC coverage
GCC, --coverage GCC coverage GCC coverage GCC coverage
Clang, no --coverage GCC cov (bad) GCC cov (bad) No coverage
Clang, --coverage GCC+Clang(bad) Clang coverage Clang cov

What problem does this PR solve?

Issue Number: close #xxx

Related PR: #xxx

Problem Summary:

Release note

None

Check List (For Author)

  • Test

    • Regression test
    • Unit Test
    • Manual test (add detailed scripts or steps below)
    • No need to test or manual test. Explain why:
      • This is a refactor/code format and no logic has been changed.
      • Previous test can cover this change.
      • No code files have been changed.
      • Other reason
  • Behavior changed:

    • No.
    • Yes.
  • Does this need documentation?

    • No.
    • Yes.

Check List (For Reviewer who merge this PR)

  • Confirm the release note
  • Confirm test cases
  • Confirm document
  • Add branch pick label

Problem:
When running `./run-be-ut.sh` without the `--coverage` flag using Clang
compiler, the build fails with duplicate symbol errors:

  ld.lld: error: duplicate symbol: __gcov_fork
  >>> defined in libgcov.a(libgcov-interface.o)
  >>> defined in libclang_rt.profile-x86_64.a(GCDAProfiling.o)

Root cause analysis:
PR apache#59543 introduced a condition in be/CMakeLists.txt to guard GCC-style
coverage flags (`-fprofile-arcs -ftest-coverage -lgcov`):

  if (NOT (ENABLE_CLANG_COVERAGE STREQUAL "ON" AND COMPILER_CLANG))

The intent was to skip GCC coverage when Clang coverage is active. However,
this condition has a logic flaw. When using Clang without `--coverage`:

  - ENABLE_CLANG_COVERAGE = OFF (default, set in run-be-ut.sh line 88)
  - COMPILER_CLANG = true

The condition evaluates as:
  NOT (OFF AND true) = NOT (false) = true

So GCC coverage flags are still added even when using Clang. Clang then
implicitly links libclang_rt.profile (which provides its own implementation
of __gcov_fork, __gcov_reset, etc.), causing duplicate symbol conflicts
with the explicitly linked libgcov.a.

Before PR apache#59543, coverage flags were unconditionally added for all
compilers in MAKE_TEST mode — which also had the same issue with Clang.

Fix:
Replace the condition with `if (COMPILER_GCC)` so that GCC-style coverage
flags are only added when actually using GCC compiler. This cleanly
separates the two coverage mechanisms:
  - GCC compiler → automatic GCC coverage via -fprofile-arcs + libgcov
  - Clang compiler → no coverage by default; use --coverage flag to
    enable Clang coverage via -fprofile-instr-generate

| Scenario             | Before apache#59543 | After apache#59543 (bug) | This fix    |
|----------------------|---------------|--------------------|-------------|
| GCC, no --coverage   | GCC coverage  | GCC coverage       | GCC coverage|
| GCC, --coverage      | GCC coverage  | GCC coverage       | GCC coverage|
| Clang, no --coverage | GCC cov (bad) | GCC cov (bad)      | No coverage |
| Clang, --coverage    | GCC+Clang(bad)| Clang coverage     | Clang cov   |
@deardeng
Copy link
Contributor Author

deardeng commented Feb 4, 2026

run buildall

@hello-stephen
Copy link
Contributor

Thank you for your contribution to Apache Doris.
Don't know what should be done next? See How to process your PR.

Please clearly describe your PR:

  1. What problem was fixed (it's best to include specific error reporting information). How it was fixed.
  2. Which behaviors were modified. What was the previous behavior, what is it now, why was it modified, and what possible impacts might there be.
  3. What features were added. Why was this function added?
  4. Which code was refactored and why was this part of the code refactored?
  5. Which functions were optimized and what is the difference before and after the optimization?

@doris-robot
Copy link

TPC-H: Total hot run time: 31568 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit cbc223b7423953bcbeebc864f3933daf5084864a, data reload: false

------ Round 1 ----------------------------------
q1	17617	5273	5027	5027
q2	2074	322	198	198
q3	10197	1271	749	749
q4	10212	845	307	307
q5	7559	2142	1865	1865
q6	194	180	152	152
q7	868	745	599	599
q8	9278	1377	1031	1031
q9	5142	4793	4883	4793
q10	6810	1929	1565	1565
q11	495	297	270	270
q12	336	373	220	220
q13	17765	4034	3180	3180
q14	245	234	219	219
q15	889	834	810	810
q16	648	679	619	619
q17	630	824	486	486
q18	6783	6376	7505	6376
q19	1314	1063	658	658
q20	424	395	235	235
q21	2949	2388	1919	1919
q22	389	347	290	290
Total cold run time: 102818 ms
Total hot run time: 31568 ms

----- Round 2, with runtime_filter_mode=off -----
q1	5601	5541	5620	5541
q2	276	354	274	274
q3	2428	2902	2613	2613
q4	1540	1894	1565	1565
q5	4894	4676	4497	4497
q6	225	179	150	150
q7	2019	2105	1709	1709
q8	2517	2416	2461	2416
q9	7643	7391	7337	7337
q10	2776	2958	2562	2562
q11	540	459	433	433
q12	615	667	566	566
q13	3538	3974	3225	3225
q14	266	287	267	267
q15	828	800	787	787
q16	631	677	637	637
q17	1057	1239	1283	1239
q18	7427	7533	7242	7242
q19	835	785	782	782
q20	1949	2043	1882	1882
q21	4463	4150	4158	4150
q22	587	541	513	513
Total cold run time: 52655 ms
Total hot run time: 50387 ms

@doris-robot
Copy link

ClickBench: Total hot run time: 28.69 s
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/clickbench-tools
ClickBench test result on commit cbc223b7423953bcbeebc864f3933daf5084864a, data reload: false

query1	0.05	0.05	0.04
query2	0.09	0.05	0.04
query3	0.25	0.08	0.08
query4	1.61	0.12	0.10
query5	0.26	0.24	0.26
query6	1.16	0.66	0.65
query7	0.03	0.03	0.02
query8	0.05	0.04	0.04
query9	0.57	0.50	0.50
query10	0.55	0.55	0.55
query11	0.14	0.09	0.09
query12	0.14	0.10	0.10
query13	0.63	0.61	0.62
query14	1.05	1.06	1.03
query15	0.87	0.86	0.87
query16	0.39	0.39	0.41
query17	1.19	1.12	1.12
query18	0.22	0.21	0.21
query19	1.98	1.93	1.92
query20	0.02	0.01	0.01
query21	15.41	0.24	0.15
query22	4.95	0.06	0.06
query23	15.89	0.29	0.11
query24	1.62	0.89	0.71
query25	0.11	0.06	0.08
query26	0.14	0.13	0.14
query27	0.06	0.08	0.06
query28	4.72	1.13	0.98
query29	12.56	3.90	3.17
query30	0.29	0.13	0.14
query31	2.82	0.64	0.40
query32	3.23	0.61	0.51
query33	3.21	3.25	3.30
query34	16.42	5.33	4.72
query35	4.76	4.82	4.79
query36	0.65	0.50	0.48
query37	0.11	0.06	0.07
query38	0.07	0.05	0.04
query39	0.05	0.03	0.03
query40	0.19	0.15	0.16
query41	0.08	0.04	0.03
query42	0.04	0.03	0.03
query43	0.05	0.04	0.04
Total cold run time: 98.68 s
Total hot run time: 28.69 s

@doris-robot
Copy link

BE UT Coverage Report

Increment line coverage 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 52.56% (19370/36854)
Line Coverage 36.05% (179959/499196)
Region Coverage 32.41% (139486/430400)
Branch Coverage 33.42% (60424/180796)

@github-actions github-actions bot added the approved Indicates a PR has been approved by one committer. label Feb 4, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Feb 4, 2026

PR approved by at least one committer and no changes requested.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 4, 2026

PR approved by anyone and no changes requested.

@hello-stephen
Copy link
Contributor

BE Regression && UT Coverage Report

Increment line coverage 100% (0/0) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 71.60% (25859/36118)
Line Coverage 54.29% (270344/498001)
Region Coverage 51.96% (225934/434816)
Branch Coverage 53.23% (96632/181526)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by one committer. reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants