Skip to content

Two-phase configuration: freeze point and analysis-phase getters#1993

Draft
Copilot wants to merge 5 commits intomasterfrom
copilot/freeze-configuration-to-avoid-timing-errors
Draft

Two-phase configuration: freeze point and analysis-phase getters#1993
Copilot wants to merge 5 commits intomasterfrom
copilot/freeze-configuration-to-avoid-timing-errors

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 12, 2026

Config reads during AfterConfig.run() (e.g. privatization module construction) see stale values because the autotuner runs afterward and modifies config. This introduces a two-phase configuration mechanism to separate config-building from analysis.

Changes

src/config/gobConfig.ml

  • Added frozen : bool ref flag and is_frozen () / freeze () functions — freeze () permanently prevents further set_* calls
  • Added analysis_read : bool ref flag — set to true once any get_*_analysis call is made; once set, any set_* call raises UsedForAnalysis
  • Added exception UsedForAnalysis of string — raised by any set_* call if analysis_read is set, making configuration timing errors immediately visible
  • Added analysis-phase getters: get_int_analysis, get_bool_analysis, get_string_analysis, get_list_analysis, get_string_list_analysis
  • Added clear_analysis_reads () — resets the analysis_read flag; called automatically by with_immutable_conf on exit so that server-mode config changes between analysis runs continue to work

src/goblint.ml

  • Call GobConfig.freeze () after all config modifications (AutoSoundConfig + AutoTune.chooseConfig) and before do_analyze
AutoSoundConfig.activateLongjmpAnalysesWhenRequired ();
if get_string "ana.specification" <> "" then AutoSoundConfig.enableAnalysesForSpecification ();
if get_bool "ana.autotune.enabled" then AutoTune.chooseConfig file;
GobConfig.freeze ();   (* <-- new: config locked from here *)
file |> do_analyze changeInfo;

How it catches bugs

Analysis code should use get_*_analysis instead of get_* for reads whose results feed into the analysis. Once any such call is made, all subsequent set_* calls raise UsedForAnalysis, pinpointing the timing error immediately rather than silently producing wrong results.

Server mode

freeze () is only called in the non-server path. Server mode continues using with_immutable_conf temporarily per analysis run, which now also calls clear_analysis_reads () on exit so that inter-run config changes via set_* are not blocked by reads from the previous run.

Agent-Logs-Url: https://github.com/goblint/analyzer/sessions/e7f71803-86c8-4b4a-a4cc-78b9bce5ae4b

Co-authored-by: michael-schwarz <13812333+michael-schwarz@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix timing errors by freezing configuration phases Freeze configuration after autotuner, before analysis Apr 12, 2026
Copilot AI requested a review from michael-schwarz April 12, 2026 07:35
@michael-schwarz
Copy link
Copy Markdown
Member

@copilot. This does not address the core issue, the problem is when values are used before the configuration has been built. So there should be two get functions, one for value to be used in the analysis, and one for getting values during building.

If a value is modified after a call to the get variant for analysis, an exception should be raised.

Copilot AI and others added 2 commits April 12, 2026 15:22
…-error detection

Agent-Logs-Url: https://github.com/goblint/analyzer/sessions/1ccb990f-d34c-4830-a4fe-3127d58dabd4

Co-authored-by: michael-schwarz <13812333+michael-schwarz@users.noreply.github.com>
Agent-Logs-Url: https://github.com/goblint/analyzer/sessions/1ccb990f-d34c-4830-a4fe-3127d58dabd4

Co-authored-by: michael-schwarz <13812333+michael-schwarz@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 12, 2026

@copilot. This does not address the core issue, the problem is when values are used before the configuration has been built. So there should be two get functions, one for value to be used in the analy...

Done in commit 2fd6827. The implementation adds:

  • get_int_analysis, get_bool_analysis, get_string_analysis, get_list_analysis, get_string_list_analysis — analysis-phase getters that record which config paths they read into an analysis_reads set.
  • exception UsedForAnalysis of string — raised by any set_* call if the target path was already read via a get_*_analysis function. This makes the timing error immediately visible.
  • clear_analysis_reads () — clears the tracking set; called automatically by with_immutable_conf on exit (server mode), so config changes between analysis runs continue to work.

Example: if privatization code calls get_string_analysis "ana.base.privatization" during AfterConfig.run(), and then the autotuner calls set_string "ana.base.privatization" "...", the exception UsedForAnalysis "ana.base.privatization" is immediately raised, identifying the configuration timing error.

Copilot AI changed the title Freeze configuration after autotuner, before analysis Two-phase configuration: freeze point and analysis-phase getters Apr 12, 2026
@michael-schwarz
Copy link
Copy Markdown
Member

@copilot: The tracking need not be per attribute.

…ttribute hashtable

Agent-Logs-Url: https://github.com/goblint/analyzer/sessions/1445f474-579c-45c1-ae37-d8bd066195d7

Co-authored-by: michael-schwarz <13812333+michael-schwarz@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 12, 2026

@copilot: The tracking need not be per attribute.

Done in commit e620873. Replaced the per-attribute Hashtbl with a single bool ref analysis_read. Once any get_*_analysis call is made the flag is set, and any subsequent set_* raises UsedForAnalysis. clear_analysis_reads () resets the flag (called by with_immutable_conf on exit for server mode).

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Freeze Configuration to Avoid Timing Errors for Configurations

2 participants