以下の内容はhttps://ujimushisradjp.hatenablog.jp/entry/2024/11/06/213100より取得しました。


LanguageServer.jl(本当はSymbolServer.jl)で不意にドツボった話

はじめに

Emacseglot-jlを使って関数等の補完をしていた時に, 自作のモジュールを読み込んだ時に不意にLanguageServerが落ちることが頻発した。 というか,100%落ちてしまいどうにもならなくなった。

丸二日調べてようやく原因が分かった。

で,結構他の人でもはまるかもしれないと思い,ここに情報を公開することとした。

どんな時に発生するか?

パッケージの構成としては,次の図のようなフォルダ構造になるのだが,この構造の MyPackage/srcの中に.で始まるファイルやディレクトリが存在するとLanguageServerの エラーが発生するようだ。

エラー発生原因の箇所

個人的に問題と思っているのはSymbolServer/src/utils.jlのところで,ソースは次のような感じ。

function sha2_256_dir(path, sha=zeros(UInt8, 32))
    (uperm(path) & 0x04) != 0x04 && return
    startswith(path, ".") && return
    if isfile(path) && endswith(path, ".jl")
        s1 = open(path) do f
            sha2_256(f)
        end
        sha .+= s1
    elseif isdir(path)
        for f in readdir(path)
            sha = sha2_256_dir(joinpath(path, f), sha)
        end
    end
    return sha
end

ここで,startswidth(path, ".") && returnreturnが問題で, 本来shaに準ずるものが返らないといけないのが,値無しで返っている。

上の関数の呼び出し元はsha_pkg という関数で,ソースは次の通り。

function sha_pkg(manifest_dir::AbstractString, pe::PackageEntry)
    relpath = path(pe)
    isa(relpath, String) || return nothing
    src_path = normpath(joinpath(manifest_dir, relpath, "src"))
    return isdir(src_path) ? sha2_256_dir(src_path) : nothing
end

つまり,パッケージのsrc以下の.jlファイルのsha2サム値の合計をpkgのshaサム値として返そうというものらしい。

しかし,何からの原因でsrcフォルダ内に.で始まるファイル等があるとLanguageServerでエラーが発生することになる。

影響

srcフォルダの中にEmacs等で一時的に.で始まるファイルを作成したり,現実的には.gitignoreファイルを作成した時に 必ずエラーが発生する等の影響があると思われる。

対策

srcフォルダの中には.で始まるファイル・フォルダを作成しないようにする必要がある。

悪用方法

srcフォルダの中に.gitignoreを作成して,他人にLanguageServerの補完をさせないようにする等の 活用方法が考えられる。

さいごに

なお,本来の対策としては

    startwith(path, ".") && return

のところを

    startwith(path, ".") && return sha

とすると,.で始まるファイルだった時はshaをそのまま返すので 簡易的な対策になると思います。というかそうすべき。

ですが,私は性格が悪いので,黙ってこのまま放置しようと思います。 誰か正義のミカタがissueを上げることを期待してこの記事を終わりにしようと思います。




以上の内容はhttps://ujimushisradjp.hatenablog.jp/entry/2024/11/06/213100より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14