Если main программы возвращает i32, почему $? (по измерениям вызвавшей его оболочки) усечено до 8 бит? - PullRequest
2 голосов
/ 09 июля 2020

Извините за такой нубский вопрос, но почему результат не 516?

define i32 @main()
{
        %1 = add i32 6, 500
        %2 = add i32 5, 5
        %3 = add i32 %1, %2
        ret i32 %3
}

http://llvm.org/docs/LangRef.html#integer -тип

i32 32-битное целое число.

Использование:

./lli Program.ir; echo $?
4

Заранее спасибо

Ответы [ 2 ]

3 голосов
/ 09 июля 2020

Выход код (я собираюсь различать guish выход значение , возвращаемое вашей программой, от выхода код сделано доступный процессу, который запустил вашу программу) на самом деле в UNIX подобных операционных системах представляет собой совокупность нескольких различных элементов, один из которых является значением выхода. См., Например, эту ссылку , которая содержит (с моими выделение и [extra information]):

Не путайте статус выхода программы [value] со статусом завершения процесса [code]. Помимо завершения программы sh, существует множество способов завершения процесса. В случае, если завершение процесса вызвано завершением программы (т.е. exit), однако, статус выхода программы [value] становится частью статуса завершения процесса [code].

Макрос для получения фактического статуса выхода из процесса (см. здесь ) указывает:

Если WIFEXITED истинно статуса, этот макрос возвращает младшие 8 бит значения статуса выхода из дочернего процесса.

Это также указывается фактическим источником код системного вызова Linux exit_group, который в конечном итоге вызывается exit:

SYSCALL_DEFINE1(exit_group, int, error_code)
{
    do_group_exit((error_code & 0xff) << 8);
    /* NOTREACHED */
    return 0;
}

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

do_group_exit(ksig->info.si_signo)

Другими словами, он также должен помещать другие вещи в код выхода процесса, например какой сигнал его завершил (если он был завершен сигналом), сбросил ли он ядро ​​и т. д. Вот почему значение выхода ограничено меньшим диапазоном, чем вы ожидаете.

Стандарт ISO (C11) также позволяет это в 7.22.4.4 The exit function /5 (поскольку возврат целочисленного значения из main() эквивалентен вызову exit() с этим значением:

Наконец, управление возвращается в среду хоста. Если значение статуса равно нулю или EXIT_SUCCESS, возвращается форма успешного завершения статуса, определяемая реализацией. . Если значение статуса EXIT_FAILURE, возвращается форма, определяемая реализацией неудачного завершения статуса. В противном случае возвращаемый статус определяется реализацией.

3 голосов
/ 09 июля 2020

Код выхода процесса в Unix составляет всего 8 бит. Любое большее значение обрезается независимо от того, задействован ли LLVM:

$ ( exit 516 ); echo $?
4
...