2 Commits

Author SHA1 Message Date
ykiko
80090986bf refactor: update kota/codec includes for new kotatsu header layout
kotatsu moved all codec headers into subdirectories; top-level files
like codec/raw_value.h and codec/toml.h no longer exist.

- codec/raw_value.h → removed (re-exported by json/json.h and
  bincode/bincode.h)
- codec/toml.h → codec/toml/toml.h
- codec/json/serializer.h → codec/json/json.h (use umbrella header)

Made-with: Cursor
2026-04-23 03:40:55 +08:00
ykiko
c9ac524df4 fix: prevent worker crashes from null ASTConsumer, invalid FileID, and missing PCH cache dir
Three pre-existing bugs cause worker processes to crash (SEGV/SIGABRT),
which becomes a reliability issue when combined with the respawn mechanism
on low-core CI machines.

- compilation.cpp: Check for null before passing WrapperFrontendAction's
  ASTConsumer to MultiplexConsumer (prevents SEGV in stateless workers
  during PCH builds when CreateASTConsumer fails)
- compilation_unit.cpp: Return empty StringRef on invalid FileID instead
  of asserting (prevents SIGABRT in stateful workers when compilation
  produces an AST with no valid main file, e.g. synthesized default
  commands without system headers)
- compiler.cpp: Create PCH cache directory before sending build request
  to stateless worker (prevents "No such file or directory" when
  load_workspace didn't run due to missing compile_commands.json
- master_server: Make load_workspace a plain synchronous function since
  it contains no async operations
EOF
)

Made-with: Cursor
2026-04-23 03:36:05 +08:00
13 changed files with 35 additions and 19 deletions

View File

@@ -26,7 +26,7 @@
#include "support/path_pool.h"
#include "syntax/dependency_graph.h"
#include "kota/codec/json/serializer.h"
#include "kota/codec/json/json.h"
#include "kota/deco/deco.h"
#include "llvm/Support/FileSystem.h"

View File

@@ -219,9 +219,10 @@ public:
auto CreateASTConsumer(clang::CompilerInstance& instance, llvm::StringRef file)
-> std::unique_ptr<clang::ASTConsumer> final {
return std::make_unique<ProxyASTConsumer>(
WrapperFrontendAction::CreateASTConsumer(instance, file),
unit);
auto consumer = WrapperFrontendAction::CreateASTConsumer(instance, file);
if(!consumer)
return nullptr;
return std::make_unique<ProxyASTConsumer>(std::move(consumer), unit);
}
/// Make this public.

View File

@@ -81,7 +81,8 @@ auto CompilationUnitRef::file_offset(clang::SourceLocation location) -> std::uin
}
auto CompilationUnitRef::file_path(clang::FileID fid) -> llvm::StringRef {
assert(fid.isValid() && "Invalid fid");
if(!fid.isValid())
return {};
if(auto it = self->path_cache.find(fid); it != self->path_cache.end()) {
return it->second;
}

View File

@@ -490,6 +490,22 @@ kota::task<bool> Compiler::ensure_pch(Session& session,
auto completion = std::make_shared<kota::event>();
workspace.pch_cache[path_id].building = completion;
if(workspace.config.project.cache_dir.empty()) {
LOG_WARN("PCH build skipped: cache_dir is not configured");
workspace.pch_cache[path_id].building.reset();
completion->set();
co_return false;
}
// Ensure the PCH cache directory exists.
auto pch_dir = path::join(workspace.config.project.cache_dir, "cache", "pch");
if(auto ec = llvm::sys::fs::create_directories(pch_dir)) {
LOG_WARN("Cannot create PCH cache dir {}: {}", pch_dir, ec.message());
workspace.pch_cache[path_id].building.reset();
completion->set();
co_return false;
}
// Build a new PCH via stateless worker.
worker::BuildParams bp;
bp.kind = worker::BuildKind::BuildPCH;

View File

@@ -14,7 +14,7 @@
#include "syntax/completion.h"
#include "kota/async/async.h"
#include "kota/codec/raw_value.h"
#include "kota/codec/json/json.h"
#include "kota/ipc/codec/json.h"
#include "kota/ipc/lsp/protocol.h"
#include "kota/ipc/peer.h"

View File

@@ -7,7 +7,7 @@
#include "support/logging.h"
#include "kota/codec/json/json.h"
#include "kota/codec/toml.h"
#include "kota/codec/toml/toml.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"

View File

@@ -56,9 +56,9 @@ MasterServer::MasterServer(kota::event_loop& loop,
MasterServer::~MasterServer() = default;
kota::task<> MasterServer::load_workspace() {
void MasterServer::load_workspace() {
if(workspace_root.empty())
co_return;
return;
auto& cfg = workspace.config.project;
@@ -125,7 +125,7 @@ kota::task<> MasterServer::load_workspace() {
if(cdb_path.empty()) {
LOG_WARN("No compile_commands.json found in workspace {}", workspace_root);
co_return;
return;
}
auto count = workspace.cdb.load(cdb_path);
@@ -331,7 +331,7 @@ void MasterServer::register_handlers() {
indexer.schedule();
};
loop.schedule(load_workspace());
load_workspace();
});
peer.on_request(

View File

@@ -12,7 +12,7 @@
#include "server/workspace.h"
#include "kota/async/async.h"
#include "kota/codec/raw_value.h"
#include "kota/codec/json/json.h"
#include "kota/ipc/peer.h"
#include "llvm/ADT/DenseMap.h"
@@ -73,7 +73,7 @@ private:
std::string session_log_dir;
std::string init_options_json; ///< Raw JSON from initializationOptions, consumed once.
kota::task<> load_workspace();
void load_workspace();
using RawResult = kota::task<kota::codec::RawValue, kota::ipc::Error>;
};

View File

@@ -9,7 +9,7 @@
#include "syntax/token.h"
#include "kota/codec/raw_value.h"
#include "kota/codec/json/json.h"
#include "kota/ipc/lsp/protocol.h"
#include "kota/ipc/protocol.h"

View File

@@ -8,8 +8,7 @@
#include "compile/compilation.h"
#include "kota/codec/json/serializer.h"
#include "kota/codec/raw_value.h"
#include "kota/codec/json/json.h"
#include "kota/ipc/codec/json.h"
namespace clice {

View File

@@ -6,7 +6,7 @@
#include "support/filesystem.h"
#include "kota/codec/json/json.h"
#include "kota/codec/toml.h"
#include "kota/codec/toml/toml.h"
namespace clice::testing {

View File

@@ -5,7 +5,7 @@
#include "server/protocol.h"
#include "server/worker_test_helpers.h"
#include "kota/codec/raw_value.h"
#include "kota/codec/json/json.h"
namespace clice::testing {

View File

@@ -6,7 +6,6 @@
#include "server/worker_test_helpers.h"
#include "kota/codec/bincode/bincode.h"
#include "kota/codec/raw_value.h"
namespace clice::testing {