LINUX.ORG.RU

Сообщения mersinvald

 

Понимание потоков ввода-вывода в C++

Есть такой код:

class LogStreamBase {
public:
    LogStreamBase(const ostream& os) : out(os) {}
    template<typename T>
    const LogStreamBase& operator<< (const T& var) {
        prepare();
        print_prolog();
        out << var;
        print_epilog();
    }

protected:
    virtual void print_prolog() = 0;
    virtual void print_epilog() = 0;

    const ostream& out;

};

Как работает operator <<, будучи вызванным вот так:

LogStreamDerived log;
log << "One" << "Two" << "Three";

Будут ли print_prolog и print_epilog вызваны для каждой строки, или для всей последовательности единожды?
Адекватен ли такой вариант или лучше наследовать streambuf и прикручивать его к ostream?

UPD: Если это не очевидно, то цель — выводить диагностические сообщения с указанием времени, вызывающей функции, уровня логгирования идт, плюс отсечение по оному уровню.

 , ,

mersinvald
()

Бэкап с помощью git — игнорирование субмодулей

Хочу сделать удобный и переносимый бэкап с помощью git,
запилил .gitignore, добавил файлы и заметил, что другие репозитории, во вложенных папках добавились кау субмодули, то есть не будут включены в бэкап.

Как заставить гит игнорировать субмодули и добавлять файлы в них, несмотря ни на что?
Желательно также добавлять .git/*, чтобы сохранять все дерево.
Нужно решение, не требующее ручками делать --force на каждой такой папке

 , ,

mersinvald
()

Повреждение данных после передачи структуры по указателю

Уже весь мозг себе сломал, не могу понять что происходит.
Есть массив классов, каждый хранит в себе свою длину и размер, указатель на указатель на массив на стеке функции и смещение в нем.

В один прекрасный момент, в одной из функций, при передаче нескольких структур, данные во всех трех превращаются в тыкву.

void poly_mul(const Poly *p, const Poly *q, Poly *newp){
    newp->length = p->length + q->length - 1;
    memset(newp->ptr(), 0, newp->length * sizeof(uint8_t)); <-- Вот тут все ломается при попытке замемсетить левую область памяти.
    /* Compute the polynomial multiplication (just like the outer product of two vectors,
     * we multiply each coefficients of p with all coefficients of q) */
    for(uint8_t j = 0; j < q->length; j++){
        for(uint8_t i = 0; i < p->length; i++){
            newp->at(i+j) ^= mul(p->at(i), q->at(j)); /* == r[i + j] = gf_add(r[i+j], gf_mul(p[i], q[j])) */
        }
    }
}

void GeneratorPoly() {
    Poly *gen = polynoms + ID_GENERATOR;
    gen->at(0) = 1;
    gen->length = 1;

    Poly *mulp = polynoms + ID_TPOLY1;
    Poly *temp = polynoms + ID_TPOLY2;
    mulp->length = 2;

    for(int8_t i = 0; i < ecc_length; i++){
        mulp->at(0) = 1;
        mulp->at(1) = gf::pow(2, i);

        gf::poly_mul(gen, mulp, temp);
        *gen = *temp;
    }
}

int abstract_func() {
    /* Allocating memory on stack for polynomials storage */
    uint8_t stack_memory[MSG_CNT * msg_length + POLY_CNT * ecc_length * 2];
    
    // Каждый класс Poly хранит указатель на указатель memory и разыменовывает его для доступа к памяти на стеке.
    // Сам массив классов тоже расположен на стеке.
    this->memory = stack_memory;

    GeneratorPoly();
}

Алгоритм написанного описывать не буду, это в принципе не так уж важно, но если кому интересно, это кодирование Рида-Соломона.

Вывод дебаггера перед вызовом poly_mul:
gen: 0x41a7c2
gen->length: 1
gen->size: 16
gen->offset: 116
gen->memory: 0x41a7a0
*gen->memory: 0x7fffc1f67550
Для 2х других аналогично

Вывод дебаггера внутри poly_mul
gen: 0x41a7c2
gen->length: 1
gen->size: 2
gen->offset: 4
gen->memory: 0x403020000000000
*gen->memory: ------

Ошибка долго была незамечена, так как в дебаг-моде, несмотря на такую кашу, все работало, а релиз начал сыпаться.

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

 , , , ,

mersinvald
()

Ноутбук резко вырубается без объявления войны

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

 , , , ,

mersinvald
()

Рандомная запись в NAND Macronix

Пытаюсь осуществить случайные чтение и запись в NAND. Делаю все по AC waveform указанной в даташите

    struct IORequest_t {
        void*    buffer;
        uint16_t ofst;
        uint16_t size;
    };    

    ResultCode_t
    NandBase::Write(uint32_t addr, IORequest_t *requests, uint32_t cnt) {
        /// Вычисляем адрес страницы в микроосхеме
        uint32_t pageNumber = addr / NAND_PAGE_SIZE;
        addr = pageNumber << 16;
    
        /// Ждем готовности микросхемы
        if(WaitReady() != RESULT_SUCCESS) {
            return RESULT_TIMEOUT;
        }
    
        /// Отправляем команду записи
        *(uint8_t* )(MapAddress | COMMAND_SECTION) = 0x80;//CMD_PAGE_WRITE;   
    
        /// Отправляем адрес
        *(uint32_t* )(MapAddress | ADDRESS_SECTION) = addr;
        
    
        /// Записываем данные
        for(uint32_t i = 0; i < cnt; i++) {
            const uint8_t* src  = (const uint8_t*) requests[i].buffer;
            uint16_t ofst = requests[i].ofst;
            uint16_t size = requests[i].size;
        
            /// Проверяем не выйдет ли запись за предел страницы
            if(ofst+size > NAND_PAGE_SIZE) {
                return RESULT_INVALID_PARAMS;
            }
        
            /// Отправляем команду произвольного доступа
            *(uint8_t* )(MapAddress | COMMAND_SECTION) = 0x85;//CMD_PAGE_WRITE;
        
            /// Отправляем смещение
            *(uint16_t*)(MapAddress | ADDRESS_SECTION) = ofst;
        
            /// Пишем данные
            for(const uint8_t* data = src; size; size--) {
                *(uint8_t*)(MapAddress | DATA_SECTION) = *data++;
            }
       
        }
    
        /// Отправляем команду подтверждения записи
        *(uint8_t* )(MapAddress | COMMAND_SECTION) = 0x10;//CMD_WRITE_CONFIRM;
    
        /// Ждем готовности микросхемы
        if(WaitReady() != RESULT_SUCCESS) {
            return RESULT_TIMEOUT;
        }
    
        /// Проверяем результат записи
        uint8_t status;
        ReadStatus(&status);
        if(status & 1) {
            return RESULT_PROGRAM_FAILED;
        }
    
        /// Отправляем коману чтения
        *(uint8_t* )(MapAddress | COMMAND_SECTION) = 0x00;//CMD_PAGE_READ;
    
        /// Отправляем адрес
        *(uint32_t* )(MapAddress | ADDRESS_SECTION) = addr;
    
        /// Отправляем команду подтверждения
        *(uint8_t* )(MapAddress | COMMAND_SECTION) = 0x30;///CMD_READ_CONFIRM;
    
        /// Ждем готовности микросхемы
        if(WaitReady() != RESULT_SUCCESS) {
            return RESULT_TIMEOUT;
        }
 
        /// Чтение каждого блока данных
        for(uint32_t i = 0; i < cnt; i++) {
            const uint8_t* src  = (const uint8_t*) requests[i].buffer;
            uint16_t ofst = requests[i].ofst;
            uint16_t size = requests[i].size;
        
            /// Отправляем команду рандомного доступа
            *(uint8_t*)(MapAddress | COMMAND_SECTION) = 0x05;//CMD_RANDOM_DATA_OUTPUT;
        
            /// Отправляем смещение
            *(uint16_t*)(MapAddress | ADDRESS_SECTION) = ofst;
        
            /// Отправляем команду подтверждения рандомного чтения
            *(uint8_t*) (MapAddress | COMMAND_SECTION) = 0xE0;//CMD_RANDOM_DATA_OUTPUT_CONFIRM;
        
            /// Сравниваем исходные и записанные данные
            for(const uint8_t* data = src; size; size--) {
                if(*data++ != *(uint8_t* )(MapAddress | DATA_SECTION)) {
                    return RESULT_PROGRAM_FAILED;
                }
            }
        }
    
        return RESULT_SUCCESS;
    }
Пишу в предварительно стертый блок, проверка чтением всегда проваливается: читаются единицы. Что я делаю не так?

 , , , ,

mersinvald
()

Конвертирование БОЛЬШОГО числа из dec в hex

Доброго времени суток.
Требуется поменять основание системы счисления у ОЧЕНЬ большого числа, а именно числа пи.
Оно хранится в файле длиной в несколько гигабайт, в дестиричной системе счисления.
Нужно перегнать в шестнадцатиричную.
Как можно это сделать, наиболее быстрым способом?
Важно ли что это - дробная часть числа или нет?

 , , ,

mersinvald
()

Как осилить Vim?

Уже 5 лет на генте, пишу на сях, работаю в эмбеде.
По статусу пора уходить от гуёв в голую консоль и если на тайловые wm таки пересел, то с IDE все сложнее.

Я НЕ МОГУ ОСИЛИТЬ VIM

Что можно сделать в тяжелой ситуации жесткой зависимости от удобства и искаробочности, чтобы искоренить в себе мальчика и стать настоящим бородатым кулхацкером?
Делитесь историями успеха, как вы начинали пользоваться vim после полноценных IDE и пилили его?

 , , , ,

mersinvald
()

Зависания GDB на вызове system()

Эпопея борьбы с «глюками» gdb продолжается, но теперь я хотя бы осознал что косячу я.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    system("echo test");

    printf("Done\n");
    return 0;
}

При построчном проходе дебаггером, gdb намертво ложится с EAGAIN в strace и висит, пока не прибьешь.
В чем может быть проблема?

GDB 7.10.1
Gentoo
Linux 4.1.12

GDB собран с USE = «client nls python python_single_target_python2_7 python_targets_python2_7 python_targets_python3_4 server zlib -expat -lzma -multitarget -python_single_target_python3_3 -python_single_target_python3_4 -python_targets_python3_3 -test -vanilla»

 , , , ,

mersinvald
()

Есть ли смысл в буферизации чтения\запись на стороне прикладного ПО

В рамках pet-project пишу логику работы с файлами на диске.
Файлы очень большие, порядка нескольких гигабайт, так что целиком в память не закинешь, а нужно работать как с непрерывным буффером.
Во время проектирования задался вопросом: а нужно ли делать буфферизацию?.
Как обстоят дела с кэшированием в ядре?
Можно ли просто напрямую читать\писать файлы на диске без дополнительных заморочек c внутренним кэшем и будут ли значительные потери в производительности IO?

И как оно в win32/osx/%systemname%?

 , , , ,

mersinvald
()

Расширение функционала программы на Си через другие языки

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

Расширения играют роль «органа» общения с внешними системами: одно принимает данные, другое обрабатывает, третье отдает пользователю, итд, короче, что-то вроде VM, но без такого лютого оверхеда и сложностей.
Для расширений уже придуман C API и, соответственно будут биндинги в другие языки для упрощения написания конфигурации

Собственно, я вижу два варианта устройства расширений:
1. Динамические библиотеки - подгрузка через dlopen, короче канон расширений плагинами.
2. Что-то вроде подхода CGI - единый интерфейс обмена через переменные окружения, stdin/stdout

Лично мне больше нравится первый вариант из-за отсутствия оверхеда при каждом вызове - один раз подгрузил плагины при старте и вызывай код из них сколько хочешь. Чем меньше оверхеда и затрат - тем лучше. (пишу системный демон с довольно высокой частотой пробуждения) Но, увы, не любой язык можно скомпилировать в динамическую библиотеку, а потенциальные пользователи, читай, одмены, вряд ли оценят написание конфигов на си.

Второй дает большую в этом плане гибкость - хоть на баше пиши или асме, но накладывает стоимость вызова шелла.

Реализовывать оба интерфейса возможности нет.

Вопрос номер один: можно ли как-то таки скомпоновать хотя бы питоньий код в динамическую библиотеку?
Вопрос номер два: можно ли при использовании второго варианта как-то уменьшить расходы на запуск сторонних исполняемых файлов?

 , , , ,

mersinvald
()

GDB виснет, падает и ведет себя как баба в месячные

GDB окончательно достал своими тормозами - на мелких проектах все работает идеально, но стоит взять что-то крупное самописное (или не дай бог подключить большую либу), дебаггер падает с «GDB process terminated», думает над каждым шагом (даже на простой арифметике) по пол минуты, зависает на старте и так далее.
Куда бежать? Каким дебаггером пользуетесь Вы?
Что там с clang/LLDB? Юзабелен ли?

Пы.Сы.
gdb --version GNU gdb (Gentoo 7.10 vanilla) 7.10

Собран с USE = «client nls python server zlib -expat -lzma -multitarget -test -vanilla»

 , , ,

mersinvald
()

Аудификация данных: проблема секвенсинга звука

Здравствуйте!
Занимаюсь проектом по визуализации данных, сейчас в процессе генерации звуковой составляющей соответственно данным.

Дано: есть битовая маска из 400 элементов, генерирующаяся из выборки данных на конкретный момент времени. Каждому биту в маске соответствует звуковая волна (волны относительно друг дружки имеют расстояние в 10 Гц). При изменении состояния выборки меняется битовая маска, и, соответственно, массив активных волн.

Задача: секвенсировать эти 0-400 волн в одну звуковую волну для воспроизведения в реальном времени.

Какие инструменты могут помочь в задаче сведения звуковых волн, ссылки на теорию и практические реализации так же приветствуются. Спасибо.

 , , , ,

mersinvald
()

Undefinied reference to ***

Чувствую себя дауном, но никак не могу понять почему не линкуется...

Есть код, который использует мою библиотеку.
По мере развития, в библиотеку добавляются новые функции.
Все прекрасно работало и линковалось, пока только что я не добавил 2 файла, хэдер и си, естественно.
В хэдере:

extern int lc_send_non_block(int fd, void* data, int size, int flags);
extern int lc_recv_non_block(int fd, void* buffer, int size, int flags);

В сишном файле:
int send_non_block(int fd, void* data, int size, int flags){
   /* code */
}

int recv_non_block(int fd, void* buffer, int size, int flags){
   /* code */
}


В библиотеке еще 6 файлов, с такой же организацией, все линковалось. Теперь именно на эти функции ld вываливает undefinied reference. Что за магия!?
Либу пересобирал.

 , , ,

mersinvald
()

Обмен данными между процессами с помощью pipe

Здравствуйте.
Такая ситуация: есть родительский процесс (Р), который порождает дочерний (C), и потом еще неопределенное количество процессов (C0 - CN)

Нужно как-то синхронизировать данные между C и C0-CN, а точнее, сделать так, чтобы сообщение принимаемое от C0 пересылалось всем C1-CN, и так для каждого CN.

Я решил использовать трубы, но уже сомневаюсь в верности своего решения...
Как я предполагаю, работать это должно так:
1) Родительский процесс создает 2 пайпа, один для сообщений(mp), второй для fd пайпов дочерних процессов(fdp), передает оба дескриптора в C и любой из порожденных CN
2) C0-СN порождаются, создают каждый по новому пайпу pN, отправляют дескриптор pN по fdp, плюс уникальный id
3) С принимает дескрипторы пайпов, сохраняет себе, ассоциирует с id
4) СN отправляет сообщение по mp, C его принимает и отправляет всем СX, с отличным от CN id

Собственно вопрос: я творю какую-то ересь, или мне кажется?
Если не кажется, как сделать проще?
Если кажется, как в C принимать данные из двух пайпов асинхронно - насколько я понял, после вызова read процесс блокируется до записи в пайп с другой стороны.

 , , ,

mersinvald
()

Проверка диска на бэды

Прогнал проверкой свой диск, ничего не выявил, в чем сильно сомневаюсь, ибо признаки есть
У кого-нибудь может есть залеченные диски, или просто старые, на которых гарантированно есть бэды? Выявляет ли все?
Сомневаюсь потому как линукс на низком уровне с дисками вроде как не работает, только докумментированные возможности в libata.

Команда: badblocks -swv /dev/sd?

 , , ,

mersinvald
()

Вопрос по дискретной математике - найти все возможные варианты связывания элементов таблицы

Здравствуйте.
Ищу метод решения проблемы поиска слов в таблице (на манер сканвордов).
В данный момент уже запрограммированы все структуры данных, осталось только написать метод самого решения.

Алгоритм, каким я его вижу:
У нас есть квадратная матрица с кодами букв, каждая клетка матрицы соответственно имеет свою координату.
1) Сгенерировать список возможных «в принципе» слов, по координатам (буквы рядом - значит их можно связать).
По сути, задача по построению всевозможных графов на этой таблице.
И я абсолютно не понимаю как найти все возможные перестановки.
Условия:

  • Графов в таблице должно быть больше одного.
  • Каждый граф должен иметь больше 2х листьев
  • Графы односвязные, ориентированные. Обратное направление - новый случай.

2) Используя сгенерированый список, проверить каждый вариант расположения букв на соответствие словарю.

Прошу натолкнуть на алгоритм действия, или показать на примере готового решения \ общей задачи.
Код не покажу, тк задача сугубо теоретическая, пока что.

UPD: Таки скорее по дискретной математике вопрос, просто у нас это в курсе вероятностей шло х)

 , , , ,

mersinvald
()

C++ Ломаный юникод для кирилических символов.

Не получается работать с кириллицей из плюсовой программы:
Если вхардкодить кириллическую строку, она и в файл и в stdout выводится как надо, в нужной локали, и все верно,
но стоит попытаться прочитать оную кирилицу из файла, stdin или, как в моем случае - получить от tesseract-ocr, вся кириллица (но не цифры) превращается в d0 (или 208) - символ Ð

Первый раз понадобилось, и тут такая ересь Оо
Скрин из дебагера

UPD: Товарищ с stackoverflow подсказал что у меня юникод невалидный - русские символы должны занимать 2 байта - d0 + код символа.
Очевидно, что-то в моей генте не так, но что?

Локали есть:

(1/4) Generating en_US.ISO-8859-1 ...
(2/4) Generating en_US.UTF-8 ...
(3/4) Generating ja_JP.UTF-8 ...
(4/4) Generating ru_RU.UTF-8 ...

 , , ,

mersinvald
()

Периодические зависания ядра в Gentoo

Доброго времени суток,
Возникла такая проблема: периодически намертво вешается система, причем видимо на уровне ядра - SysRq не работают.
Сначала грешил на SSD, но после замены обоих по гарантии (прости, %seller_name%), ничего не поменялось.
Если честно, буду рад любым советам, потому как я в ступоре - на уровне сборки мои скиллы в linux на уровне ядра пока заканчиваются)

Thinkpad T420, Gentoo ~amd64, Linux 4.2.0-gentoo-r1
Конфиг ядра

 , , , ,

mersinvald
()

i3bar и conky - как отучить i3bar пухнуть и парсить ВЕСЬ JSON?

Ситуация такова: использую коньки как провайдер статуса в i3bar, естественно в формате JSON.
Если кто не в курсе, выглядит это как добавление в конец JSON нового перечисления, типо бесконечный массив. Соответственно размер оного JSONа увеличивается линейно.
Приводит это к тому что i3 хапает больше и больше памяти, но это еще терпимо.
Куда хуже что из-за этого через 10-20 минут появляется ощутимая задержка в отклике i3, а после он и вовсе виснет (технически то он работает, но пятисекундная задержка на распарсить JSON на быстродействии положительно не сказывается).
Что делать? i3status и i3blocks используют тот же протокол, но проблема не возникает..

Gentoo, 4.2-r1, i3-gaps 4.10.4-680-* (ветка i3-next), conky 1.9.0

скрипт запуска коньков + conkyrc
конфиг i3

 , , ,

mersinvald
()

i3bar и conky - настройка сепаратора

Доброго времени суток.
Пилю свой идеальный конфиг, вдохновляясь этимх
Пользуюсь форком i3-gaps, оно помимо всего прочего умеет в бэкграунды в i3bar

В процессе возникла проблема: при использовании коньков в качестве провайдера статуса, каждый JSON блок, получаемый от коньков i3bar отделяет своим дефолтным сепаратором «|».
Как заставить его использовать тот сепаратор, который по душе мне или хотя бы не использовать их вовсе?
Знаю, что можно назначить цвет сепараторов, чтобы слить их с фоном, но это не выход - место они все равно занимать будут.

Gentoo, 4.2-r1, i3-gaps 4.10.4-680-* (ветка i3-next), conky 1.9.0

 , , ,

mersinvald
()

RSS подписка на новые темы