kondybas: (100 - мои пять копеек...)
kondybas ([personal profile] kondybas) wrote2016-10-23 12:28 pm

Технологічне


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

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

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

Відкриваю у `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 замість #!, інтерпретатору команд стає трохи зле.

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

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

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

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

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

[identity profile] henryflowerjr.livejournal.com 2016-10-23 11:04 pm (UTC)(link)
Інтерпретатор команд, бачучи ці чарівні символи, читає строчку до кінця

the interpretation of shebang lines is done by a kernel. the shell itself has nothing to do w/ it.

[identity profile] kondybas.livejournal.com 2016-10-28 08:07 am (UTC)(link)
Так, це вірно, дякую.
(deleted comment)

[identity profile] kondybas.livejournal.com 2016-10-29 02:36 pm (UTC)(link)
Ага, чудовий аналіз. Респект.

У випадку 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 2016-10-29 14:38 (UTC)

[identity profile] henryflowerjr.livejournal.com 2016-10-29 03:00 pm (UTC)(link)
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

[identity profile] kondybas.livejournal.com 2016-10-29 03:32 pm (UTC)(link)
Мені у фрі комфортно та затишно, на відміну від лінуксів. Звісно, це справа смаку.

[identity profile] henryflowerjr.livejournal.com 2016-10-29 04:00 pm (UTC)(link)
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.

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

[identity profile] henryflowerjr.livejournal.com 2016-10-29 03:11 pm (UTC)(link)
LJ thinks I'm a damn spammer!

[identity profile] kondybas.livejournal.com 2016-10-29 03:16 pm (UTC)(link)
Спробуй ще раз, фільтр для нефрендів :)

[identity profile] click0.livejournal.com 2016-10-28 07:31 am (UTC)(link)
Очень полезная утилитка
hexdump, hd — ASCII, decimal, hexadecimal, octal dump

Например, hexdump -C filename

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

[identity profile] click0.livejournal.com 2016-10-28 08:03 am (UTC)(link)
А еще есть truss и ktrace :)

[identity profile] kondybas.livejournal.com 2016-10-28 08:08 am (UTC)(link)
Ну от я якось не дійшов до рівня трасування системних викликів :) Трошки раніше настало прозріння.