Перейти к содержимому
  • 0
Belzebub

Как читать stderr компов?

Вопрос

Рекомендуемые сообщения

Ну для начала будьте добры исходники запускаемой программы

Похоже где-то происходит вызов пустой переменной. Без кода точно никто не скажет, тут не ванги.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Да как решить то я знаю, вопрос был не об этом.

Вопрос был в корявости комповской stderr, его можно как-то починить?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Обвернуть выполняемый код в 

print(xpcall(function()
--code 
end, debug.traceback))

По идее ниче лучше сделать нельзя, поправьте мя, если я не прав

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Вопрос неоднозначный. Как такового файлового потока stderr, по аналогии с реальными машинами, в opencomputers нет. То что вы видите - фактически сообщение об ошибке красного цвета. Если вы хотите самостоятельно обработать ошибку, произошедшую в рантаеме, есть два способа:
Самый простой вариант - pcall

local result, value = pcall (function () --[[ ... ]] end)

Если функция, переданная в pcall первым аргументом, выполнена успешно, первое возвращаемое значение будет true, а все последующие - значения, которые вернула исполняемая функция.

В обратном случае, первым значением pcall вернёт false, а вторым - сообщение об ошибке, которое вам нужно.

Однако, при использовании pcall, вы получите только сообщение об ошибке, но не стек вызовов, который показывает OpenOS.

 

Другой, более навороченный вариант - xpcall

local function errorHandler (errorMessage)
	print ("Runtime error: " .. errorMessage)
	print (debug.traceback ())
end

local result, value = xpcall (function () --[[ ... ]] end, errorHandler)

Если функция, переданная в xpcall выполнена успешно, то возвращаемые значения будут такие же, как и с pcall.

А если во время выполнения функции произойдёт ошибка, то вторым значением xpcall вернёт то, что вернула функция-обработчик.

То есть xpcall вызывает обработчик, вместо того чтобы просто вернуть ошибку.

Но в чём же профит, спросите вы? Тут есть один занятный момент: обработчик ошибок вызывается именно в том месте, в котором произошла ошибка. А это значит, что debug.traceback, вызванный в обработчике, вернёт стек вызовов актуальный для контекста ошибки.

 

Хитрым образом эту фичу использовал @ECS в процессе разработки MineCode IDE для реализации брейкпоинтов:

В том месте кода, где пользователь поставит брейкпоинт, намеренно произойдёт ошибка, которую потом поймает обработчик и покажет отладочную информацию. Таким образом, выполнение программы безопасно прерывается в нужном месте.  

 

Кстати, пожалуй, удобнее всего обрабатывать ошибки так:

local result, value = xpcall (function () --[[ ... ]] end, debug.traceback)
if not result then
  print (value)
end

Поскольку debug.traceback конкатенирует свой аргумент со стеком вызовов.

Изменено пользователем Anon

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
В 25.03.2021 в 14:10, Belzebub сказал:

Да как решить то я знаю, вопрос был не об этом.

Вопрос был в корявости комповской stderr, его можно как-то починить?

Нет, нельзя. В стеке вызовов видно, что ошибка происходит в /lib/process.lua. А происходит она, скорее всего, из-за неверного значения переданного в одну из функций библиотек OpenOS аргумента. Судя по всему, стек вызовов настолько большой, что debug.traceback заменила его часть на "(...tail calls...)". Это недоработка разработчиков самого lua, так как во время отладки важно видеть первые вызовы, а не последние.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
14 часа назад, Anon сказал:

Судя по всему, стек вызовов настолько большой, что debug.traceback заменила его часть на "(...tail calls...)". Это недоработка разработчиков самого lua, так как во время отладки важно видеть первые вызовы, а не последние.

Неправда. Tail call - это вызов, сделанный в строке return:

local function f2()
  return error('tail call')
end
local function f3()
  return f2()
end

print(xpcall(f3, debug.traceback))

--[[
false	input:2: tail call
stack traceback:
	[C]: in function 'error'
	input:2: in function <input:1>
	(...tail calls...)
	[C]: in function 'xpcall'
	input:8: in main chunk
	[C]: in function 'pcall'
	demo.lua:60: in main chunk
	[C]: in ?
]]

Это оптимизация, позволяющая использовать бесконечную рекурсию без переполнения стека - запись о старой функции (её upvalues и тому подобное) удаляется, и её место занимает новая запись.

Без этой оптимизации плохо, поэтому это не недоработка.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

@ProgramCrafter Значит я неправильно понял сообщение об ошибке. Так или иначе, получить полный стектрейс в этом случае не получится.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вы вставили отформатированное содержимое.   Удалить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.


×
×
  • Создать...