Sitelet https://github.com/tensorflow/tensorflow/pull/126064
Skip to content

Fix configure.py crash when clang reports no parseable version - #126064

Open
VaggelisGian wants to merge 5 commits into
tensorflow:masterfrom
VaggelisGian:fix-configure-clang-version-none
Open

Fix configure.py crash when clang reports no parseable version#126064
VaggelisGian wants to merge 5 commits into
tensorflow:masterfrom
VaggelisGian:fix-configure-clang-version-none

Conversation

@VaggelisGian

Copy link
Copy Markdown

Fixes #125939

Summary

./configure.py aborted with a traceback when the clang executable does not report a parseable version, which happens with wrappers such as ccache (the reporter's which clang resolves to /usr/lib64/ccache/clang). Two crashes were reachable:

  1. retrieve_clang_version returns None after printing "WARNING: current clang installation version unknown.", and disable_clang_offsetof_extension then crashed on int(clang_version.split('.')[0]) with AttributeError: 'NoneType' object has no attribute 'split'. Non-numeric version strings crashed the same line with ValueError.
  2. If the wrapper exits without printing anything to stdout, run_shell returns an empty string and retrieve_clang_version itself crashed with IndexError: string index out of range while taking the first character of the output.

The fix guards the consumer so unknown or non-numeric versions skip the -Wno-gnu-offsetof-extensions flag exactly like every confirmed version outside 16 and 17, and normalizes the parsing in retrieve_clang_version so empty, whitespace-only, unrecognized, adjacent-marker and truncated banners all flow into the existing unknown-version warning instead of raising.

One deliberate behavior change worth flagging: banners without a version token no longer print the misleading "current clang installation is not a release version" warning that master produced by accident (that check used to run over characters of a string instead of tokens), and a token-free banner starting with a digit is now reported as an unknown version instead of as a bogus one-digit version. Version-bearing outputs behave identically to master.

Testing

Direct call matrix on disable_clang_offsetof_extension:

None / '' / 'unknown' -> no write, no crash
'16.0.0', '17.1.8'    -> writes build --copt=-Wno-gnu-offsetof-extensions
'22.1.8', '15.x', '18.x' -> no write, byte identical to master output

On master, None reproduced the exact error from the issue:

AttributeError: 'NoneType' object has no attribute 'split'

Monkeypatched run_shell harness over retrieve_clang_version plus the full retrieve-and-consume flow:

empty stdout, whitespace only, banner without token, digit-initial token-free
banner, adjacent "clang version " separators, truncated marker:
    all return None with the unknown-version warning, no crash end to end
'clang version 22.1.8'            -> returns 22.1.8
'Ubuntu clang version 18.0.0git'  -> returns 18.0.0 with prerelease warning

On master the empty-output input reproduced:

IndexError: string index out of range

Lint and compile:

$ python -m py_compile configure.py          # exit 0
$ pylint --rcfile=tensorflow/tools/ci_build/pylintrc configure.py
Your code has been rated at 10.00/10         # same as the unmodified file

No bazel run was needed: configure.py sits outside the bazel graph (the root BUILD exports it as a plain data file) and every check above exercises the changed functions directly.

retrieve_clang_version returns None when the clang executable does not
report a parseable version, which happens with wrappers such as ccache
or any tool whose --version banner lacks a usable version token.
disable_clang_offsetof_extension then crashed with AttributeError while
deciding whether to add -Wno-gnu-offsetof-extensions for clang 16 and
17. Non-numeric version strings would crash the same way with
ValueError. Both cases now skip the flag, matching every confirmed
version outside 16 and 17; the existing "current clang installation
version unknown" warning still prints.

Test Plan:
  python -m py_compile configure.py
  python -m pylint --rcfile=tensorflow/tools/ci_build/pylintrc \
      configure.py  # rated 10.00/10, same as master
  Direct call matrix on disable_clang_offsetof_extension: None, empty
  string and 'unknown' return without writing; '16.0.0' and '17.1.8'
  write build --copt=-Wno-gnu-offsetof-extensions; '22.1.8', '15.x'
  and '18.x' write nothing, byte identical to master bazelrc output.
  On master, None reproduced "AttributeError: 'NoneType' object has no
  attribute 'split'" from issue 125939.
retrieve_clang_version indexed the first character of whatever the
clang executable printed, so a wrapper that exits with nothing on
stdout crashed with IndexError. The parsed result is now always
handled as a token list: an empty or unrecognized banner reaches the
existing unknown-version warning and returns None, and an adjacent
or truncated "clang version " marker does the same instead of raising
IndexError. Together with the previous commit this makes configure
survive any clang whose --version output cannot be parsed.

Version-bearing outputs are unchanged. One deliberate difference:
banners without a version token no longer print the misleading
"not a release version" warning that master produced by accident,
because that check now runs over tokens instead of characters. A
token-free banner starting with a digit used to be reported as a
bogus one digit version; it is now reported as unknown.

Test Plan:
  Monkeypatched run_shell harness over retrieve_clang_version and
  the retrieve plus disable_clang_offsetof_extension flow on this
  branch: empty stdout, whitespace only stdout, banner without a
  version token, digit-initial token-free banner, adjacent
  "clang version " separators and a truncated marker all return
  None with the unknown-version warning and no crash; "clang
  version 22.1.8" returns 22.1.8; "Ubuntu clang version 18.0.0git"
  returns 18.0.0 with the prerelease warning. On master the
  empty-output input reproduced "IndexError: string index out of
  range". pylint --rcfile=tensorflow/tools/ci_build/pylintrc rates
  configure.py 10.00/10.
@google-ml-butler google-ml-butler Bot added the size:S CL Change Size: Small label Aug 25, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request improves the robustness of Clang version detection and parsing in configure.py by handling empty tokens, missing version strings, and non-integer version formats gracefully. The feedback suggests a cleaner approach to handle cases where the 'clang version ' string is not found in the output, recommending consistently returning None with a warning instead of wrapping the unrecognized version in a list.

Comment thread configure.py Outdated
Comment on lines +916 to +923
if len(curr_version_split) > 1:
curr_version = curr_version_split[1].split()[0].split('git')
tokens = curr_version_split[1].split()
if not tokens:
print('WARNING: current clang installation version unknown.\n')
return None
curr_version = tokens[0].split('git')
else:
curr_version = [curr_version]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Instead of falling back to wrapping the unrecognized version string in a list (curr_version = [curr_version]), we can explicitly handle the case where 'clang version ' is not found in the output. This allows us to print the unknown version warning and return None consistently, which is much cleaner and more robust.

  if len(curr_version_split) <= 1:
    print('WARNING: current clang installation version unknown.\n')
    return None

  tokens = curr_version_split[1].split()
  if not tokens:
    print('WARNING: current clang installation version unknown.\n')
    return None

  curr_version = tokens[0].split('git')

@keerthanakadiri
keerthanakadiri requested a review from a team August 25, 2026 07:57
@google-ml-butler google-ml-butler Bot added the awaiting review Pull request awaiting review label Aug 25, 2026
@github-project-automation github-project-automation Bot moved this to Assigned Reviewer in PR Queue Aug 25, 2026
@VaggelisGian

Copy link
Copy Markdown
Author

Note on CI: the two failing checks are pre-existing on master and unrelated to this change.

  • build-windows-x86 / build-and-test fails in //tensorflow/cc/saved_model:fingerprinting_test with runfiles/symlink errors (GetSymbolicLinkTarget cannot open file); master's own CI runs show the same failure class over the past several days.
  • build-arm64 / build-only failed without producing job logs, which points at runner startup rather than the change.

This PR only edits configure.py, which is exported by the root BUILD file as a plain data file and is not part of any bazel target graph.

Split the no "clang version " marker case into its own early return
instead of wrapping the raw banner in a single-element list. Same
observable behavior on every input, clearer control flow.

Test Plan:
  Monkeypatched run_shell matrix rerun after the change: empty stdout,
  whitespace only, banner without token, digit-initial token-free
  banner, adjacent separators and truncated marker all return None
  with the unknown-version warning; 'clang version 22.1.8' returns
  22.1.8; 'Ubuntu clang version 18.0.0git' returns 18.0.0 with the
  prerelease warning. python -m py_compile exit 0; pylint with
  tensorflow/tools/ci_build/pylintrc rates configure.py 10.00/10.
@VaggelisGian

Copy link
Copy Markdown
Author

Addressed the review feedback in 4e43c59: the missing-marker case now returns None with the unknown-version warning through its own early return instead of wrapping the raw banner in a list. Re-ran the behavior matrix afterwards; all eight input classes return exactly what they did before.

@dmiltr3
dmiltr3 self-requested a review August 25, 2026 15:19
@google-ml-butler google-ml-butler Bot added kokoro:force-run Tests on submitted change ready to pull PR ready for merge process labels Aug 25, 2026
@github-project-automation github-project-automation Bot moved this from Assigned Reviewer to Approved by Reviewer in PR Queue Aug 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting review Pull request awaiting review kokoro:force-run Tests on submitted change ready to pull PR ready for merge process size:S CL Change Size: Small

Projects

Status: Approved by Reviewer

Development

Successfully merging this pull request may close these issues.

configure failes at clang_version

4 participants