LINUX.ORG.RU

Ответ на: комментарий от rumgot

код можно, но весь его тут не выложить - в цикле, который крутится в отдельном потоке нечто подобное делаю с локальной для цикла переменной

atomic_ushort auKb(0);

--- начало процедуры
string sKb("");

---Тут цикл на семафоре
        if (auKb)
        {
            if (sKb.length() >= MAX_NUMBER + PASSWORD_LEN)
                sKb.erase(0, 1);

            sKb += (unsigned char)auKb.load();
        }
        else
            sKb.clear();


sKb.erase(0, 1) - здесь исключение ловлю

auKb - это прилетают ascii символы с uart

wolverin ★★★
() автор топика
Ответ на: комментарий от wolverin

В в однопоточном варианте можно воспроизвести?

Все таки похоже кто то память засохатил.

Я бы понавтыкал для начала диагностики, в какой строке кода в какой момент строка становится такой толстой.

AntonI ★★★★
()

Это скорее всего значение std::string::npos для используемой архитектуры, который является флагом ошибки и зависит от контектса, но непонятно почему в результате std::string.lengh()

sparks ★★★
()
Ответ на: комментарий от AntonI

Segmentation fault того места

==1205== Process terminating with default action of signal 11 (SIGSEGV)
==1205==  Bad permissions for mapped region at address 0x77AE000
==1205==    at 0x484600C: memmove (vg_replace_strmem.c:1242)
==1205==    by 0x49655E9: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_erase(unsigned int, unsigned int) (in /usr/lib/arm-linux-gnueabihf/libstdc++.so.6.0.21)
==1205==
==1205== HEAP SUMMARY:
==1205==     in use at exit: 146,572 bytes in 154 blocks
==1205==   total heap usage: 40,038 allocs, 39,884 frees, 531,810 bytes allocated
==1205==
==1205== LEAK SUMMARY:
==1205==    definitely lost: 180 bytes in 2 blocks
==1205==    indirectly lost: 0 bytes in 0 blocks
==1205==      possibly lost: 760 bytes in 5 blocks
==1205==    still reachable: 145,632 bytes in 147 blocks
==1205==         suppressed: 0 bytes in 0 blocks

wolverin ★★★
() автор топика
Ответ на: комментарий от wolverin

Ну, в erase же? Весь мой скромный опыт говорит что если std так падает, значит кто то запорол память контейнера.

Валгринд и санитайзеры в помощь, а std::string ни в чем не виноват. Если его заменить на char* ошибка просто уедет в другое место.

Кстати отладочная печать тож не факт что поможет, от неё ошибка опять таки убежит куда то ещё.

AntonI ★★★★
()
Ответ на: комментарий от wolverin

Включай проверки в stl, если сам не можешь их обеспечить.

#define _GLIBCXX_DEBUG
#include <string>

int main() {
  std::string s;
  s.pop_back();
}
/usr/include/c++/12/bits/basic_string.h:2094: void std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::pop_back() [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]: Assertion '!empty()' failed.
Аварийный останов

MOPKOBKA ★★★★
()
Последнее исправление: MOPKOBKA (всего исправлений: 1)
Ответ на: комментарий от rumgot

Нууу… это несколько контринтуитивно, во всяком случае для меня. Я понимаю отсутствие проверок в operator [], но тут… как то ожидаешь более высокоуровневого поведения от классов.

Для вектора та же шляпа.

AntonI ★★★★
()
Ответ на: комментарий от AntonI

МОРКОВКА всё верно написал.

А так у libstdc++ есть -D_GLIBCXX_DEBUG

/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/basic_string.h:2130: void std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::pop_back() [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]: Assertion '!empty()' failed.

https://gcc.godbolt.org/z/YaMP8d3Y1

В libc++ есть _LIBCPP_ENABLE_ASSERTIONS

/opt/compiler-explorer/clang-16.0.0/bin/../include/c++/v1/string:3265: assertion !empty() failed: string::pop_back(): string is already empty

https://gcc.godbolt.org/z/Mzqs588zW

А в Visual Studio это так выглядит если установить _ITERATOR_DEBUG_LEVEL в 1 или 2. (в Release сборках он по умолчанию 0, в DEBUG 2) : https://imgur.com/a/NMVtZzf

Эти проверки можно включить и в релизных сборках, если кому-то нужно. (в Visual C++ поэтому аж 3 режима, а не 2. _ITERATOR_DEBUG_LEVEL=1, там включены только проверки которые не сильно замедляют код. Но вообще этот режим собираются убрать, так как никто (или почти никто) не пользуется этим…

fsb4000 ★★★★★
()
Ответ на: комментарий от wolverin

UB - это не значит, что х знает что будет или черти будут летать и все сгорит. UB - это значит, что стандарт C++ не определяет, что там должно происходить и каждая реализация компилятора может вести себя по своему.

rumgot ★★★★★
()
Последнее исправление: rumgot (всего исправлений: 1)
Ответ на: комментарий от rumgot

Речь не про число, а поведение.

Па сути одним стандартным действием контейнер приводится в невосстановимое состояние.

wolverin ★★★
() автор топика
Последнее исправление: wolverin (всего исправлений: 1)
Ответ на: комментарий от AntonI

нет — тут все логично — тебе предоставляется способ проверки — в данном примере на empty — а ты можешь ее делать только в определенном слуае, и в остальных случаях, когда у тебя там заверенно хранится что-то не делать проверку. Zero-cast абстракция же.

safocl ★★
()
Ответ на: комментарий от wolverin

там сказ про то — что ты не можешь полагаться на какой либо результат отдельно взятой реализации... Сказано ub  — значит ub — без каких либо вариантов...

safocl ★★
()
Ответ на: комментарий от wolverin

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

safocl ★★
()
Ответ на: комментарий от safocl

Когда я оборачиваю какой то функционал в класс - я не занимаюсь хернёй по проверке целостности снаружи

Причем в духе - здесь проверяем, здесь не проверяем, а здесь рыбу заворачивали (с)

wolverin ★★★
() автор топика
Последнее исправление: wolverin (всего исправлений: 3)
Ответ на: комментарий от wolverin

так std::string тоже не занимается проверкой снаружи))) это должен делать программист — интерфейс вполне себе валидный и актуальный и недвусмысленный — при чем отлично документированный. И в документации (в стандарте) указано, что твое то действие на объекте, который empty — ub. Больше добавить нечего — можешь либо принять, либо дальше упираться. А еще можешь свою строку написать — вдруг она будет лучше стандартной.

safocl ★★
()