$ systemctl start hoge.service
# うまく起動せず、ステータス確認
$ systemctl status hoge -l
● hoge.service
Loaded: loaded (/usr/lib/systemd/system/hoge.service; disabled; vendor preset: disabled)
Active: active (exited) (Result: exit-code) since Wed 2022-03-09 11:11:11:
Process: 12345 ExecStop=/bin/kill -s QUIT $MAINPID (code=exited, status=1/FAILURE)
Process: 12345 ExecStart=/bin/sh -c ${JAVA_EXEC} ${JAVA_OPTS} /opt/app/${APP_NAME}.jar ${APP_OPTS} (code=exited, status=127)
Main PID: 12345 (code=exited, status=127)
Mar 09 11:11:11 host systemd[1]: Started Host Service
Mar 09 11:11:12 host systemd[1]: hoge.service: main process exited, code=exited, status=127/n/a
ここでsystemctl status で-lオプションを実行する。
systemctlによるデーモンプロセス起動時に、bashのstatus終了コード127で落ちているのがわかる。
127番はコマンドが見つからなかったときに返るエラーというのはわかりますが、エラーの詳細がこれだけではわからない状況です。
https://microsoft.github.io/language-server-protocol/
Language Server Protocolは、IDEとLanguage Serverの間で使われるプロトコルです。
自動補完や、関数などの定義へのジャンプ、関数などの呼び出し元を探したりなど、言語ごとの機能を提供するものです。
Go Language Serverは、このプロトコルに準拠しており、Goに関する上記の機能を提供するものです。
Go Language Serverの1つとして、現在Go公式でサポートしているgoplsがよく使われているようです。
function add(a, b) {
return a + b;
}
add(10, 20)
function sub(a, b) {
return a - b;
}
sub(20, 10)
function constAdd(a) {
const v = 100;
return a + v;
}
constAdd(1);
function constAddLarge(a) {
const v = 100000;
return a + v;
}
constAddLarge(1);
Ldar a1
// Load accumulator with value from register .
Ldarはレジスターからアキュムレータに値を読み込むバイトコードです。
a1は a1レジスタとなり、ここでは引数の2番めの値をアキュムレータに保存します。
実際にバイトコード Ldarの実装を見てみると下記の通りになります。
// Return
//
// Return the value in the accumulator.
IGNITION_HANDLER(Return, InterpreterAssembler) {
UpdateInterruptBudgetOnReturn();
TNode<Object> accumulator = GetAccumulator();
Return(accumulator);
}
subの場合
subの場合は、先程のaddと違うのが、2番目のバイトコードが Sub a0, [0] になっているのが異なります。
それ以外は、基本的にレジスターの値を操作してアキュムレータに結果を書き込み、最後にその値をReturnして返すという大まかな構造は変わりません。
// LdaSmi <imm>
//
// Load an integer literal into the accumulator as a Smi.
IGNITION_HANDLER(LdaSmi, InterpreterAssembler) {
TNode<Smi> smi_int = BytecodeOperandImmSmi(0);
SetAccumulator(smi_int);
Dispatch();
}
// Star0 - StarN
//
// Store accumulator to one of a special batch of registers, without using a
// second byte to specify the destination.
//
// Even though this handler is declared as Star0, multiple entries in
// the jump table point to this handler.
IGNITION_HANDLER(Star0, InterpreterAssembler) {
TNode<Object> accumulator = GetAccumulator();
TNode<WordT> opcode = LoadBytecode(BytecodeOffset());
StoreRegisterForShortStar(accumulator, opcode);
Dispatch();
}
// Jump by the number of bytes represented by the immediate operand |imm|.
IGNITION_HANDLER(Jump, InterpreterAssembler) {
TNode<IntPtrT> relative_jump = Signed(BytecodeOperandUImmWord(0));
Jump(relative_jump);
}