kondybas: (100 - мои пять копеек...)
[personal profile] kondybas

Я вчора промудохався півдня, відловлюючи бридкий і складний баг.

Почалось все з того, що в мене перестала працювати скриптова система керування серваком. Видавало щось отакого типу:

Відкриваю катом. Нє, всьо ок:

Відкриваю у `ee` - фєншуйчик!

Ну, думаю, відкрию редактором `le`! А там все теж зашибись:

Відкриваю у встроєному редакторі `deco` - і знов невдача!

Ах, ти ж! - думаю, а єслі у вінді? Перекидаю у FAR - благолєпіє повне:

А шо ще в мене є під рукою? Ага! Ще більш-менш є more-less! Ага, спіймався, падлюка!

Ну, і канєшно ж у `vi` цю холєру вдалося ампутувати:


Після недовгого гугління з'ясувалась причина. Деякі редактори зберігаючи файло у кодуванні 65001 ака UTF8, пхають у перші два байти файлу т.зв. BOM - byte order marker. U+FEFF. Big-endian, little-endian - вот єто вот всьо, вся ета русофобія. Ідея в тому, щоб натикаючись на файло, текстові процесори розуміли, з чим мають справу. Як бачимо, більшість редакторів розуміє це добре, навіть не виводячи цей службовий символ на табло.

Проблема ж в тому, що криворукий тупоголовий уєбан, що вигадав це "покращення", й гадки не мав, що в ніксах текстові файли можуть бути скриптами. І що спецом для цього діла перші два байти кожного скрипта починаються з магічної сигнатури 'шебанг' - #!
Інтерпретатор команд, бачучи ці чарівні символи, читає строчку до кінця, а там має бути прописаний шлях до інтерпретатора тієї скриптової мови, якою написаний наш скрипт. Вигляда це все як `#!/bin/sh`, `#!/usr/local/bin/perl` або `#!/usr/local/bin/php`. Ясний пень, що бачучи во пєрвих строках моєво пісьма FEFF замість #!, інтерпретатору команд стає трохи зле.

Ми всі чудово знаємо, в якій осі екзекутабельність файла визначається не пермішнами, а розширенням, і де такі неявні фокуси із вмістом файлів можуть минати безкарно. От тепер скажіть, що мені даремно хочеться повідривать їм ноги і дать цими ногами по голові!

Date: 23 Oct 2016 10:35 (UTC)

(no subject)

From: [identity profile] sirozhagladkov.livejournal.com
А по-моєму, каждий редактор по-своїму хароший. Главне, шоб це був vi.
Date: 23 Oct 2016 15:07 (UTC)

(no subject)

From: [identity profile] kondybas.livejournal.com
В мене чогось з vi не зрослося. Я команди знаю, але нема напрацьованого автоматизму, коли просто не думаєш, як зробить те чи інше. А без автоматизму він дещо важкуватий. А мені вже ліньки ламать себе об коліно і розучувать гами.
Date: 23 Oct 2016 15:57 (UTC)

(no subject)

From: [identity profile] juan-gandhi.livejournal.com
Да вендовой фигней не надо пользоваться, конечно. Это они эти бомы вставляют.
Date: 23 Oct 2016 16:09 (UTC)

(no subject)

From: [identity profile] kondybas.livejournal.com
Дык, понятно. Но уж редкостно противное западло. Нетривиальное.
Date: 23 Oct 2016 23:04 (UTC)

(no subject)

From: [identity profile] henryflowerjr.livejournal.com
Інтерпретатор команд, бачучи ці чарівні символи, читає строчку до кінця

the interpretation of shebang lines is done by a kernel. the shell itself has nothing to do w/ it.
Date: 28 Oct 2016 08:07 (UTC)

(no subject)

From: [identity profile] kondybas.livejournal.com
Так, це вірно, дякую.
(deleted comment)
Date: 29 Oct 2016 14:36 (UTC)

(no subject)

From: [identity profile] kondybas.livejournal.com
Ага, чудовий аналіз. Респект.

У випадку FreeBSD, якщо мені не зраджує маразм, коли /bin/sh не може визначити метод запуску екзекутабла, він вважає його скриптом для себе, і форкає екземпляр себе, який і виконує команди в скрипті одна за одною:
rpi.lan # ls -l bom
-rwx------  1 root  wheel  41 Oct 29 14:31 bom

rpi.lan # cat bom
## no shebang here
cat $0
echo $$
#####

rpi.lan # echo $$
17988

rpi.lan # ./bom
## no shebang here
cat $0
echo $$
#####

97221
rpi.lan #
Edited Date: 29 Oct 2016 14:38 (UTC)
Date: 29 Oct 2016 15:00 (UTC)

(no subject)

From: [identity profile] henryflowerjr.livejournal.com
yup. turns out, /bin/sh in fbsd doesn't follow the APUE advice too: (tryexec() function):

svnweb.freebsd.org/base/stable/11/bin/sh/exec.c?view=markup

and similarly to bash, it looks for the NULL char to decide if it should try another execve run!

btw, the code is *much* more readable compared to bash. fbsd can be so cute!

PS
glad you liked the text
Date: 29 Oct 2016 15:32 (UTC)

(no subject)

From: [identity profile] kondybas.livejournal.com
Мені у фрі комфортно та затишно, на відміну від лінуксів. Звісно, це справа смаку.
Date: 29 Oct 2016 16:00 (UTC)

(no subject)

From: [identity profile] henryflowerjr.livejournal.com
linux lacks taste, that's hard to deny, but unfortunately it has a bandwagon effect.

I was an avid fbsd user, but eventually got tired of constantly broken ruby gems that were (are) tested on osx/linux only, npm pkgs that regularly failed to compile under fbsd, etc. perhaps fbsd is still fine for network engineers or if you work for a big fbsd shop.

I suspect if not for its permissive license (as compared to that gnu/linux nonsense), fbsd would have been dead by now.
Date: 29 Oct 2016 16:07 (UTC)

(no subject)

From: [identity profile] kondybas.livejournal.com
Не одною бсд-ліцензією жива фря. А якість портів визначається виключно якістю майнтейнерів. Якщо майнтейнер неспроможний якісно пропатчить кде під фрю... Ну, такоє.
Date: 29 Oct 2016 15:11 (UTC)

(no subject)

From: [identity profile] henryflowerjr.livejournal.com
LJ thinks I'm a damn spammer!
Date: 29 Oct 2016 15:16 (UTC)

(no subject)

From: [identity profile] kondybas.livejournal.com
Спробуй ще раз, фільтр для нефрендів :)
Date: 28 Oct 2016 07:31 (UTC)

(no subject)

From: [identity profile] click0.livejournal.com
Очень полезная утилитка
hexdump, hd — ASCII, decimal, hexadecimal, octal dump

Например, hexdump -C filename
Date: 28 Oct 2016 07:36 (UTC)

(no subject)

From: [identity profile] kondybas.livejournal.com
Та в хексі подивитись не проблема. Проблема в тому, що ідея псування текстового файлу, та ще й у неочевидний і не відображуваний більшістю редакторів спосіб - занадто нетривіальна, аби локалізувати проблему. В той момент, коли я зрозумів, що проблема саме у невідображуваних символах, інструмент вже не був проблемою. Але дійти думки про підміну сигнатури я мусив аналітично, без хекс-редакторів тощо. В цьому була складність проблеми.
Date: 28 Oct 2016 08:03 (UTC)

(no subject)

From: [identity profile] click0.livejournal.com
А еще есть truss и ktrace :)
Date: 28 Oct 2016 08:08 (UTC)

(no subject)

From: [identity profile] kondybas.livejournal.com
Ну от я якось не дійшов до рівня трасування системних викликів :) Трошки раніше настало прозріння.