vectorgraphics / asymptote

2D & 3D TeX-Aware Vector Graphics Language
https://asymptote.sourceforge.io/
GNU General Public License v3.0
550 stars 90 forks source link

Language Server segfaults when used from an editor #394

Open MicroTransactionsMatterToo opened 1 year ago

MicroTransactionsMatterToo commented 1 year ago

The language server crashes with a segfault when I try to use it from within Emacs, or any other editor. Executing asy -lsp from the terminal works correctly, but when I try to actually use it, it always segfaults. I haven't been able to figure out why. I'm certain that LSP is enabled. I haven't been able to replicate the issue outside of an editor. As best I can tell, it's not the lack of a TTY, so I'm kind of stumped.

MicroTransactionsMatterToo commented 1 year ago

Got some more information. The segmentation fault occurs when using the TCP Server mode as well. I ended up having to use it because I couldn't find another way to debug the communication between the editor and the language server. I've attached the asy LSP output and the data that was going over the TCP socket. I'm not sure how to debug this using the normal stdio model, but I think it's caused by a bug somewhere in the parsing.

Socket TcpServer 127.0.0.1 3040 start.
New client 127.0.0.1 connect.
runtime: Stack overflow or segmentation fault: rerun with -nothreads
[1]    15942 IOT instruction (core dumped)  /usr/bin/asy -vvv -lsp -lspport=3040
Content-Length: 4261

{
    "id": 1,
    "params": {
        "rootUri": null,
        "initializationOptions": {},
        "capabilities": {
            "workspace": {
                "workspaceEdit": {
                    "failureHandling": "abort",
                    "documentChanges": true
                },
                "didChangeConfiguration": {
                    "dynamicRegistration": true
                },
                "executeCommand": {},
                "applyEdit": true,
                "semanticTokens": {
                    "refreshSupport": true
                },
                "configuration": true,
                "symbol": {
                    "symbolKind": {
                        "valueSet": [
                            16,
                            23,
                            10,
                            21,
                            9,
                            3,
                            5,
                            13,
                            17,
                            18,
                            4,
                            11,
                            7,
                            25,
                            1,
                            15,
                            22,
                            14,
                            20,
                            2,
                            12,
                            26,
                            8,
                            24,
                            6,
                            19
                        ]
                    },
                    "dynamicRegistration": true,
                    "tagSupport": {
                        "valueSet": [
                            1
                        ]
                    }
                },
                "diagnostics": {
                    "refreshSupport": true
                },
                "codeLens": {
                    "refreshSupport": true
                },
                "workspaceFolders": true,
                "inlayHint": {
                    "refreshSupport": true
                }
            },
            "textDocument": {
                "completion": {
                    "dynamicRegistration": true,
                    "completionItemKind": {
                        "valueSet": [
                            22,
                            16,
                            15,
                            11,
                            13,
                            4,
                            7,
                            6,
                            9,
                            21,
                            8,
                            10,
                            24,
                            18,
                            17,
                            12,
                            20,
                            19,
                            3,
                            1,
                            25,
                            5,
                            23,
                            2,
                            14
                        ]
                    },
                    "completionList": {
                        "itemDefaults": [
                            "editRange",
                            "insertTextFormat",
                            "data"
                        ]
                    },
                    "completionItem": {
                        "labelDetailsSupport": true,
                        "documentationFormat": [
                            "markdown",
                            "plaintext"
                        ],
                        "insertTextModeSupport": {
                            "valueSet": [
                                2
                            ]
                        },
                        "resolveSupport": {
                            "properties": [
                                "detail",
                                "documentation",
                                "additionalTextEdits"
                            ]
                        },
                        "snippetSupport": true,
                        "deprecatedSupport": true,
                        "insertReplaceSupport": true,
                        "tagSupport": {
                            "valueSet": [
                                1
                            ]
                        }
                    },
                    "insertTextMode": 2
                },
                "typeHierarchy": {
                    "dynamicRegistration": true
                },
                "implementation": {
                    "dynamicRegistration": true,
                    "linkSupport": true
                },
                "typeDefinition": {
                    "dynamicRegistration": true,
                    "linkSupport": true
                },
                "documentHighlight": {
                    "dynamicRegistration": true
                },
                "selectionRange": {
                    "dynamicRegistration": true
                },
                "publishDiagnostics": {
                    "dataSupport": true,
                    "versionSupport": true,
                    "relatedInformation": true,
                    "codeDescriptionSupport": true,
                    "tagSupport": {
                        "valueSet": [
                            1,
                            2
                        ]
                    }
                },
                "documentLink": {
                    "dynamicRegistration": true,
                    "tooltipSupport": true
                },
                "formatting": {
                    "dynamicRegistration": true
                },
                "inlayHint": {
                    "dynamicRegistration": true,
                    "resolveSupport": {
                        "properties": [
                            "textEdits",
                            "label.command"
                        ]
                    }
                },
                "signatureHelp": {
                    "dynamicRegistration": true,
                    "contextSupport": true,
                    "signatureInformation": {
                        "parameterInformation": {
                            "labelOffsetSupport": true
                        },
                        "activeParameterSupport": true,
                        "documentationFormat": [
                            "markdown",
                            "plaintext"
                        ]
                    }
                },
                "diagnostic": {
                    "dynamicRegistration": true,
                    "relatedDocumentSupport": true
                },
                "semanticTokens": {
                    "formats": [
                        "relative"
                    ],
                    "augmentsSyntaxTokens": true,
                    "tokenModifiers": [
                        "abstract",
                        "async",
                        "declaration",
                        "documentation",
                        "readonly",
                        "static",
                        "modification",
                        "definition",
                        "defaultLibrary",
                        "deprecated"
                    ],
                    "requests": {
                        "range": true,
                        "full": {
                            "delta": true
                        }
                    },
                    "tokenTypes": [
                        "struct",
                        "decorator",
                        "number",
                        "enum",
                        "namespace",
                        "class",
                        "type",
                        "string",
                        "method",
                        "event",
                        "interface",
                        "property",
                        "operator",
                        "comment",
                        "enumMember",
                        "modifier",
                        "function",
                        "typeParameter",
                        "macro",
                        "variable",
                        "keyword",
                        "parameter",
                        "regexp"
                    ],
                    "dynamicRegistration": true,
                    "overlappingTokenSupport": false,
                    "multilineTokenSupport": true
                },
                "declaration": {
                    "dynamicRegistration": true,
                    "linkSupport": true
                },
                "callHierarchy": {
                    "dynamicRegistration": true
                },
                "references": {
                    "dynamicRegistration": true
                },
                "colorProvider": {
                    "dynamicRegistration": true
                },
                "rename": {
                    "prepareSupport": true,
                    "dynamicRegistration": true,
                    "prepareSupportDefaultBehavior": 1
                },
                "documentSymbol": {
                    "symbolKind": {
                        "valueSet": [
                            16,
                            23,
                            10,
                            21,
                            9,
                            3,
                            5,
                            13,
                            17,
                            18,
                            4,
                            11,
                            7,
                            25,
                            1,
                            15,
                            22,
                            14,
                            20,
                            2,
                            12,
                            26,
                            8,
                            24,
                            6,
                            19
                        ]
                    },
                    "dynamicRegistration": true,
                    "hierarchicalDocumentSymbolSupport": true,
                    "tagSupport": {
                        "valueSet": [
                            1
                        ]
                    }
                },
                "rangeFormatting": {
                    "dynamicRegistration": true
                },
                "definition": {
                    "dynamicRegistration": true,
                    "linkSupport": true
                },
                "codeLens": {
                    "dynamicRegistration": true
                },
                "synchronization": {
                    "dynamicRegistration": true,
                    "willSaveWaitUntil": true,
                    "willSave": true,
                    "didSave": true
                },
                "codeAction": {
                    "dataSupport": true,
                    "dynamicRegistration": true,
                    "isPreferredSupport": true,
                    "resolveSupport": {
                        "properties": [
                            "edit"
                        ]
                    },
                    "codeActionLiteralSupport": {
                        "codeActionKind": {
                            "valueSet": [
                                "quickfix",
                                "refactor",
                                "refactor.extract",
                                "refactor.inline",
                                "refactor.rewrite",
                                "source.fixAll",
                                "source.organizeImports"
                            ]
                        }
                    }
                },
                "hover": {
                    "dynamicRegistration": true,
                    "contentFormat": [
                        "markdown",
                        "plaintext"
                    ]
                }
            },
            "general": {
                "regularExpressions": {
                    "engine": "ECMAScript"
                },
                "markdown": {
                    "version": "3.2.2",
                    "parser": "Python-Markdown"
                }
            },
            "window": {
                "workDoneProgress": true,
                "showDocument": {
                    "support": true
                },
                "showMessage": {
                    "messageActionItem": {
                        "additionalPropertiesSupport": true
                    }
                }
            }
        },
        "clientInfo": {
            "version": "1.25.0",
            "name": "Sublime Text LSP"
        },
        "rootPath": null,
        "workspaceFolders": null,
        "processId": 16463
    },
    "jsonrpc": "2.0",
    "method": "initialize"
}
MicroTransactionsMatterToo commented 1 year ago

Did a bit more digging, the segfault occurs at asymptote/LspCpp/src/jsonrpc/RemoteEndPoint.cpp:387. It seems to be a segfault caused by the JSON parsing. I'm not familiar enough with the code base to figure out exactly why though.

MicroTransactionsMatterToo commented 1 year ago

Done more digging. It seems to segfault if any property value in the JSON is greater in length than 1295. It also seems to segfault depending on the number of child objects in capabilities.textDocument. Seems to be a memory error somewhere.

MicroTransactionsMatterToo commented 1 year ago

Also, if it's of use, the commit hash I used when compiling from source was aa9f81bad9478bfe8b2ab5fc5376c19c6c79c708. Output of asy --version is

Asymptote version 2.87-4 [(C) 2004 Andy Hammerlindl, John C. Bowman, Tom Prince]

ENABLED OPTIONS:
V3D      3D vector graphics output
WebGL    3D HTML rendering
OpenGL   3D OpenGL rendering
SSBO     GLSL shader storage buffer objects
GSL      GNU Scientific Library (special functions)
FFTW3    Fast Fourier transforms
Eigen    Eigenvalue library
XDR      External Data Representation (portable binary file format for V3D)
CURL     URL support
LSP      Language Server Protocol
Readline Interactive history and editing
Sigsegv  Distinguish stack overflows from segmentation faults
GC       Boehm garbage collector
threads  Render OpenGL in separate thread

DISABLED OPTIONS:
johncbowman commented 9 months ago

Does commit 081db9d0865403a5d82a749e58f035479193ca8a solve the problem?

johncbowman commented 7 months ago

Is this issue still present with Asymptote 2.87?

MicroTransactionsMatterToo commented 7 months ago

I’ll check later today and get back to you.Many Thanks,Ennis MasseyOn 28/02/2024, at 8:22 AM, John Bowman @.***> wrote: Is this issue still present with Asymptote 2.87?

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you authored the thread.Message ID: @.***>

MicroTransactionsMatterToo commented 7 months ago

Unfortunately it doesn't seem to have been resolved, in 2.87 or compiling from git. Behaviour is identical, although I haven't done a deep dive into it. I'm running it on Arch Linux, I haven't tested it in WSL or other distros.

asy --version output for the two versions I tried is:

Asymptote version 2.88-0 [(C) 2004 Andy Hammerlindl, John C. Bowman, Tom Prince]

ENABLED OPTIONS:
V3D      3D vector graphics output
WebGL    3D HTML rendering
OpenGL   3D OpenGL rendering
SSBO     GLSL shader storage buffer objects
GSL      GNU Scientific Library (special functions)
FFTW3    Fast Fourier transforms
Eigen    Eigenvalue library
XDR      External Data Representation (portable binary file format for V3D)
CURL     URL support
LSP      Language Server Protocol
Readline Interactive history and editing
Sigsegv  Distinguish stack overflows from segmentation faults
GC       Boehm garbage collector
threads  Render OpenGL in separate thread

DISABLED OPTIONS:

and

Asymptote version 2.87git [(C) 2004 Andy Hammerlindl, John C. Bowman, Tom Prince]

ENABLED OPTIONS:
V3D      3D vector graphics output
WebGL    3D HTML rendering
OpenGL   3D OpenGL rendering
SSBO     GLSL shader storage buffer objects
GSL      GNU Scientific Library (special functions)
FFTW3    Fast Fourier transforms
XDR      External Data Representation (portable binary file format for V3D)
CURL     URL support
LSP      Language Server Protocol
Readline Interactive history and editing
Sigsegv  Distinguish stack overflows from segmentation faults
GC       Boehm garbage collector
threads  Render OpenGL in separate thread

DISABLED OPTIONS:
Eigen    Eigenvalue library
jamievlin commented 5 months ago

Can you please detail the steps to reproduce this? (In particular, which asymptote file are you working with - if possible, strip out any confidential data, or are you in a project?) - this would help me quite a bit

MicroTransactionsMatterToo commented 5 months ago

It's unfortunately not a specific file, any attempt to use the LSP from any editor causes the issue. However, after pulling the most recent version and compiling it with -O0 and -g, I get exceptions instead of segfaults. This occurs with both stdio and TCP server modes.

The exception is shown below:

Socket TcpServer 127.0.0.1 3040 start.
asymptote: New client 127.0.0.1 connect.
asymptote: Reason:Exception  when process requestnotification message:
asymptote: _Map_base::at
asymptote: content:
asymptote: {"params":{"processId":271635,"initializationOptions":{},"rootPath":null,"capabilities":{"textDocument":{"documentHighlight":{"dynamicRegistration":true},"implementation":{"linkSupport":true,"dynamicRegistration":true},"synchronization":{"willSave":true,"didSave":true,"willSaveWaitUntil":true,"dynamicRegistration":true},"rename":{"prepareSupportDefaultBehavior":1,"prepareSupport":true,"dynamicRegistration":true},"documentSymbol":{"symbolKind":{"valueSet":[12,10,3,5,15,13,22,11,17,20,4,8,7,6,25,18,24,23,2,26,16,21,14,9,19,1]},"tagSupport":{"valueSet":[1]},"hierarchicalDocumentSymbolSupport":true,"dynamicRegistration":true},"hover":{"contentFormat":["markdown","plaintext"],"dynamicRegistration":true},"semanticTokens":{"tokenModifiers":["async","declaration","deprecated","documentation","static","modification","definition","readonly","abstract","defaultLibrary"],"dynamicRegistration":true,"multilineTokenSupport":true,"requests":{"range":true,"full":{"delta":true}},"augmentsSyntaxTokens":true,"tokenTypes":["function","number","enum","macro","namespace","class","event","variable","string","enumMember","decorator","interface","comment","modifier","method","operator","type","struct","typeParameter","property","regexp","parameter","keyword"],"overlappingTokenSupport":false,"formats":["relative"]},"diagnostic":{"relatedDocumentSupport":true,"dynamicRegistration":true},"documentLink":{"tooltipSupport":true,"dynamicRegistration":true},"typeDefinition":{"linkSupport":true,"dynamicRegistration":true},"completion":{"insertTextMode":2,"completionItem":{"documentationFormat":["markdown","plaintext"],"insertTextModeSupport":{"valueSet":[2]},"labelDetailsSupport":true,"insertReplaceSupport":true,"snippetSupport":true,"tagSupport":{"valueSet":[1]},"deprecatedSupport":true,"resolveSupport":{"properties":["detail","documentation","additionalTextEdits"]}},"completionList":{"itemDefaults":["editRange","insertTextFormat","data"]},"completionItemKind":{"valueSet":[3,13,12,7,23,6,20,18,8,5,10,2,24,22,9,16,21,17,11,4,15,1,19,25,14]},"dynamicRegistration":true},"selectionRange":{"dynamicRegistration":true},"callHierarchy":{"dynamicRegistration":true},"colorProvider":{"dynamicRegistration":true},"publishDiagnostics":{"versionSupport":true,"codeDescriptionSupport":true,"tagSupport":{"valueSet":[2,1]},"dataSupport":true,"relatedInformation":true},"declaration":{"linkSupport":true,"dynamicRegistration":true},"references":{"dynamicRegistration":true},"codeLens":{"dynamicRegistration":true},"typeHierarchy":{"dynamicRegistration":true},"codeAction":{"resolveSupport":{"properties":["edit"]},"isPreferredSupport":true,"codeActionLiteralSupport":{"codeActionKind":{"valueSet":["quickfix","refactor","refactor.extract","refactor.inline","refactor.rewrite","source.fixAll","source.organizeImports"]}},"dataSupport":true,"dynamicRegistration":true},"definition":{"linkSupport":true,"dynamicRegistration":true},"signatureHelp":{"signatureInformation":{"documentationFormat":["markdown","plaintext"],"parameterInformation":{"labelOffsetSupport":true},"activeParameterSupport":true},"contextSupport":true,"dynamicRegistration":true},"formatting":{"dynamicRegistration":true},"rangeFormatting":{"dynamicRegistration":true},"inlayHint":{"resolveSupport":{"properties":["textEdits","label.command"]},"dynamicRegistration":true}},"window":{"showMessage":{"messageActionItem":{"additionalPropertiesSupport":true}},"showDocument":{"support":true},"workDoneProgress":true},"workspace":{"applyEdit":true,"executeCommand":{},"inlayHint":{"refreshSupport":true},"diagnostics":{"refreshSupport":true},"workspaceEdit":{"failureHandling":"abort","documentChanges":true},"didChangeConfiguration":{"dynamicRegistration":true},"symbol":{"symbolKind":{"valueSet":[12,10,3,5,15,13,22,11,17,20,4,8,7,6,25,18,24,23,2,26,16,21,14,9,19,1]},"tagSupport":{"valueSet":[1]},"dynamicRegistration":true},"configuration":true,"semanticTokens":{"refreshSupport":true},"workspaceFolders":true,"codeLens":{"refreshSupport":true}},"general":{"markdown":{"parser":"Python-Markdown","version":"3.2.2"},"regularExpressions":{"engine":"ECMAScript"}}},"rootUri":null,"clientInfo":{"version":"1.25.0","name":"Sublime Text LSP"},"workspaceFolders":null},"jsonrpc":"2.0","id":1,"method":"initialize"}
MicroTransactionsMatterToo commented 5 months ago

The file I'm using to debug with is:

int a = 3;

struct Test {
    int a;
    int b;
};

Test l = new Test;
l.a;
MicroTransactionsMatterToo commented 5 months ago

Another exception, different this time, now compiled with -O2 instead of -O0

asymptote: Reason:Exception  when process requestnotification message:
asymptote: unordered_map::at
asymptote: content:
asymptote: {"method":"initialize","params":{"clientInfo":{"version":"1.29.0","name":"Sublime Text LSP"},"rootUri":null,"workspaceFolders":null,"initializationOptions":{},"capabilities":{"textDocument":{"hover":{"contentFormat":["markdown","plaintext"],"dynamicRegistration":true},"rename":{"prepareSupportDefaultBehavior":1,"dynamicRegistration":true,"prepareSupport":true},"inlayHint":{"dynamicRegistration":true,"resolveSupport":{"properties":["textEdits","label.command"]}},"typeHierarchy":{"dynamicRegistration":true},"diagnostic":{"relatedDocumentSupport":true,"dynamicRegistration":true},"typeDefinition":{"linkSupport":true,"dynamicRegistration":true},"synchronization":{"didSave":true,"willSaveWaitUntil":true,"dynamicRegistration":true,"willSave":true},"documentSymbol":{"symbolKind":{"valueSet":[4,23,12,3,13,8,9,7,11,6,22,26,20,14,15,10,2,16,17,1,19,18,21,25,5,24]},"dynamicRegistration":true,"hierarchicalDocumentSymbolSupport":true,"tagSupport":{"valueSet":[1]}},"declaration":{"linkSupport":true,"dynamicRegistration":true},"references":{"dynamicRegistration":true},"publishDiagnostics":{"codeDescriptionSupport":true,"versionSupport":true,"dataSupport":true,"relatedInformation":true,"tagSupport":{"valueSet":[2,1]}},"foldingRange":{"foldingRangeKind":{"valueSet":["comment","imports","region"]},"dynamicRegistration":true},"callHierarchy":{"dynamicRegistration":true},"signatureHelp":{"signatureInformation":{"documentationFormat":["markdown","plaintext"],"activeParameterSupport":true,"parameterInformation":{"labelOffsetSupport":true}},"dynamicRegistration":true,"contextSupport":true},"documentLink":{"dynamicRegistration":true,"tooltipSupport":true},"completion":{"insertTextMode":2,"completionItemKind":{"valueSet":[14,22,8,12,3,15,5,4,19,10,6,2,20,25,18,21,13,16,1,9,17,24,7,11,23]},"completionList":{"itemDefaults":["editRange","insertTextFormat","data"]},"completionItem":{"snippetSupport":true,"tagSupport":{"valueSet":[1]},"deprecatedSupport":true,"labelDetailsSupport":true,"documentationFormat":["markdown","plaintext"],"insertReplaceSupport":true,"resolveSupport":{"properties":["detail","documentation","additionalTextEdits"]},"insertTextModeSupport":{"valueSet":[2]}},"dynamicRegistration":true},"definition":{"linkSupport":true,"dynamicRegistration":true},"selectionRange":{"dynamicRegistration":true},"implementation":{"linkSupport":true,"dynamicRegistration":true},"codeAction":{"isPreferredSupport":true,"resolveSupport":{"properties":["edit"]},"dataSupport":true,"dynamicRegistration":true,"codeActionLiteralSupport":{"codeActionKind":{"valueSet":["quickfix","refactor","refactor.extract","refactor.inline","refactor.rewrite","source.fixAll","source.organizeImports"]}}},"semanticTokens":{"formats":["relative"],"tokenTypes":["keyword","struct","interface","macro","typeParameter","namespace","function","modifier","property","operator","type","method","enumMember","comment","string","enum","event","number","parameter","variable","regexp","decorator","class"],"requests":{"range":true,"full":{"delta":true}},"augmentsSyntaxTokens":true,"overlappingTokenSupport":false,"dynamicRegistration":true,"multilineTokenSupport":true,"tokenModifiers":["definition","abstract","documentation","deprecated","readonly","defaultLibrary","declaration","static","modification","async"]},"formatting":{"dynamicRegistration":true},"documentHighlight":{"dynamicRegistration":true},"rangeFormatting":{"rangesSupport":true,"dynamicRegistration":true},"colorProvider":{"dynamicRegistration":true},"codeLens":{"dynamicRegistration":true}},"window":{"showMessage":{"messageActionItem":{"additionalPropertiesSupport":true}},"workDoneProgress":true,"showDocument":{"support":true}},"workspace":{"symbol":{"symbolKind":{"valueSet":[4,23,12,3,13,8,9,7,11,6,22,26,20,14,15,10,2,16,17,1,19,18,21,25,5,24]},"tagSupport":{"valueSet":[1]},"dynamicRegistration":true,"resolveSupport":{"properties":["location.range"]}},"didChangeConfiguration":{"dynamicRegistration":true},"workspaceFolders":true,"codeLens":{"refreshSupport":true},"executeCommand":{},"configuration":true,"applyEdit":true,"workspaceEdit":{"failureHandling":"abort","documentChanges":true},"inlayHint":{"refreshSupport":true},"semanticTokens":{"refreshSupport":true},"diagnostics":{"refreshSupport":true}},"general":{"markdown":{"parser":"Python-Markdown","version":"3.2.2"},"regularExpressions":{"engine":"ECMAScript"}}},"processId":278502,"rootPath":null},"jsonrpc":"2.0","id":1}
jamievlin commented 5 months ago

Thanks for the information. I'll look into this further. My apologies for not getting this done sooner

jamievlin commented 5 months ago

Suspect this might be a race condition somehow considering boost::asio. I'll try to add mutexes

jamievlin commented 5 months ago

@MicroTransactionsMatterToo Do you mind trying the changes in PR #440? (The build system is cmake since I'm developing this on my windows machine which does not have access to make - I did include build instructions in the branch)

This change might mitigate some of the issues you're seeing, but please let me know if it works (or doesn't)