Найти в Дзене
BASH DAYS | Linux Factory

Дебажим PHP скрипт с помощью strace

Разбираемся с PHP скриптом, который при создании файла на диске, выставляет плохие права. Грубо говоря, нужно поставить 777, а у файла права по факту 01411.

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

А жиза заключается в том, что кто-то бездумно пишет код, а кто-то этот код вынужден дебажить. Доказывая что проблема не на сервере, а в кривых руках разработчика.

Вот и вчера.
Ситуация: какой-то php скрипт при создании файла на диске, выставляет плохие права на этот файл. Грубо говоря, нужно поставить 777, а у файла права по факту 01411. Конечно, проблема в сервере! Пусть дядя Рома с этим разбирается. Ладно, за монету и корку хлеба можно и покопаться.

Блин, как я давно с php дел не имел. Пришлось вспоминать всю эту лапшу с ООП.

Так, вдумчиво пробегаюсь глазами по php коду, нахожу функцию, которая ставит права на файл, выглядит это так:

<?php
chmod('test.txt', '777');
?>


Для простоты восприятия, адаптировал под наши с вами реалии. Вроде всё корректно, тошноты пока нет. Что ей надо? Запускаю скрипт, хм… снова получаю вместо 777 какие-то 01411.

А если уберем кавычки? Вдруг это как string воспринимается:

<?php
chmod('test.txt', 777);
?>

Метод тыка не помог, но терпим до последнего. В документацию по chmod в php не лезем. Нас же НЕ просили исправить баг, нас поставили перед фактом — проблемы на сервере. Вот мы и пытаемся доказать обратное.

Расчехляем strace

> strace php app.php

В самом конце видим:

read(3, "<?php\n\nchmod('test.txt', 777);\n\n"..., 4096) = 35
chmod("test.txt", 01411) = 0


Видим знакомое 01411. Доказательства собрали. С серверами всё хорошо, на лицо баг в коде. Несем эту информацию тимлиду, пусть учит разработчика читать документацию и дает ему по шапке.

А что все-таки не так с php скриптом, почему 01411? Вообще это не наше дело. Но если коротко:

В php целые числа могут быть указаны в десятичной, шестнадцатеричной, восьмеричной или двоичной системе. Все это дело должно обозначаться начальным нулем. Наша тема - восьмеричная система. Если перевести 777 в восьмеричную систему получим как раз 1411.

📌А откуда берется 01 перед 1411?? А давай ты сам подумаешь и в комментариях напишешь. А мы тебе дружно лайк поставим.

Ошибка была в том, что в php скрипте число 777 передается как строка. Неважно в скобках оно или нет.

Фикс тут простой, просто вставляем 0 перед 777:

<?php
chmod('test.txt', 0777);
?>


Ну а если хочется без ведущего нуля, то так:

<?php
chmod('test.txt', intval('777', 8));
?>


Вот такие пироги. Можно было бы продолжить метод тыка и вставить сразу 0 перед 777, но повторюсь — нас не просили ничего багфиксить. Не нужно упрощать кому-то работу, это опыт, который ты воруешь у человека.

Пусть лучше лишние полчаса погуглит, посмотрит, зато самостоятельно заполнит свою дофаминоваю яму. И потешет ЭГО новой победой над багом.

Ладно, увидимся, давай!

Рекомендую почитать: