| Угадайте |
[May. 23rd, 2012|11:54 pm] |
А кто угадает город по фоторгафии?

Это мы в отпуск съездили. Вот.
|
|
|
| КулинарноЭ |
[May. 5th, 2012|10:39 pm] |
Приготовил сегодня чипсы по-Хестоновски. Как положено, triple cooked.
Теперь ведь ни в фаш-н-чапс не сходить, ни в макдак. Такими темпами в ресторан можно будет идти только разве что за дефлопе. С семечками кациуса.
|
|
|
| Просьба к Дедушке Морозу |
[Apr. 28th, 2012|11:20 pm] |
До следующего Н.Г. осталось чуть больше полугода, так что самое время отправлять просьбы, если хотите, чтобы они вовремя дошли.
Дедушка Мороз, пожалуйста, сделай так, чтобы все копиразды сдохли нахрен к чертям собачьим как можно быстрее!
Только что вставил второй диск из комплекта Queen “Greatest video hits 1″. Абсолютно лицензионный, купленный лично мной в JB в Сиднее за кровно заработанные пластиковые. Знаете, что мне эта виндовая падла сказала? Что у меня, падшая женщина, конфликт, падшая женщина, где-то между, падшая женщина, DVD приводом, системой и видеокартой, падшая женщина! И предложила, самка собаки, обновить драйвер видеокарты, на мужской половой орган! И проигрывать диск, самка собаки, отказалась!
И это на полностью лицензионной винде на новом нотебяке с последними драйверами!
Я, в принципе, и не собирался диск смотреть на нотебяке, а всего лишь хотел его скопировать на мой MythTV, ибо в наше время терабайтных жестких дисков жонглирование DVD сродни онанизму. Кроме того, DVD эти, даже все из себя лицензионные новорят то и дело испортиться. Короче, когда я вставил диск, виндовый проигрыватель выскочил автоматически. Выскочил только для того, чтобы сообщить мне всю это ценную информацию.
Для меня не составляет никаких проблем скопировать этот диск прямо на линкус машине. Но суть в том, что все, чего эти коперазды добились, заботясь якобы о моем благе – это то, что я не могу просмотреть законно купленный диск на своем честно купленном оборудовании. Вы знаете, во всех остальных отраслях человеческой деятельности подобные финты ушами называются мошенничеством и караются длительными тюремными сроками.
|
|
|
| Неделя оптимизатора |
[Apr. 27th, 2012|11:05 pm] |
Что-то у меня эта неделя проходит под знаком единства и борьбы с оптимизатором компилятора. То я компилятор чем удивлю, то он меня в ответ.
Рисую шаблонный движок для реализации конечных автоматов (Finite state machine). Такое я уже делал раньше, просто сейчас свистелки с перделками нужны оказались совсем другие. Еще было странное желание, чтобы движок мог компилироваться для AVR, Ардуино то бишь. Забегая вперед скажу, что таки сделал в лучшем виде.
В общем, в одном месте у меня получился такой код
typedef void (*stateHandler)();
stateHandler currentState;
// Irrelevant crap skipped
void SetNewState(stateHandler* _newState)
{
if (currentState != _newState)
{
callOnExitFor(currentState);
currentState = _newState;
callOnEnterFor(_newState);
}
}
Настоящий код выглядит совсем не так. Потому что на шаблонах. Но суть от этого не меняется, кроме того, тащить в этот псто всю шаблонную магию мне природная скромность не позволяет. Код позволяет определить набор состояний, каждое из которых обслуживается своей функцией и потом совершать переходы из состояния в состояние путем вызова SetNewState. Собственно состояние определяется функцией- обработчиком этого состояния.
SetNewState проверяет, не переходим ли в то же состояние. Для КА подобные переходы вполне легальны, и даже обычны, хотя и не имеют большого смысла. Задача SetNewState, кроме регистрации следующего состояния, заключается еще и в том, чтобы вызвать функцию-эпилог для прошлого состояния и пролог для нового. Соответственно if нужен для того, чтобы не вызывать эпилог и пролог в случае, когда переходим в то же самое состояние.
Как водится, написал юнит-тест. Набор состояний с функциями-обработчиками, таблица переходов, все дела. Поскольку это юнит-тест, все функции-обработчики оказались одинаковыми и внутри просто увеличивали счетчик вызовов да указатель на себя записывали в переменную, которую я потом ассертом проверял:
stateHandler test_lastState;
int test_Counter;
void InitState()
{
test_lastState = InitState;
++test_Counter;
}
void RunState()
{
test_lastState = RunState;
++test_Counter
}
И так далее. Юнит-тест тривиальнейший, вызываем переход, проверяем, что новое состояние установлено согласно ожидаемому да счетчик вызовов увеличивается правильно.
Потом настала очередь проверить работу обработчиков эпилога и пролога. И вот тут ко мне пришел великий птиц обломинго. При переходе из InitState в RunState ни эпилог, ни пролог не вызывались. По свежему опыту проверил поведение debug сборки и убедился, что чертовщина происходит только в релизе. Было очевидно, что опять что-то соптимизировалось не так и не туда.
Грабли нашлись после взятия всех анализов у оператора if из функции SetNewState. В моем юнит-тесте при переходе из InitState в RunState условие InitState != RunState почему-то всегда вычислялось как false. Оказалось, что в релизной сборке InitState == RunState. Оптимизатор линкера просто взял и слил две одинаковые функции в одну, поскольку посчитал, что они делают абсолютно одно и то же. Откуда ж ему было знать, болезному, что я ожидал, что указатели на InitState и RunState должны различаться?
В итоге движок КА оказался конкретно так сконфужен. И, поскольку в моем случае вероятность того, что в продакшен коде тоже могут потребоваться обработчики разных состояний с абсолютно одинаковым кодом внутри, очень велика, пришлось искать вариант, на который оптимизация компилятора повлиять бы не смогла. В итоге нашел замечательный со всех сторон способ убрать проверки из рантайма и заставить компилятор их сделать во время компиляции.
Но об этом потом.
|
|
|
| Пятницо, да! |
[Apr. 20th, 2012|09:50 pm] |
А я поимел дофига фана на работе.
Сижу, пишу эмулятор сетевого девайса. Даже не девайса, а целой PLC. Хорошо так пишу, натыкаюсь на место, где нужно некий кусок данных зазиповать перед выдачей клиенту. Piece of cake – качаю zlib1.dll с официального сайта, подключаю, пишу йунит-тесты. Все работает аж фуфайко заворачиваеццо.
А потом дернул меня чОрд собрать йунит-тест в релизе. Впрочем, чего это он меня дернул, я обычно все сразу собираю в релизе, а на дебаг переключаюсь только в крайнем случае, когда без дебаггера никуда. Так что вопрос скорее в том, какого лешего я вообще собирал дебаг версию тестов? Впрочем, это неважно, собираю релиз версию юнит-теста, а оно обламывается. У мну йунит-тесты прогоняются как post-build step, соответственно если юнит-тест обламыается, то и билд фейлится.
На этот раз фейл оказался эпичным. Из тех йунит-тестов, которые проверяли zlib функциональность вылезает хаааароший такой Access violation во всю морду при первом же вызове функции из zlib1.dll Что характерно – эти же тесты в дебаге отработали как надо.
Дальше чудесатее и странноватее. В своем коде перетряхнул все, что можно, и что нельзя тоже. Проверил и перепроверил все настройки. Потом еще раз. Затем стал отлаживать disassembly. Обнаружил забавную вещь – вызов zlib функции выглядел как call any_random_address. Запахло расстрелом памяти и прочими heap corruption.
Вынос всего лишнего, в том числе и того, что даже теоретически не могло стрелять по памяти, на картину не повлияло. Debug же сборка продолжала угорать надо мной, выдавая 100% pass безо всяких спецэффектов.
Так бы и не понял, чезанах, если бы не случай.
Препарируя пациента дебаггером в стопицотый раз, обратил внимание, что zlib1.dll отсутствует в списке загруженных модулей. Интересно, что дебаг сборка библиотеку исправно грузила. Релизная же нет – тестовый экзешник запускался даже на машине, куда ни одна версия zlib1.dll еще не добралась. Запускался и валился по AV.
Ага, сказали суровые сибирские мужики. Никаким late binding и LoadLibrary там и не пахло, экзешник динамически линковал zlib1.dll. Только линковал как-то странно.
В итоге, проблема оказалась в том, что все ссылки на импортированные из dll функции линкер зачем-то заботливо потер. В итоге библиотека оказалась как бы слинкована, но ни одна функция из нее в экзешник не импортировалась. Вместо этого импортированные функции указывали куда придется. Интересно, что отключение оптимизации в линковщике (/OPT:ref) проблему убирало (поэтому и дебаг сборка работала, кстати). Но такой вариант меня не устраивал по вполне понятным причинам и мне пришлось искать альтернативные решения.
К слову, в списках рассылки zlib мне удалось найти пару упоминаний о такой проблеме. Проблема проявлялась как раз на такой же версии, как и у меня. Все сошлись во мнении, что линкер офигевал от чего-то, что попало в .lib файл библиотеки, который кто-то заботливо собрал каким то специальным, только одному ему известным способом.
Короче, проблема решилась самостоятельной сборкой zlib из исходников старым добрым компилятором 2005 студии.
Мораль всего этого такова – пишите йунит-тесты вообще для всего, @#$%!!!!. Мне страшно представить объем попаболи, если бы этот бабах случился бы в готовом продукте.
И еще один вопрос остается открытым – КАК?
|
|
|
| Открытие дня |
[Apr. 19th, 2012|03:11 pm] |
Только что с прискорбием узнал, что Build Events в Visual Studio не агрегируются и поэтому не наследуются из Property Sheets. Потомушта это “simple property, not the aggregate one” (пруф).
Пичаль.
|
|
|
| Danger 5 |
[Apr. 2nd, 2012|10:30 pm] |
Посмотрел случайно серию Danger 5. В титрах проскочило “Снято в Южной Австралии”.
Аборигены Южной Австралии, скажите, пожалуйста, у вас там в водопроводную воду никаких полезных веществ не добавляют? А то чуть со смеху не абосралсо.
|
|
|
| РабочеЭ |
[Mar. 28th, 2012|08:56 pm] |
Написал юнит-тест.
В последней строчке его короткое слово FAIL().
Ибо нефиг.
|
|
|
| Снова потребительское |
[Mar. 27th, 2012|12:22 pm] |
Хотел купить себе новый лаптоп. Искал в гуглях, читал всякие информации, обзоры и прочую маркетологическую болтовню
Сейчас один из сайтов выдал контекстную рекламу. Не знаю, связаны ли они с гуглем, или сами догадались, но посоветовали мне нотебяку от Тошибы. Написано, сильно крутой нотебяк для бизнеса, весь из себя i5 и может даже заменть десктоп и всего за полторы штукабаксов. Читаю дальше спецификации. Оказывается, на крутой бызнес-нотебяк установлена 64-битная ось, что есть типа круто. Целых пять строчек спецификаций посвящены подробному описанию того, какой крутой сидиром в оный нотебяк установлен и как много он, этот сидиром, умеет.
А еще туда установлено целых 2 (два) гигабайта памяи.
Я, конечно, знаю, что мир густо населен идиотами, но иногда все же хочется, чтобы из было поменьше, и чтобы кто-нибудь уже сделал нормальный рабочий лаптоп без этого ненужного сидирома и без дурацких конструкций вроде глянцевого экрана и 64-битной видновс на 2 гигах памяти.
Или я губу сильно раскатал?
|
|
|
| navigation |
| [ |
viewing |
| |
most recent entries |
] |
| [ |
go |
| |
earlier |
] |
| |
|
|