Что означает (k)ill в меню перерыва iex?

Я получаю доступ к меню Break в eix 1.8.2, нажимая CTRL + C. Оно выглядит так:

BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
       (v)ersion (k)ill (D)b-tables (d)istribution

Сначала я предполагал, что kill будет похож на abort (т. е. просто завершает сеанс), но нет. Вместо этого нажатие k создает дамп ядра и предлагает дополнительные параметры:

iex(1)> 
BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
       (v)ersion (k)ill (D)b-tables (d)istribution
k


Process Information

--------------------------------------------------
=proc:<0.105.0>
State: Waiting
Spawned as: erlang:apply/2
Spawned by: <0.75.0>
Message queue length: 0
Number of heap fragments: 1
Heap fragment data: 5
Link list: [{to,<0.64.0>,#Ref<0.720592203.270008322.27074>}]
Reductions: 4202
Stack+heap: 233
OldHeap: 0
Heap unused: 177
OldHeap unused: 0
BinVHeap: 1
OldBinVHeap: 0
BinVHeap unused: 46421
OldBinVHeap unused: 46422
Memory: 2804
Stack dump:
Program counter: 0x000000001f8230e0 (io:execute_request/2 + 200)
CP: 0x0000000000000000 (invalid)
arity = 0

0x000000001ddcee08 Return addr 0x000000001f8a4ba0 ('Elixir.IEx.Server':io_get/3 + 96)
y(0)     #Ref<0.720592203.270008322.27074>
y(1)     {false,{get_line,unicode,<<"iex(1)> ">>}}
y(2)     <0.64.0>

0x000000001ddcee28 Return addr 0x000000001d53ecf8 (<terminate process normally>)
y(0)     <0.105.0>
y(1)     <0.75.0>
Internal State: ACT_PRIO_NORMAL | USR_PRIO_NORMAL | PRQ_PRIO_NORMAL
(k)ill (n)ext (r)eturn:

Если я снова нажму k, я получу еще один дамп ядра. Нажатие n также дает мне дамп ядра, и я думаю, что это то же самое, что и нажатие k. Последняя опция, r, делает разные вещи в зависимости от того, что я сделал ранее. Если я нажал k или n всего несколько раз, он просто проигнорирует это, и мне придется дважды нажимать ввод. iex интерпретирует второй ввод как обычно и возвращает nil.

(k)ill (n)ext (r)eturn:
r

nil

Если я нажимал k и n несколько раз, это либо делало это:

(k)ill (n)ext (r)eturn:
r
** (EXIT from #PID<0.104.0>) shell process exited with reason: killed

Interactive Elixir (1.8.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> 
09:39:57.929 [info]  Application iex exited: killed

или это:

(k)ill (n)ext (r)eturn:
r

09:46:20.268 [info]  Application iex exited: killed

09:46:20.269 [info]  Application elixir exited: killed

09:46:20.274 [error] GenServer IEx.Pry terminating
** (stop) killed
Last message: {:EXIT, #PID<0.88.0>, :killed}
State: 1

или это:

(k)ill (n)ext (r)eturn:
r
Logger - error: {removed_failing_handler,'Elixir.Logger'}
Logger - error: {removed_failing_handler,'Elixir.Logger'}
Logger - error: {removed_failing_handler,'Elixir.Logger'}

Я не уверен, как он решает, какое из этих сообщений должно отображаться.

Мне действительно любопытно, что делает (k)ill и его подопции, и я с нетерпением жду возможности узнать об этом. Любое направление приветствуется, спасибо!


person Alex V    schedule 20.06.2019    source источник
comment
не о том вопрос, но если вы хотите выйти из iex, то можете нажать control +\   -  person apelsinka223    schedule 20.06.2019


Ответы (2)


Команда kill перебирает все запущенные процессы, и для каждого из них выводит кучу информации и спрашивает, нужно ли:

  • убить его и перейти к следующему процессу (k)
  • перейти к следующему процессу, не убивая этот (n), или
  • прекратите убивать процессы и вернитесь в оболочку (r).

Может быть сложно определить процесс, который вы хотите убить. Одна вещь, на которую вы можете обратить внимание, это строка Dictionary, которая для большинства длительно выполняющихся процессов имеет запись $initial_call, сообщающую вам, какой модуль содержит код, который выполняет этот процесс. Например:

Dictionary: [{'$ancestors',[<0.70.0>]},{iex_evaluator,ack},{'$initial_call',{'Elixir.IEx.Evaluator',init,4}}]

Различные сообщения отображаются в зависимости от того, какой процесс (ы) вы убили. Например, похоже, что Elixir.IEx.Evaluator — это процесс, запускающий оболочку Elixir, которая выдает вам сообщение об ошибке shell process exited with reason: killed.

С одной стороны, это показывает отказоустойчивость приложения Elixir: даже если процесс где-то внутри системы имеет ошибку (в данном случае вызванную явным завершением процесса), супервизоры пытаются перезапустить рассматриваемый процесс. и держать всю систему в рабочем состоянии.


На самом деле, я никогда не использовал этот способ уничтожения процессов в работающей системе. Если вы знаете идентификатор процесса («pid») процесса, который хотите убить, вы можете ввести что-то вроде этого в оболочку:

Process.exit(pid("0.10.0"), :kill)

без необходимости просматривать список процессов.

person legoscia    schedule 21.06.2019

Глядя на исходный код:

case 'k':
    process_killer();

а также

switch(j) {
case 'k':
            ASSERT(erts_init_process_id != ERTS_INVALID_PID);
            /* Send a 'kill' exit signal from init process */
            erts_proc_sig_send_exit(NULL, erts_init_process_id,
                                    rp->common.id, am_kill, NIL,
                                    0);
case 'n': br = 1; break;
case 'r': return;
default: return;
}

k, по-видимому, предназначен для перечисления и уничтожения отдельных процессов путем отправки им сигнала уничтожения. Другой вывод связан с тем, что он зависит от того, как каждый процесс обрабатывает сигнал.

person Adam Millerchip    schedule 21.06.2019
comment
Спасибо за ссылку на исходный код, я искал соответствующий код в исходном коде iex в репозитории Elixir на GitHub, мне не приходило в голову, что я должен был смотреть исходный код BEAM. - person Alex V; 22.06.2019