Hatred's Log Place

DON'T PANIC!

Nov 8, 2022 - 1 minute read - Electronic

PCB: Castellated Holes

Они же:

В общем речь о переходных отверстиях по краю платы, которые “разрезаны” пополам и используются для краевого монтажа собранного модуля на другую плату…

Aug 11, 2022 - 1 minute read - Programming

Qt Creator: фикс креша при создании Generic Project

Yet another contribution. В общем :)

Зашёл очередной фикс. Поломашка в master, и скорее всего никого пока не задела. Кроме отмороженных, кто сидит на ночных сборках или собирает сам:

Больше фиксов хороших и разных!

UPD: и практически следом:

May 26, 2022 - 1 minute read - Linux

Konsole: исправлен баг с выделением окна в трее при возникновении bell

Наконец-то починили. Джва года ждал:

В Konsole есть такая возможность: при возникновении сигнала в терминале, который генерируется, например, так:

echo -e '\a'

или так:

tput bel

сделать какие-то действия.

Настраивается: Меню (если выключено: Ctrl+Shift+M) → Настройка → Настроить уведомления…

Нас интересуют:

  • Сигнал в активном сеансе
  • Сигнал в неактивном сеансе

Что бы выделить терминал в панели задач, нужно включить пункт “Выделить программу в панели задач” и нажать Применить или Ок.

Собственно, что это даёт: когда сигнал возникнет, то Konsole выделит, подсветит кнопку приложения в панели задач, примерно так:

При этом сделает это на текущем экране, вне зависимости от того, на каком рабочем столе находится приложение. А если кликнуть по ней, то автоматически активируется окно с переключением на соответствующий рабочий стол.

Плюсом, что сигнал может быть и на удалённом сервере, при подключении через SSH: терминал обрабатывает событие локально.

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

Запуск примерно так:

make -j8 ; tput bel

Не стоит ставить &&, или ||: мы же хотим среагировать при любом коде возврата make? Но если нужно именно для успешного или наоборот неуспешного завершения сигнализировать, то карты вам в руки.

May 23, 2022 - 8 minute read - Linux Life Thinkpad

Переустановка системы на ноутбуке или переезд - хуже пожара

На днях поборол жабу, и позволил себе купить на замену стокового системного HDD HGST Travelstart Z7K500 / 500Гб, новый SSD Samsung SSD 870 EVO.

Первое впечатление - систему стероидами накачали. А дальше - увлекательная процедура миграции нужного и не очень в новое окружение.

May 23, 2022 - 2 minute read - Туризм Linux Maps

Автоматическое резервное копирование при подключении навигатора Garmin GPSMAP 64s

После неудачного удаления всех точек и треков с навигатора, решил, что автоматический бекап это наше всё.

Сделал средствами Systemd.

Для начала определяемся с местом для бекапа, пусть это будет ~/Documents/GPX и создаём там скрипт ~/Documents/GPX/sync.sh. А внутре… у ней неонка:

#!/bin/sh  
  
#  
# Ref:  
#  https://askubuntu.com/questions/25071/how-to-run-a-script-when-a-specific-flash-drive-is-mounted  
#  
# `systemctl list-units -t mount`  
#  
# "~/.local/share/systemd/user/garmin-backup.service"  
#  
#  
# ```  
# [Unit]  
# Description=Backup GARMIN GPSMAP 64s GPX data  
# # Use output from the: `systemctl list-units -t mount`  
# Requires=run-media-hatred-GARMIN.mount  
# After=run-media-hatred-GARMIN.mount  
#    
# [Service]  
# ExecStart=/home/hatred/Documents/GPX/sync.sh  
#    
# [Install]  
# WantedBy=run-media-hatred-GARMIN.mount  
# ```  
#  
# `systemctl --user start garmin-backup`  
# `systemctl --user enable garmin-backup`  
#  
# Monitor:  
#  
# ```sh  
# journalctl --user --unit garmin-backup -f  
# ```  
#  
  
prefix="/run/media/hatred/GARMIN/Garmin/GPX"  
  
dir=$(dirname $0)  
cd "$dir"  
  
echo "Work dir: " $(pwd)  
  
sleep 2  
  
stat "$prefix" 2> /dev/null && \  
   rsync -rubv --suffix=.old  "$prefix" . && \  
   touch sync_last.txt && \  
   notify-send -u normal -a "Garmin Sync" "Garmin GPSMAP 64s" "Backup done"

Да, я не разбирался с переменными для имени пользователя, поэтому указывал полные пути с учётом своего рабочего аккаунта: hatred. Т.е. нужно будет скорректировать под себя.

Следующий шаг: сам юнит. ~/.local/share/systemd/user/garmin-backup.service:

# Ref:  
#  https://askubuntu.com/questions/25071/how-to-run-a-script-when-a-specific-flash-drive-is-mounted  
#  
# systemctl list-units -t mount  
# systemctl --user start garmin-backup.service  
# systemctl --user enable garmin-backup.service  
#  
# journalctl --user --unit garmin-backup -f  
#  
[Unit]  
Description=Backup GARMIN GPSMAP 64s GPX data  
Requires=run-media-hatred-GARMIN.mount  
After=run-media-hatred-GARMIN.mount  
  
[Service]  
ExecStart=/home/hatred/Documents/GPX/sync.sh  
  
[Install]  
WantedBy=run-media-hatred-GARMIN.mount

Тут главное, это запуститься, когда увидим, что нужно устройство примонтировалось. У меня, когда монтируется GARMIN, он использует метку GARMIN для своего внутреннего хранилища (куда и пишутся GPX файлы). Путь для монтирования выходит /run/media/$USER/GARMIN.

Systemd создаёт временный сервис, на который можно сослаться. Если просто, то возьмите путь монтирования, у меня это /run/media/hatred/GARMIN, замените все / на - (кроме первого) и добавьте в конце .mount: run-media-hatred-GARMIN.mount. Ну или смотрим вывод:

systemctl list-units -t mount

после монтирования раздела GARMIN.

А за подробностями по ссылке:

После этого включаем сервис:

systemctl --user enable garmin-backup.service
systemctl --user start garmin-backup.service

Последить за работой:

journalctl --user --unit garmin-backup -f

Feb 12, 2022 - 5 minute read - Linux

ThinkPad T530: зависание при выходе из сна на ядрах 5.10+ (опять)

“Никогда такого не было и вот опять” (с). В этот раз зависание имеет место быть, если воткнуто какое-то USB устройство.

Я уже толком не вспомню ход разбирательства, но меня смущал тот факт, что на 5.10 этой проблемы изначально не было и нет на более ранних LTS ядрах, которые имеют место быть в Manjaro (вот тот самый случай, когда несколько ядер это лютый вин).

Первая мысль: помирает железо. Тем более, что в какой-то момент стало невозможно работать с мышкой Logitech MX Master, подключенный по BT. BT на ThinkPad T530 подключен по USB. Невозможность заключалась в том, что она постоянно отваливалась и подключалась опять. Лаги очень раздражали.

Потом что-то меня навело на мысль, посмотреть на параметры модулей-драйверов USB:

  • xhci_hcd - USB 3.0 (или по модному: USB 3.2 Gen1)
  • ehci-pci - USB 2.0

Больше интересовало второе, так как все проблемные подключенцы были на USB 2.0. Выхлоп примерно такой:

$ modinfo ehci-pci  
name:           ehci_pci  
filename:       (builtin)  
license:        GPL  
file:           drivers/usb/host/ehci-pci  
author:         Alan Stern  
author:         David Brownell  
description:    EHCI PCI platform driver

И тут меня заинтересовала эта строчка:

filename:       (builtin)

Это означает, что модуль встроен в ядро. К слову, даже если он встроен, его параметры и интерфейс доступны через /sys/module/.

Решил глянуть, как обстоят дела на 5.4, а там модуль собран отдельно:

$ find /lib/modules/5.4.176-1-MANJARO/ -name '*ehci*.ko*'   
/lib/modules/5.4.176-1-MANJARO/kernel/drivers/usb/host/ehci-pci.ko.xz  
/lib/modules/5.4.176-1-MANJARO/kernel/drivers/usb/host/ehci-hcd.ko.xz  
/lib/modules/5.4.176-1-MANJARO/kernel/drivers/usb/host/ehci-fsl.ko.xz  
/lib/modules/5.4.176-1-MANJARO/kernel/drivers/usb/host/ehci-platform.ko.xz

Что это означает? Всё, что встроено в ядро может инициализировать на самых ранних стадиях старта системы, ещё на этапе работы с RAM-диском (initrd) и даже вообще до подключения корневой файловой системы. А модули уже подгружаются или с initrd образа или уже с основной файловой системы, тут как настроено.

Я уже сталкивался с ситуацией по работе, когда подобное различие влияло на работу системы. Получалось, что модуль, ответственный за работу одной железки стартовал достаточно рано, когда блок, генерирующий тактовый сигнал (“клок”) не неё ещё не был проинициализирован и завершал свою инициализацию с ошибкой. Типичное состояние гонки. Да, на этот случай предусмотрен специальный код возврата EPROBE_DEFER и он не был использован в этот раз чисто по ошибке. Но дело в том, что когда драйвер был собран модулем, то он успешно грузился на более поздних стадиях загрузки системы и клок был проинициализирован и устройство запускалось нормально.

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

Самый просто способ: вынести драйвера в виде модулей. Но пересобирать ядро не хотелось. Поэтому включил логику: почти все драйвера предлагают функционал bind/unbind. Устройства на PCI шине (по крайней мере на PCIe) могут быть пересканированы (т.е. чисто теоретически PCIe - Hot Plug, но лучше не проверяйте :)). А что станет, если после загрузки, отключить железку от драйвера и потом подключить опять? Почти всё железо содержит функционал Reset настроек в исходное состояяние, что будет если сбросить и сконфигурировать всё, когда система уже готова?

Сказано - сделано. И вы не поверите: после загрузки отключил USB контроллеры, подключил обратно и попытался сделать suspend. И сработало! Ядро 5.15 - resume заработал.

К слову, на 5.16 сломано более сильно. И WA ниже не помогает. Сижу на 5.15.

Более того, вылечился BT и мышка перестала отваливаться при работе (при работе через Logitech Unify Receiver она и так работала хорошо, но теперь и по BT стала - плюс один порт свободен).

Код под катом.

Feb 12, 2022 - 3 minute read - Programming

Qt Creator: подтасовка триплета архитектуры для кодовой модели

Что текущий основной парсер, что грядущий (или нагрянувший, как посмотреть) парсер на clangd работают поверх libclang и сотоварищи и умеют разбирать то, что умеет собирать clang.

Внезапно, он умеет не всё. И это не всё, к примеру, отлично умеет GCC. Вот то, с чем я столкнулся сам:

Под катом будет хак, который я использовал, что бы запуститься и работать с этим добром. UPD: хак больше не работает, так как этот код вообще удалён из репозитория QtC ветки master на момент 23.05.2022.

Но сейчас не об этом. Просматривая изменения в апстриме, наткнулся на этот коммит:

И визуально это выглядит так:

Похоже, жизнь станет проще. К сожалению, мне сейчас не на чем проверить. Как только дойдут руки, то обязательно это сделаю. Как минимум, есть ещё нюанс с неподдерживаемыми параметрами командной строки, но оно сейчас обходится так:

# Hack QtC Clang:  
# https://bugreports.qt.io/browse/QTCREATORBUG-22329  
export QTC_CLANG_CMD_OPTIONS_BLACKLIST="-mxl-soft-mul;-mlongcalls;-fstrict-volatile-bitfields"

Данная функциональность, судя по этому списку изменений будет доступна в Qt Creator 7.0, т.е. совсем скоро:

Ну а ниже, как обещал - костыль. Требует пересборки Qt Creator из исходников.

Feb 12, 2022 - 2 minute read - Programming

Qt Creator 7: clangd

Тут обновлял свой CMakeProjectManager2 и краем глаза заметил добавление файла dist/changes-7.0.0.md. Решил перечитать (с некоторыми изменениями я сталкиваюсь регулярно, так как живу на master-ветке).

Там фигурирует:

### C++  
  
* Switched to Clangd by default (QTCREATORBUG-22917)

И таки да, они переключились на кодовую модель от Clangd. Оно появилось ещё раньше, где-то к версии 6.0, но была выключена. Можно ознакомиться с анонсом из первоисточника: Qt Creator and clangd: An Introduction. Или почитать комментарии к соответствующей новости на Phoronix.

В частности, они там объясняют причины. Основная (как мне кажется): libclang больше активно не развивается и для полноценной навигации, рефакторинга и прочего приходится держать две модели.

Там же они рекомендуют использовать самую последнюю версию clangd. Так что ссылки ниже ваши други:

Ну а теперь мои личные впечатления… Точнее табличка, которую я для себя составил. Плюсы и минусы.

Jan 7, 2022 - 4 minute read - Туризм

Траверс г.Острая или закрываем гештальты

В 2016 году (а в 2020 дошли по Большой Пионерской) уже была попытка добраться до Острой по хребту, пробираясь по “милым Приморским рощам” (они же: “Южный Лес”). В этом году решил закрыть этот гештальт, плюс размять ногу после микротравмы на пробежке.

Oct 8, 2021 - 1 minute read - Туризм Maps Programming

GeoCrop 2.0

Встречайте: GeoCrop v2.0

Нового функционала не завезли, но обновил для сборки с современными Proj. Сейчас актуальная версия API - 6. Проверял с Proj 8.0.1.

Итак:

  1. CMake: почищен файл, приведён чуточку к виду Modern CMake.
  2. Для сборки нужен Proj ≥ 6.0, так как используется его API теперь. Proj4 не поддерживается, если нужно, то берите код по метке v1.0
  3. Исправлен досадный баг с полигоном обрезки: последним элементом нужно указать начальную точку, что бы полигон закрылся. Старые версии Gdal ругались (точно не помню), но игнорировали и обрезали, моя текущая версия (3.3.1 на момент публикации) уже вываливается с ошибкой.

Oct 7, 2021 - 4 minute read - Linux

Ubuntu: persistent live stick

Задача: сделать USB стик с Ubuntu, но так, что бы состояние сохранялось. Между перезагрузкам.

Забегая вперёд, это делается, но с одним ограничением: ядро не меняется. Но под мои задачи этого достаточно.

Jul 1, 2021 - 2 minute read - Life

Как я хакером стал (на самом деле нет)

И смешно и грустно :)

Итак, начнём.

Мне нужно было скачать одну статью с информацией по ковидной тест-системе (пытался понять значение КП, которое сам получил на тесте). И располагалась она на сайте: Электронный журнал “Справочник заведующего КДЛ”, который является частью сервисов Action Media: https://action-media.ru и использует для входа единый аккаунт. На статью перешёл с сайта производителя тест системы Векто-Бест.

Доступ к журналу платный, но предоставляется пробный бесплатный доступ на 3 или 4 дня.

При регистрации требую телефон и почту. Но так как для меня этот сайт является мусорным, то оставлять свой основной мейл и телефон, ровно как и мои реальные ФИО мне нет никакого резона, то я воспользовался сервисом https://smska.us/. Взял второй в списке и ввёл.

Скачал статью и успокоился. Но они начали закидывать меня тоннами спама. Решил снести аккаунт. Но, как это полагается у подобных сайтов, кнопки удаления нет. Полез в саппорт и вот такой вот диалог состоялся:

Я: День добрый! Как удалить свой аккаунт?

Бот помощник: Здравствуйте! Если удалить учетную запись, вы больше не сможете зарегистрироваться на сайтах «Актион» и получать приглашения на закрытые мероприятия. Отписаться от рассылок можно в разделе «Рассылки». Не переживайте, если после отписки придет несколько писем. Нам нужно время, чтобы остановить рассылки.

Вы получили ответ на свой вопрос?

Я: Нет, нужен менеджер

Елена Табачукова: Здравствуйте, Алекс , рады видеть Вас на нашем сайте

Я: День добрый! Нужно удалить аккаунт

Кристина Вырлан: Здравствуйте, Алекс , рады видеть Вас на нашем сайте

Минуту, пожалуйста

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

Я: Я не проходил у вас обучения и сертификатов нет. Я уже 5 минут кликаю на отписку от чёртовой горы подписок и ещё не дошёл до конца. С таким отношением в печь такие сервисы. Спасибо. Запросите технический персонал (разработчиков), что бы удалили записи в базе данных по e-mail ZXXXXXY@inbox.ru. Надеюсь на понимание.

Кристина Вырлан: Алекс, ранее данный аккаунт принадлежал ХмХХХву Роману, Вы переделали аккаунт на себя и свою почту, просьба вернуть все данные обратно, в таком случае все данные и Ваш аккаунт удалиться и Вы вернете аккаунт Роману

Я: Вы по телефону смотрите? :) Это телефон сервиса Онлайн-СИМ, то что нужно для регистрации на мусорных сайтах

Кристина Вырлан: Screenshot_5.png 0.03Mb

Вы стерли чужой аккаунт , сменив все данные на себя

На скрине - логи системы с изменением настроек профиля :) скрины переписки под катом.

Короче, Роман сфейлился, указав левый номер, потом работал с аккаунтом. Там пачка платёжных документов, пройденные курсы, сертификаты.

Будьте внимательны и осторожны :)

Apr 29, 2021 - 3 minute read - Linux Programming

Kernel: deadlock при использовании spin lock

Цитата:

Many functions in the kernel sleep (ie. call schedule()) directly or indirectly: you can never call them while holding a spinlock, or with preemption disabled. This also means you need to be in user context: calling them from an interrupt is illegal.

Неделю достаточно трудоёмкой (в плане воспроизведения) отладки пришлось потрать по причинам:

  1. Незнания информации из цитаты выше (компетентность? не, не слышал).
  2. Наличия неявной блокировки в недрах ALSA при вызове колбека snd_pcm_ops::trigger().

Про второй пункт попадалась информация:

Run under stream lock

Этот самый “stream lock” обеспечивается семейством функций:

  • snd_pcm_stream_lock()/snd_pcm_stream_unlock()
  • snd_pcm_stream_lock_irq()/snd_pcm_stream_unlock_irq()
  • snd_pcm_stream_lock_irqsave()/snd_pcm_stream_unlock_irqsave()

И вводит понятия: “atomic context” and “non-atomic context”.

Контекст определяется значением флага substream->pcm->nonatomic (bool snd_pcm::nonatomic).

Если не сказано иного, то там значение 0, или “atomic context”.

И этот самый контекст вляет на то, какой тип блокировки будет использоваться: mutex или spin lock.

По неудачному стечению обстоятельств в колбеке snd_pcm_ops::trigger() появился вызов cancel_delayed_work_sync(). А контекст был объявлен как “atomic”. И работать всё стало очень весело, в зависимости от того, куда какое нейтрино попадёт :)

Проявлялось по разному:

  • случайные зависания при закрытии аудио устройства
  • случайные зависания при перезагрузке (если устройство было открыто)

В терминал при этом вылетало такое:

Requesting system reboot
[   56.034544] watchdog: BUG: soft lockup - CPU#3 stuck for 23s! [init:7475]

А дальше вариции:

  • Стектрейсы, например:

    [   52.084474] Modules linked in: sch_htb xlnx_sdi_audio regmap_mmio v_comp(O) v_scaler(O) v_process(O) snd_soc_xlnx_audio_formatter snd_soc_xlnx_i2s mali(O) xilinx_dp_card xilinx_dp_pcm xilinx_dp_codec snd_soc_tlv320aic3x pwm_cadence(O) max6966_keys(O) max6966_backlight(O) max6966_leds(O) max6966_mfd(O) fbili9341(O) it666x(O) xilinx_hdmi_rx(O) xilinx_vphy(O) xilinx_sdirxss u_dma_buf(O) uio_pdrv_genirq dmaproxy(O) al5d(O) xlnx_vcu_clk al5e(O) allegro(O) xlnx_vcu xlnx_vcu_core xlnx_pl_snd_card snd_soc_core snd_pcm_dmaengine snd_pcm snd_timer snd soundcore xilinx_vpss_scaler xilinx_video videobuf2_v4l2 v4l2_fwnode videobuf2_common videobuf2_dma_contig videobuf2_memops videodev media
    [   52.144543] CPU: 1 PID: 6938 Comm: init Tainted: G           O        4.19.0-xilinx-v2019.2 #83
    [   52.153054] Hardware name: Epiphan X3 (DT)
    [   52.157136] pstate: 20000005 (nzCv daif -PAN -UAO)
    [   52.161915] pc : smp_call_function_single+0x140/0x170
    [   52.166952] lr : smp_call_function_single+0x110/0x170
    [   52.171985] sp : ffffff802e0f3bb0
    [   52.175283] x29: ffffff802e0f3bb0 x28: ffffffc03d3eac00 
    [   52.180586] x27: 0000000000000002 x26: ffffff8008b887c8 
    [   52.185881] x25: ffffff8008b9a9a0 x24: ffffff8008125800 
    [   52.191185] x23: 0000000000000002 x22: ffffff8008b9a9c0 
    [   52.196480] x21: ffffffbebffc7b58 x20: ffffff8008b88548 
    [   52.201774] x19: ffffff802e0f3be0 x18: 0000000000000000 
    [   52.207069] x17: 0000000000000000 x16: 0000000000000000 
    [   52.212364] x15: 0000000000000000 x14: 0000000000000000 
    [   52.217659] x13: 0000000000000000 x12: 0000000000000000 
    [   52.222953] x11: 0000000000000000 x10: 0000000000000000 
    [   52.228248] x9 : 0000000000000000 x8 : 0000000000000000 
    [   52.233543] x7 : 0000000000000000 x6 : ffffff802e0f3be0 
    [   52.238838] x5 : ffffff802e0f3be0 x4 : 0000000000000004 
    [   52.244133] x3 : ffffff802e0f3bf8 x2 : 0000000000000000 
    [   52.249428] x1 : 0000000000000003 x0 : 0000000000000000 
    [   52.254723] Call trace:
    [   52.257155]  smp_call_function_single+0x140/0x170
    [   52.261844]  perf_event_exit_cpu_context+0x84/0xe0
    [   52.266624]  perf_reboot+0x2c/0x60
    [   52.270011]  notifier_call_chain+0x54/0x90
    [   52.274099]  blocking_notifier_call_chain+0x54/0x80
    [   52.278960]  kernel_restart_prepare+0x1c/0x40
    [   52.283299]  kernel_restart+0x14/0x60
    [   52.286945]  __se_sys_reboot+0xd4/0x1f0
    [   52.290764]  __arm64_sys_reboot+0x18/0x20
    [   52.294758]  el0_svc_handler+0xc8/0x120
    [   52.298584]  el0_svc+0x8/0xc
    
  • Периодические репорты:

    [   62.477485] BUG: workqueue lockup - pool cpus=2 node=0 flags=0x0 nice=0 stuck for 36s!
    

В общем, рекомендую к внимательному чтению:

Только не смотрите на год :)

И перед тем, как ставить msleep()/mutex_lock()/etc, изучите, кто вызывает этот код, есть ли там блокировка и какая. А если код ваш, посмотрите на шпаргалку по выбору типа блокировки.

PS а если полезно под рукой иметь глоссарий. В частности он объяснил мне, что это за функции с суффиксом _bh и что такое tasklet.

Apr 14, 2021 - 1 minute read - Linux

ThinkPad T530: зависание при выходе из сна на ядрах 5.10+

Тот самый случай, когда WA ломается.

Причина проста: наличие параметра ядра scsi_mod.scan=sync.

По умолчанию его нет, поэтому и проблема не слишком актуальна. А появился он… как WA проблемы с тем же самым Resume after Speep. Но тогда рушился XOrg:

Таким образом, наличие этой опции на ядре 4.15+ решает проблему с выходом из сна и падением XOrg и никак не мешает работе вплоть до ядер 5.9.x, но начиная с ядра 5.10 эта опция должна быть удалена, иначе уже она является причиной зависания при выходе из сна.

Скорее всего такое поведение тоже является ошибочным

Apr 9, 2021 - 2 minute read - programming

GTest: запуск теста только вручную

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

Тестовый фреймворк GTest.

GTest, как и многие другие имеет возможность фильтровать тесты, иными словами, выбирать только те, которые нужно запустить в данный момент времени:

./tests --gtest_filter=Categoty.some_test

Если фильтр не указывается, то запускаются все тесты. При этом, у Google Test есть макрос, который в рантайме позволяет исключить тест из прогона:

GTEST_SKIP()

Остаётся придумать, как передать условие, по которому этот макрос вызовется.

Дополнительный параметр командной строки заводить не хотелось, тем более, что уже есть фильтр… Оказалось, что достучаться к тому, что передано для --gtest_filter= в качестве параметра проще простого:

std::string str = ::testing::GTEST_FLAG(filter);

Сама строка фильтра: набор масок, разделённых двоеточием. Собственно, нам достаточно проверить, что фильтр не содержит имени нашего теста и в этом случае скипнуть его:

TEST(Category, some_test) {
    std::string str = ::testing::GTEST_FLAG(filter);
	auto enable_pos = str.find("Category.some_test");
	if (enable_pos == std::string::npos) {
    	GTEST_SKIP();
	}
}

Теперь, тест запустится, только если явно указать имя теста при запуске:

./tests --gtest_filter=Category.some_test

или все тесты, включая наш:

./tests --gtest_filter=Category.some_test:*

Под катом небольшой бонус :)