Как найти ошибку, из-за которой вылетает программа?

Модератор: Модераторы разделов

Ответить
MiK13
Сообщения: 1164
ОС: Linux Debian

Как найти ошибку, из-за которой вылетает программа?

Сообщение MiK13 »

Есть программа. Довольно большая (около двух десятков файлов .cpp и .h). Написана больше 10 лет назад другим человеком. Из другой организации.
Spoiler
Написана была на Борланд билдере. Для винды.
Когда-то вместе переводили её на gcc (g++). Перевели. Программа нормально работала пол линуксом.
Она в реальном времени принимает данные, их обрабатывает и выдаёт результат обработки.
Из принципиальных изменений был канал получения и выдачи данных. Первоначально это было по протоколу TCP: источник выдавал данные на некий "сервер", а программа их оттуда забирала и выдавала на него же, откуда их мог забрать "потребитель".
Я сделал, чтобы программа принимала данные через кольцевой буфер (так было удобнее), а выдавала по протоколу UDP.
Были ещё небольшие косметические доработки. В основном для выдачи протоколов работы. Но никаких принципиальных изменений не было.
И вот в связи с тем, что стали использовать 64-битные системы, решил её перетранслировать.
Трансляция проходит. Правда, с кучей предупреждений, но автор ещё тогда говорил, что на них не надо обращать внимания.
Но работать не хочет. То есть начинает и через несколько секунд вылетает. Странслированная когда-то 32-битная версия работает нормально.
Есть подозрение, что новый компилятор как-то по-другому транслирует. А старый найти проблема. (Иногда мне кажется, что кто-то раздавил бабочку :))
Пытаюсь найти место вылета под отладчиком. И вот, что обнаружил. Программа вылетает в месте, где используется переменная Map_Cell. Точнее, это объект класса. Объявлена в нём как map<int, CCell_KMP> Map_Cell;
Ставлю в gdb точки останова, где она используется. И вижу.

Код: Выделить всё

Breakpoint 1, Clasic_KMP_Sting::Calculate (this=0x61200000bd40, AzimuthAntena=0.2515709400177002, NumberCanal_E=0, time=1608734295.85675, T_obzora=10.792600604559416, 
    m=std::vector of length 1, capacity 1 = {...}) at InterferenceRejection.cpp:856
856	      Map_Cell.insert ( Map_Cell.end(), pair<int, CCell_KMP>(N_cell, CELL) );                   // Контейнер ячеек КМП
(gdb) p Map_Cell
$1 = std::map with 0 elements
(gdb) c
Continuing.

Breakpoint 1, Clasic_KMP_Sting::Calculate (this=0x61200000bbc0, AzimuthAntena=0.2515709400177002, NumberCanal_E=0, time=1608734295.85675, T_obzora=10.792600604559416, 
    m=std::vector of length 1, capacity 1 = {...}) at InterferenceRejection.cpp:856
856	      Map_Cell.insert ( Map_Cell.end(), pair<int, CCell_KMP>(N_cell, CELL) );                   // Контейнер ячеек КМП
(gdb) p Map_Cell
$2 = std::map with 0 elements
(gdb) c
Continuing.
 [057-239]  Az: 119.4  Tm: 52729.4 Targs: 0 
Breakpoint 3, Clasic_KMP_Sting::Calculate (this=0x61200000bd40, AzimuthAntena=2.0834600925445557, NumberCanal_E=0, time=1608734329.4622188, T_obzora=11.304437463364723, m=std::vector of length 0, capacity 1)
    at InterferenceRejection.cpp:906
906	      iterator_Cell it =  Map_Cell.find( VNC[j] );
(gdb) p Map_Cell
$3 = std::map with 24753 elements<error reading variable: Cannot access memory at address 0xaf90000060c4>
То есть при первой остановке этот объект имеет 0 элементов. При второй -- тоже 0. А вот при третьей -- 24753
Как это может получаться?
И как найти место, которое изменяет эту переменную?
Команда grep -o "Map_Cell.*()" *.cpp | sort | uniq показывает, что после Map_Cell в программе есть только: .begin(), .end(), .clear(), .insert() и .size().
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20752
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Как найти ошибку, из-за которой вылетает программа?

Сообщение Bizdelnick »

MiK13 писал:
23.12.2020 19:31
с кучей предупреждений, но автор ещё тогда говорил, что на них не надо обращать внимания.
Не надо обращать внимания, как правило, именно на такие слова. ☺
MiK13 писал:
23.12.2020 19:31
И как найти место, которое изменяет эту переменную?
watch Map_Cell
https://www.sourceware.org/gdb/onlinedocs/gdb/Set-Watchpoints.html
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
MiK13
Сообщения: 1164
ОС: Linux Debian

Re: Как найти ошибку, из-за которой вылетает программа?

Сообщение MiK13 »

Bizdelnick писал:
23.12.2020 19:52
MiK13 писал:
23.12.2020 19:31
с кучей предупреждений, но автор ещё тогда говорил, что на них не надо обращать внимания.
Не надо обращать внимания, как правило, именно не такие слова. ☺
Как я уже однажды писал, после того, как я потерял несколько часов из-за того, что при нажатии на <Enter> случайно задел клавишу с '\', я решил все свои программы траслировать с -Wall и добиваться отсутствия любых warning и note. Но оказалось, что то, что нормально для gcc, не нравится g++. Некоторые предупреждения у меня вопросов не вызывают и я знаю, как от них избавиться. Например,

Код: Выделить всё

FunctionsProcessing.cpp:36:2: warning: extra ‘;’ [-Wpedantic]
 };//0
  ^
Или массивы нулевого размера (возможно в будущем буду шире использовать union)
Но что делать с такими предупреждениями как

Код: Выделить всё

rmatrix.h:104:40: warning: friend declaration ‘T Sp(Rmatrix<T>&)’ declares a non-template function [-Wnon-template-friend]
   friend T          Sp     (Rmatrix<T>&);
                                        ^
я не знаю
Bizdelnick писал:
23.12.2020 19:52
MiK13 писал:
23.12.2020 19:31
И как найти место, которое изменяет эту переменную?
watch Map_Cell
https://www.sourceware.org/gdb/onlinedocs/gdb/Set-Watchpoints.html
Пытался. Не получается.
Причём, на работе (Debian 9.11) просто работа прерывается с сообщением, что не известно выражение.
Дома (Debian 10.4) ещё интереснее.
Вот что получается:

Код: Выделить всё

mik13@MD410:~/1/RDR/VOI1$ gdb ./voi
GNU gdb (Debian 8.2.1-2+b3) 8.2.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./voi...done.
(gdb) b InterferenceRejection.cpp:765
Breakpoint 1 at 0x94d86: file InterferenceRejection.cpp, line 765.
(gdb) r
Starting program: /home/mik13/1/VOI1/voi.

Breakpoint 1, Clasic_KMP_Sting::SetParametr_KMP (this=0x555555684ac0, PK=...) at InterferenceRejection.cpp:765
765         Map_Cell.clear();
(gdb) p Map_Cell
$1 = std::map with 0 elements
(gdb) watch Map_Cell.size()
Watchpoint 2: Map_Cell.size()
(gdb) c
Continuing.

[1]+  Остановлен    gdb ./voi
mik13@MD410:~/1/VOI1$ fg
gdb ./voi
Error evaluating expression for watchpoint 2
There is no member or method named Map_Cell.
Watchpoint 2 deleted.

[1]+  Остановлен    gdb ./voi
mik13@MD410:~/1/VOI1$ fg
gdb ./voi
Error evaluating expression for watchpoint 2
There is no member or method named Map_Cell.
Watchpoint 2 deleted.
std::map<int, CCell_KMP, std::less<int>, std::allocator<std::pair<int const, CCell_KMP> > >::clear (this=0x555555685dac) at /usr/include/c++/8/bits/stl_map.h:1132
1132          clear() _GLIBCXX_NOEXCEPT
(gdb)
При попытке продолжить выполнение программы после установки наблюдения за значением Map_Cell.size() вдруг происходит выход в bash. Который повторяется ещё раз. И отладчик сообщает, что не знает, что такое Map_Cell.
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20752
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Как найти ошибку, из-за которой вылетает программа?

Сообщение Bizdelnick »

Ну не знаю, у меня работает:

Shell

% cat test.cc
#include <map>

int main ()
{
std::map<int, int> m;

m.insert(m.end(), std::pair<int, int>(1, 1));
m.insert(m.end(), std::pair<int, int>(2, 1));
m.insert(m.end(), std::pair<int, int>(3, 1));

return 0;
}
% g++ -Wall -g test.cc
% gdb ./a.out
GNU gdb (Debian 8.2.1-2+b3) 8.2.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./a.out...done.
(gdb) break main
Breakpoint 1 at 0x11d1: file test.cc, line 5.
(gdb) run
Starting program: /home/mikhirev/tmp/a.out

Breakpoint 1, main () at test.cc:5
5 std::map<int, int> m;
(gdb) watch m
Watchpoint 2: m
(gdb) c
Continuing.

Watchpoint 2: m

Old value = std::map with 0 elements
New value = std::map with 0 elements
std::_Rb_tree_header::_M_reset (this=0x7fffffffe588) at /usr/include/c++/8/bits/stl_tree.h:209
209 _M_header._M_left = &_M_header;
(gdb) bt
#0 std::_Rb_tree_header::_M_reset (this=0x7fffffffe588) at /usr/include/c++/8/bits/stl_tree.h:209
#1 0x0000555555555382 in std::_Rb_tree_header::_Rb_tree_header (this=0x7fffffffe588) at /usr/include/c++/8/bits/stl_tree.h:176
#2 0x00005555555554b4 in std::_Rb_tree<int, std::pair<int const, int>, std::_Select1st<std::pair<int const, int> >, std::less<int>, std::allocator<std::pair<int const, int> > >::_Rb_tree_impl<std::less<int>, true>::_Rb_tree_impl (
this=0x7fffffffe580) at /usr/include/c++/8/bits/stl_tree.h:703
#3 0x00005555555553f6 in std::_Rb_tree<int, std::pair<int const, int>, std::_Select1st<std::pair<int const, int> >, std::less<int>, std::allocator<std::pair<int const, int> > >::_Rb_tree (this=0x7fffffffe580)
at /usr/include/c++/8/bits/stl_tree.h:929
#4 0x0000555555555412 in std::map<int, int, std::less<int>, std::allocator<std::pair<int const, int> > >::map (this=0x7fffffffe580) at /usr/include/c++/8/bits/stl_map.h:183
#5 0x00005555555551e0 in main () at test.cc:5
(gdb) c
Continuing.

Watchpoint 2: m

Old value = std::map with 0 elements
New value = std::map with 0 elements
std::_Rb_tree_header::_M_reset (this=0x7fffffffe588) at /usr/include/c++/8/bits/stl_tree.h:210
210 _M_header._M_right = &_M_header;
(gdb) bt
#0 std::_Rb_tree_header::_M_reset (this=0x7fffffffe588) at /usr/include/c++/8/bits/stl_tree.h:210
#1 0x0000555555555382 in std::_Rb_tree_header::_Rb_tree_header (this=0x7fffffffe588) at /usr/include/c++/8/bits/stl_tree.h:176
#2 0x00005555555554b4 in std::_Rb_tree<int, std::pair<int const, int>, std::_Select1st<std::pair<int const, int> >, std::less<int>, std::allocator<std::pair<int const, int> > >::_Rb_tree_impl<std::less<int>, true>::_Rb_tree_impl (
this=0x7fffffffe580) at /usr/include/c++/8/bits/stl_tree.h:703
#3 0x00005555555553f6 in std::_Rb_tree<int, std::pair<int const, int>, std::_Select1st<std::pair<int const, int> >, std::less<int>, std::allocator<std::pair<int const, int> > >::_Rb_tree (this=0x7fffffffe580)
at /usr/include/c++/8/bits/stl_tree.h:929
#4 0x0000555555555412 in std::map<int, int, std::less<int>, std::allocator<std::pair<int const, int> > >::map (this=0x7fffffffe580) at /usr/include/c++/8/bits/stl_map.h:183
#5 0x00005555555551e0 in main () at test.cc:5
(gdb) c
Continuing.

Watchpoint 2: m

Old value = std::map with 0 elements
New value = std::map with 0 elements
std::_Rb_tree_header::_M_reset (this=0x7fffffffe588) at /usr/include/c++/8/bits/stl_tree.h:211
211 _M_node_count = 0;
(gdb) bt
#0 std::_Rb_tree_header::_M_reset (this=0x7fffffffe588) at /usr/include/c++/8/bits/stl_tree.h:211
#1 0x0000555555555382 in std::_Rb_tree_header::_Rb_tree_header (this=0x7fffffffe588) at /usr/include/c++/8/bits/stl_tree.h:176
#2 0x00005555555554b4 in std::_Rb_tree<int, std::pair<int const, int>, std::_Select1st<std::pair<int const, int> >, std::less<int>, std::allocator<std::pair<int const, int> > >::_Rb_tree_impl<std::less<int>, true>::_Rb_tree_impl (
this=0x7fffffffe580) at /usr/include/c++/8/bits/stl_tree.h:703
#3 0x00005555555553f6 in std::_Rb_tree<int, std::pair<int const, int>, std::_Select1st<std::pair<int const, int> >, std::less<int>, std::allocator<std::pair<int const, int> > >::_Rb_tree (this=0x7fffffffe580)
at /usr/include/c++/8/bits/stl_tree.h:929
#4 0x0000555555555412 in std::map<int, int, std::less<int>, std::allocator<std::pair<int const, int> > >::map (this=0x7fffffffe580) at /usr/include/c++/8/bits/stl_map.h:183
#5 0x00005555555551e0 in main () at test.cc:5
(gdb) c
Continuing.

Watchpoint 2: m

Old value = std::map with 0 elements
New value = std::map with 0 elements
0x00007ffff7ebb603 in std::_Rb_tree_insert_and_rebalance(bool, std::_Rb_tree_node_base*, std::_Rb_tree_node_base*, std::_Rb_tree_node_base&) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
(gdb) bt
#0 0x00007ffff7ebb603 in std::_Rb_tree_insert_and_rebalance(bool, std::_Rb_tree_node_base*, std::_Rb_tree_node_base*, std::_Rb_tree_node_base&) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#1 0x0000555555555df7 in std::_Rb_tree<int, std::pair<int const, int>, std::_Select1st<std::pair<int const, int> >, std::less<int>, std::allocator<std::pair<int const, int> > >::_M_insert_node (this=0x7fffffffe580, __x=0x0,
__p=0x7fffffffe588, __z=0x55555556be70) at /usr/include/c++/8/bits/stl_tree.h:2320
#2 0x00005555555556ea in std::_Rb_tree<int, std::pair<int const, int>, std::_Select1st<std::pair<int const, int> >, std::less<int>, std::allocator<std::pair<int const, int> > >::_M_emplace_hint_unique<std::pair<int, int> > (
this=0x7fffffffe580, __pos={first = 0, second = 0}, __args#0=...) at /usr/include/c++/8/bits/stl_tree.h:2421
#3 0x000055555555558b in std::map<int, int, std::less<int>, std::allocator<std::pair<int const, int> > >::insert<std::pair<int, int> > (this=0x7fffffffe580, __position={first = 0, second = 0}, __x=...)
at /usr/include/c++/8/bits/stl_map.h:876
#4 0x0000555555555245 in main () at test.cc:7
И т. д. Что у Вас не так — не видя кода, догадаться не могу. Возможно, Map_Cell вне области видимости. Возможно, у Вас там вообще разные Map_Cell в разных областях видимости.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
MiK13
Сообщения: 1164
ОС: Linux Debian

Re: Как найти ошибку, из-за которой вылетает программа?

Сообщение MiK13 »

Bizdelnick писал:
23.12.2020 19:52
watch Map_Cell
Попробовал. Но столкнулся с проблемой видимости Map_Cell. Когда отладка останавливается по изменению значения, Map_Cell просто не виден.
Решил контролировать "размер" Map_Cell косвенным путём: int *AM=&Map_Cell и потом watch AM[8]
Получилось. Но bt выдал трассу из 9 строк. Причём,
#0 указывает на from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#1 -- на at /usr/include/c++/6/bits/stl_tree.h:1537
#2 -- на at /usr/include/c++/6/bits/stl_tree.h:2004
#3 -- на at /usr/include/c++/6/bits/stl_tree.h:950
#4 -- на at /usr/include/c++/6/bits/stl_map.h:794
Следующие 4 -- уже на строки в программе.
Добавил такую отладку (перед и после .insert):

Код: Выделить всё

      if(DeBug&64) fprintf(stderr,"  >>>>>>> &Map_Cell=%p, size: %ld ==(%d)==> ",(void *)&Map_Cell,Map_Cell.size(),N_cell);
      Map_Cell.insert ( Map_Cell.end(), pair<int, CCell_KMP>(N_cell, CELL) );
      if(DeBug&64) fprintf(stderr,"%ld\n",Map_Cell.size()); 
Получил такой вывод:

Shell

>>>>>>> &Map_Cell=0x55bf6574ccf8, size: 0 ==(58660)==> 21952
>>>>>>> &Map_Cell=0x55bf6574ce58, size: 0 ==(58660)==> 21952
>>>>>>> &Map_Cell=0x55bf6574ccf8, size: 21952 ==(61009)==> Ошибка сегментирования
Сначала я не понимал почему печатается разное значение в качестве адреса Map_Cell, но потом понял, что в классе DeviceBeforeProtected_SING есть два объекта, pClasic_KMP_1 и pClasic_KMP_2 типа Clasic_KMP*, класса, в который входит map<int, CCell_KMP> Map_Cell;
Из того, что я почитал про метод .insert(), у меня сложилось впечатление, что он добавляет один элемент. Но тут получается, что после его выполнения число элементов увеличивается на 20 с лишнем тысяч. Причём, значения могут быть разные.
Правда, я разбирался в основном с vector. А тут map
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20752
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Как найти ошибку, из-за которой вылетает программа?

Сообщение Bizdelnick »

MiK13 писал:
29.12.2020 16:24
Из того, что я почитал про метод .insert(), у меня сложилось впечатление, что он добавляет один элемент.
Так и есть.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
MiK13
Сообщения: 1164
ОС: Linux Debian

Re: Как найти ошибку, из-за которой вылетает программа?

Сообщение MiK13 »

С программой что-то непонятное.
Я решил поменять стандарт. Добавил компилятору опцию std=c++11.
Дома запустил -- программа отработала чуть больше, чем обычно.
Запустил с отладочной печатью -- стала работать. И даже выдавать результат. Потом, правда, перестала.
Из действий, что я делал -- только приводил вид кода к одному стилю; комментарии на одном уровне и довольно далеко от кода, все отступы по два пробела, открывающая скобка после оператора, а закрывающая на одном уровне с ним.
Сейчас на работе стал дальше проверять. Вылетает, но уже не на системной файле (по данным gdb), а в одном из .h файлов.
Что смущает. Вывод отладчика:

Shell

Program received signal SIGSEGV, Segmentation fault.
0x00005555555957f3 in Rmatrix<double>::operator= (this=0x7fffffffcd60, __M=...) at rmatrix.h:355
355 M[i][j] = __M[i][j];
Смотрю файл rmatix.h:

Код: Выделить всё

template<class T>
Rmatrix<T>& Rmatrix<T>::operator=(const Rmatrix<T>& __M) {
  if(size==0) {
    size=__M.size;
    size1=__M.size1;
    M=new T*[size];
    for(int i=0;i<size;i++) M[i]=new T[size1];
  }
  if((size !=__M.size)||(size1 !=__M.size1)) {
    for(int i=0; i<size; i++) delete[] M[i];; delete[] M;
    size=__M.size;
    size1=__M.size1;
    M=new T*[size];
    for(int i=0;i<size;i++) M[i]= new T[size1];
  }
  for (int i=0; i<size; i++)
    for (int j=0; j<size1; j++)
      M[i][j] = __M[i][j];                             /// !!! (355)
  return *this;
}
Строка 355 подчёркнута (я использую редактор geany). И предупреждение компилятора:

Shell

rmatrix.h:355:20: required from ‘Rmatrix<T>& Rmatrix<T>::operator=(const Rmatrix<T>&) [with T = double]’
BunchTraject.cpp:664:40: required from here
rmatrix.h:74:65: warning: returning reference to temporary [-Wreturn-local-addr]
const T* const & operator[](int index)const{return M[index];};
^
А вот как объявлен сам класс:

Код: Выделить всё

template <class T> class Rmatrix {
  T **M;
public:
  int size;
  int size1;
  // constructors
  Rmatrix(int);
  Rmatrix(int,T);
  Rmatrix(int,int);
  Rmatrix(int,int, T);
  Rmatrix(void);
  Rmatrix(const Rmatrix<T>&);
  ~Rmatrix(void);
  Rmatrix<T>&   operator=(const Rmatrix<T> &);
  T*&           operator[](int index)     {return M[index];};
  const T* const &     operator[](int index)const{return M[index];};                 /// !!! (74)
  //    T*&           operator[](int index)     {return (T*)M[index];};
  //    const T*&     operator[](int index)const{return (T*)M[index];};
  int           GetSize(){return size;};
  Rmatrix<T>&   operator+=(Rmatrix<T>&);
  Rmatrix<T>&   operator-=(Rmatrix<T>&);
  Rmatrix<T>&   operator*=(T);
  Rmatrix<T>&   operator*=(Rmatrix<T>&);
  Rmatrix<T>&   operator/=(T);
  Rmatrix<T>    operator+();
  Rmatrix<T>    operator-();

  // === AS begin
  T Find_MaxElement(int &row, int &col );       // Найти значение максимального элемента в матрице и его
                                                // координаты - строка, столбец
  T Find_MinElement(int &row, int &col );       // Найти значение минимального  элемента в матрице и его
                                                // координаты - строка, столбец
  Rvector<T> getRow   (int row);                // Вернуть строку
  void setRow         (int row, T v          ); // Присвоить значениям строки значение переменной
  void setRow         (int row, Rvector<T> &v); // Присвоить значениям строки значение вектора
  Rvector<T> getColumn(int col);                // Вернуть колонку
  void setColumn      (int col, T v          ); // Присвоить значениям Столбца значение переменной
  void setColumn      (int col, Rvector<T> &v); // Присвоить значениям Столбца значение вектора
  void FillUpMatrix   (Rmatrix<T> &MAT       ); // Заполнить матрицу значениямиМатрицы MAT
                                                // (Используется в тех случаях когда размеры матриц не совпадают)
  // === AS end


  friend class Rvector<T>;
  friend Rmatrix<T> transp (Rmatrix<T>&);                 /// !!! (103)
  friend T          Sp     (Rmatrix<T>&);                 /// !!! (104)
  friend T          tr     (Rmatrix<T>&);                 /// !!! (105)
  friend Rmatrix<T> inverse(Rmatrix<T>&);                 /// !!! (106)
  friend T          det    (Rmatrix<T>&);                 /// !!! (107)

};
В нём подчёркнута строка 74. И ещё строки 103 ... 107. На них предупреждения типа

Shell

rmatrix.h:103:40: warning: friend declaration ‘Rmatrix<T> transp(Rmatrix<T>&)’ declares a non-template function [-Wnon-template-friend]
friend Rmatrix<T> transp (Rmatrix<T>&);
^
rmatrix.h:103:40: note: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here)
rmatrix.h:104:40: warning: friend declaration ‘T Sp(Rmatrix<T>&)’ declares a non-template function [-Wnon-template-friend]
friend T Sp (Rmatrix<T>&);
^
rmatrix.h:105:40: warning: friend declaration ‘T tr(Rmatrix<T>&)’ declares a non-template function [-Wnon-template-friend]
friend T tr (Rmatrix<T>&);
Случайно ли совпадение о строке, на которой вылетела программа с предупреждением компилятора?
Спасибо сказали:
Аватара пользователя
s.xbatob
Сообщения: 1139
ОС: Fedora

Re: Как найти ошибку, из-за которой вылетает программа?

Сообщение s.xbatob »

Похоже, у вас в динамической памяти нагажено. Либо где-то вылезаете за границы объекта, либо, что более вероятно, используете уже удалённые.
Ловить это сложно: крах может произойти гораздо позже реального инцидента и в совершенно случайном месте.
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20752
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Как найти ошибку, из-за которой вылетает программа?

Сообщение Bizdelnick »

Могу предположить, что там ошибка в конструкторе, в результате которой либо M указывает в никуда, но size отличен от 0, либо один из M[ i ] указывает в никуда, хотя i<size, либо размер M[ i ] оказывается меньше size1
Вообще, раз там такие приколы имеют место быть, рекомендую собирать для проверки с -fsanitize=address,undefined.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
MiK13
Сообщения: 1164
ОС: Linux Debian

Re: Как найти ошибку, из-за которой вылетает программа?

Сообщение MiK13 »

Bizdelnick писал:
30.12.2020 14:10
Вообще, раз там такие приколы имеют место быть, рекомендую собирать для проверки с -fsanitize=address,undefined.
Я собирал с -fsanitize=address, но потом отказался, так как были непонятные (для меня) проблемы с valgrind'ом.
Сейчас собрал с -fsanitize=address,undefined (как я понял, эту опцию надо указывать только для окончательной сборки).
Произошло следующее.
Запустил под gdb, поставил точку останова b InterferenceRejection.cpp:541 на начало функции

Код: Выделить всё

Sektor_KMP::Sektor_KMP(int Num, double LS, double RS) {           /// Line 541
   Number    = Num;                                               // Номер сектора
   LeftSeite = LS;   RightSeite = RS;                             // (рад) Левая и правая границы сектора
}
Запустил (r). После остановки в указанном месте выдал команду на шаг (s) и получил:

Shell

InterferenceRejection.cpp:541:53: runtime error: constructor call on misaligned address 0x7fffffffc894 for type 'struct vector', which requires 8 byte alignment
0x7fffffffc894: note: pointer points here
10 ac bd 55 55 55 00 00 40 bf 00 00 80 60 00 00 c0 c8 ff ff ff 7f 00 00 40 bf 00 00 80 60 00 00
^
std::vector<int, std::allocator<int> >::vector (this=0x7fffffffc894) at /usr/include/c++/6/bits/stl_vector.h:255
255 vector()
Причём ошибка эта не фатальная. Работа программы продолжается после группы таких сообщений.
И показываемые значения могут быть разные. При другом запуске выскочило

Shell

InterferenceRejection.cpp:541:53: runtime error: constructor call on misaligned address 0x7fffffffc884 for type 'struct vector', which requires 8 byte alignment
0x7fffffffc884: note: pointer points here
00 00 00 00 e0 aa 15 41 00 00 00 00 00 00 00 00 86 64 8b 68 ce 1a b4 3f 00 00 00 00 00 00 00 00
^
std::vector<int, std::allocator<int> >::vector (this=0x7fffffffc884) at /usr/include/c++/6/bits/stl_vector.h:255
255 vector()
Почему vector ТУТ -- не знаю,
Судя по bt эта функция вызвана из строки 746

Код: Выделить всё

  int N_sektor = 10;                                                       /// Line 743
  sizeSektor   = 2.0*M_PI/double(N_sektor);                                /// Line 744
  for(int i = 0; i<10; i++) {                                              /// Line 745
    Sektor_KMP FS( i, double(i)*sizeSektor, double(i+1)*sizeSektor );      /// Line 746
    VectSektor.push_back(FS);                                              /// Line 747
  }
Добавление к вектору VectSektor должно происходить в 747-й строке, ПОСЛЕ вызова конструктора.
Удивляют слова misaligned address 0x7fffffffc894 for type 'struct vector', which requires 8 byte alignment. При том, что в начале я поставил #pragma pack(8).
Может быть из-за того, что после аргумента int идёт аргумент double?
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20752
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Как найти ошибку, из-за которой вылетает программа?

Сообщение Bizdelnick »

MiK13 писал:
04.01.2021 13:18
Bizdelnick писал:
30.12.2020 14:10
Вообще, раз там такие приколы имеют место быть, рекомендую собирать для проверки с -fsanitize=address,undefined.
Я собирал с -fsanitize=address, но потом отказался, так как были непонятные (для меня) проблемы с valgrind'ом.
Так не нужен при такой сборке valgrind. Этот санитайзер делает ровно то же самое, что и valgrind memcheck.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20752
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Как найти ошибку, из-за которой вылетает программа?

Сообщение Bizdelnick »

MiK13 писал:
04.01.2021 13:18
Запустил под gdb
А без gdb запускать пробовали?
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20752
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Как найти ошибку, из-за которой вылетает программа?

Сообщение Bizdelnick »

MiK13 писал:
04.01.2021 13:18
Судя по bt эта функция вызвана из строки 746

Код: Выделить всё

  int N_sektor = 10;                                                       /// Line 743
  sizeSektor   = 2.0*M_PI/double(N_sektor);                                /// Line 744
  for(int i = 0; i<10; i++) {                                              /// Line 745
    Sektor_KMP FS( i, double(i)*sizeSektor, double(i+1)*sizeSektor );      /// Line 746
    VectSektor.push_back(FS);                                              /// Line 747
  }
Добавление к вектору VectSektor должно происходить в 747-й строке, ПОСЛЕ вызова конструктора.
Удивляют слова misaligned address 0x7fffffffc894 for type 'struct vector', which requires 8 byte alignment.
А какое значение в итоге у sizeSektor? И что делает конструктор? У меня такое впечатление, что он пытается создать новый вектор из куска существующего со смещением, не кратным 8.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
MiK13
Сообщения: 1164
ОС: Linux Debian

Re: Как найти ошибку, из-за которой вылетает программа?

Сообщение MiK13 »

Bizdelnick писал:
04.01.2021 15:29
MiK13 писал:
04.01.2021 13:18
Судя по bt эта функция вызвана из строки 746

Код: Выделить всё

  int N_sektor = 10;                                                       /// Line 743
  sizeSektor   = 2.0*M_PI/double(N_sektor);                                /// Line 744
  for(int i = 0; i<10; i++) {                                              /// Line 745
    Sektor_KMP FS( i, double(i)*sizeSektor, double(i+1)*sizeSektor );      /// Line 746
    VectSektor.push_back(FS);                                              /// Line 747
  }
Добавление к вектору VectSektor должно происходить в 747-й строке, ПОСЛЕ вызова конструктора.
Удивляют слова misaligned address 0x7fffffffc894 for type 'struct vector', which requires 8 byte alignment.
А какое значение в итоге у sizeSektor? И что делает конструктор? У меня такое впечатление, что он пытается создать новый вектор из куска существующего со смещением, не кратным 8.
По данным отладчика у sizeSektor значение вполне нормальное, 0.628... -- 2*M_PI/10.
Конструктор:

Код: Выделить всё

Sektor_KMP::Sektor_KMP(int Num, double LS, double RS) {
  if(DeBug&4)
    fprintf(stderr,"&Number     = %p\n&LeftSeite  = %p\n&RightSeite = %p\n",&Number,&LeftSeite,&RightSeite);
  Number    = Num;                                                                              // Номер сектора
  LeftSeite = LS; RightSeite = RS;                                                              // (рад) Левая и правая границы сектора
}
(печать -- моя добавка)
Тут ещё вот, что выявилось.
В другом модуле в "операторе присваивания" я добавил печать.

Код: Выделить всё

void Measure::operator = (const Measure& tM) {//0
  if(DeBug&128) fprintf(stderr," --==>>> &tM = %p\n",&tM);
  NumberUniqueM = tM.NumberUniqueM;                    /// Line 116
  Z = tM.Z; Z_Disper = tM.Z_Disper;                    /// Line 117
  X = tM.X; X_Disper = tM.X_Disper;                    /// Line 118
  R = tM.R; B = tM.B; E = tM.E;                        /// Line 119
  Time      = tM.Time;                                 /// Line 120
  InBlanc   = tM.InBlanc;                              /// Line 121
  amplitude = tM.amplitude;                            /// Line 122
}//0
и вот, что получил при работе программы:

Shell

--==>>> &tM = 0x60b000008bd0
--==>>> &tM = 0x7fffae8883d0
--==>>> &tM = 0x7fffae888120
--==>>> &tM = 0x7fffae8878d0
--==>>> &tM = 0x7fffae888120
--==>>> &tM = 0x7fffae887990
--==>>> &tM = 0x7fffae888120
--==>>> &tM = 0x7fffae887a50
--==>>> &tM = 0x7fffae888120
--==>>> &tM = 0x7fffae887b10
--==>>> &tM = 0x7fffae887ab0
--==>>> &tM = 0x7fffae887b70
--==>>> &tM = 0x621000014799
DataExchange.cpp:116:22: runtime error: member access within misaligned address 0x621000014799 for type 'const struct Measure', which requires 8 byte alignment
0x621000014799: note: pointer points here
00 00 f0 3f d0 e8 a0 c8 01 56 00 00 ff ff ff ff 00 be be be d5 92 95 82 71 0f e2 40 08 ce 8d ef
^
Причём, сообщение об ошибке повторялось по два раза для всех строк с 116 по 122.
Но ошибка эта не фатальная и были моменты, когда моя печать показывала нормальное значение адреса так, что они не умещались на экране.
Добавлено (16:17):
Сейчас посмотрел фрагмент вывода и обнаружил следующий участок

Shell

--==>>> &tM = 0x7fffae887b40
--==>>> &tM = 0x7fffae887c00
--==>>> &tM = 0x6210000138e1
--==>>> &tM = 0x7fffae8881e0
--==>>> &tM = 0x621000013239
--==>>> &tM = 0x60b0000089c0
--==>>> &tM = 0x7fffae8881f0
Два раза встретился нечётный адрес, но сообщений об ошибке не было.
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20752
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Как найти ошибку, из-за которой вылетает программа?

Сообщение Bizdelnick »

MiK13 писал:
04.01.2021 16:12
По данным отладчика у sizeSektor значение вполне нормальное, 0.628... -- 2*M_PI/10.
А, разлепил наконец глаза и увидел, где он определяется.
Нет, я так не угадаю, что там к чему. Надо все определения классов видеть.
MiK13 писал:
04.01.2021 16:12
Но ошибка эта не фатальная
А Вас только фатальные ошибки беспокоят? Пофиг, что делает программа и какой результат выдаст, лишь бы не падала? Тогда могу дать простой совет: выкиньте весь этот код, пусть она просто "hello world" печатает, и довольно. Падать не будет, скорее всего.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
devilr
Сообщения: 3665
ОС: Mandriva => Gentoo (~amd64)
Контактная информация:

Re: Как найти ошибку, из-за которой вылетает программа?

Сообщение devilr »

Bizdelnick писал:
04.01.2021 16:59
Тогда могу дать простой совет: выкиньте весь этот код, пусть она просто "hello world" печатает, и довольно. Падать не будет, скорее всего.
5 баллов! :D
Мудрость приходит с возрастом.
Иногда возраст приходит один.
Эхо разума
Спасибо сказали:
MiK13
Сообщения: 1164
ОС: Linux Debian

Re: Как найти ошибку, из-за которой вылетает программа?

Сообщение MiK13 »

Bizdelnick писал:
04.01.2021 16:59
А Вас только фатальные ошибки беспокоят?
Конечно нет :)
Основная проблема в том, что при фатальной ошибке AddressSanitizer печатает стек с указанием мест в программе. Можно попытаться проверить данные.
А при нефатальной просто печатает номер строки в .h файле в каталоге /usr/include/c++/6/bits. При этом она может произойти, а может и нет.
Я записал вывод stderr в файл. Получил в нём 1111 строк моего вывода с нормальным значением адреса (кратным 8), а потом, вдруг,

Shell

/usr/include/c++/6/bits/stl_vector.h:427:28: runtime error: member call on misaligned address 0x621000008a82 for type 'struct _Vector_base', which requires 8 byte alignment
0x621000008a82: note: pointer points here
00 00 00 00 d0 c3 00 00 40 60 00 00 f8 c3 00 00 40 60 00 00 f8 c3 00 00 40 60 00 00 00 01 00 00
^
Поставить точку остановка на /usr/include/c++/6/bits/stl_vector.h:427 не трудно. Но можно ли сделать, чтобы она сработала только если указатель будет не кратен 8?
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20752
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Как найти ошибку, из-за которой вылетает программа?

Сообщение Bizdelnick »

Сделать все ошибки фатальными несложно: export ASAN_OPTIONS=abort_on_error=1
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
MiK13
Сообщения: 1164
ОС: Linux Debian

Re: Как найти ошибку, из-за которой вылетает программа?

Сообщение MiK13 »

Bizdelnick писал:
04.01.2021 18:43
Сделать все ошибки фатальными несложно: export ASAN_OPTIONS=abort_on_error=1
Спасибо. Завтра попробую.
Спасибо сказали:
MiK13
Сообщения: 1164
ОС: Linux Debian

Re: Как найти ошибку, из-за которой вылетает программа?

Сообщение MiK13 »

Bizdelnick писал:
04.01.2021 18:43
Сделать все ошибки фатальными несложно: export ASAN_OPTIONS=abort_on_error=1
Попробовал. Но это ничего не дало. Выскакивают сообщения типа

Shell

StructExchangeDataNet.cpp:370:50: runtime error: constructor call on misaligned address 0x7ffdc8422283 for type 'struct CriterionCondition', which requires 4 byte alignment
0x7ffdc8422283: note: pointer points here
04 00 00 00 00 00 00 00 00 d0 4e 90 68 b0 7f 00 00 f8 44 90 68 b0 7f 00 00 a0 51 78 67 b0 7f 00
^
И работа программы продолжается.
Правда, это меня особо не удивляет. На сколько я знаю, архитектура X86 не требует выравнивания адреса кода или данных.

Но меня больше смущает то, что когда программа вылетает, AddressSanitizer указывает на те строки, на которые "ворчит" компилятор.
В частности:

Shell

In file included from BunchTraject.h:6:0,
from BunchTraject.cpp:6:
rmatrix.h: In instantiation of ‘const T* const& Rmatrix<T>::operator[](int) const [with T = double]’:
rmatrix.h:359:99: required from ‘Rmatrix<T>& Rmatrix<T>::operator=(const Rmatrix<T>&) [with T = double]’
BunchTraject.cpp:662:37: required from here
rmatrix.h:74:68: warning: returning reference to temporary [-Wreturn-local-addr]
const T* const & operator[](int index) const { return M[index]; }
^
Строки, о которых предупреждает компилятор:

Код: Выделить всё

template<class T> class Rmatrix {
  T **M;
public:
  int size;
  int size1;
  // constructors
  Rmatrix(int);
  Rmatrix(int,T);
  Rmatrix(int,int);
  Rmatrix(int,int, T);
  Rmatrix(void);
  Rmatrix(const Rmatrix<T>&);
 ~Rmatrix(void);
  Rmatrix<T>     & operator=(const Rmatrix<T> &);
        T*       & operator[](int index)       { return     M[index]; }
  const T* const & operator[](int index) const { return     M[index]; }     /// Line 74
  ...
    for(int i=0; i<size; i++) {
    //~ if(DeBug&128) fprintf(stderr,"  ---==> %d: %p -- > %p\n",i,M[i],__M[i]);
    for(int j=0; j<size1; j++) {
      if(DeBug&128) fprintf(stderr,"   3--==> &M[%d][%d]=%p <==--- %p,%p\n",i,j,&M[i][j],&__M,&__M[i]); /// Line 359
      M[i][j] = __M[i][j];                                                  /// Line 360
    }
  }
При "вылете" программ в stderr выдаётся:

Shell

rmatrix.h:74:68: runtime error: reference binding to null pointer of type 'const double *'
3--==> &M[0][0]=0x606000008ae0 <==--- 0x7fff8882fe70,(nil)
rmatrix.h:360:23: runtime error: load of null pointer of type 'const double *'
ASAN:DEADLYSIGNAL
=================================================================
==7168==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x563a35645892 bp 0x7fff8882fda0 sp 0x7fff8882fd40 T0)
#0 0x563a35645891 in Rmatrix<double>::operator=(Rmatrix<double> const&) /Work/RDR/VOI1/rmatrix.h:360
#1 0x563a3563e172 in BunchTrajector::disassemble(double) /Work/RDR/VOI1/BunchTraject.cpp:662
#2 0x563a357fcdf3 in IdentificationDevice::getTrajectoryIsLaterWork(double, double) /Work/RDR/VOI1/IdentificationDevice.cpp:492
Впечатление, что после обращения к подпрограмме используются её временные данные.
В чистом C я бы разобрался. В C++ с его классами и переопределением операторов не могу :(
Спасибо сказали:
Аватара пользователя
devilr
Сообщения: 3665
ОС: Mandriva => Gentoo (~amd64)
Контактная информация:

Re: Как найти ошибку, из-за которой вылетает программа?

Сообщение devilr »

MiK13 писал:
13.01.2021 13:35
В чистом C я бы разобрался. В C++ с его классами и переопределением операторов не могу
А в чём принципиальная разница? Код есть, отладчик есть, желание, вроде, тоже есть. :)
Не, если вы привыкли искать ошибки просто "глазами в коде", тогда увы - c++ немного сложнее простого c.
Мудрость приходит с возрастом.
Иногда возраст приходит один.
Эхо разума
Спасибо сказали:
MiK13
Сообщения: 1164
ОС: Linux Debian

Re: Как найти ошибку, из-за которой вылетает программа?

Сообщение MiK13 »

devilr писал(а):
13.01.2021 13:42
MiK13 писал:
13.01.2021 13:35
В чистом C я бы разобрался. В C++ с его классами и переопределением операторов не могу
А в чём принципиальная разница?
Разница в том, что мне много приходилось писать на языках без объектов -- Fortran-4, PL/1, Macro-11, PL-11,Pascal, C. Где, исходя из кода, можно понять, что делается.
А C++, в котором при простом операторе вызывается функция, которая что-то делает с объектами, смысл которых мне не известен...
Спасибо сказали:
Аватара пользователя
devilr
Сообщения: 3665
ОС: Mandriva => Gentoo (~amd64)
Контактная информация:

Re: Как найти ошибку, из-за которой вылетает программа?

Сообщение devilr »

MiK13 писал:
13.01.2021 14:20
А C++, в котором при простом операторе вызывается функция, которая что-то делает с объектами, смысл которых мне не известен...
Т.е., если я правильно вас понял, вы не понимаете, что делают объекты в программе (их "смысл") и пытаетесь ошибку найти?
Мудрость приходит с возрастом.
Иногда возраст приходит один.
Эхо разума
Спасибо сказали:
MiK13
Сообщения: 1164
ОС: Linux Debian

Re: Как найти ошибку, из-за которой вылетает программа?

Сообщение MiK13 »

devilr писал(а):
13.01.2021 14:44
MiK13 писал:
13.01.2021 14:20
А C++, в котором при простом операторе вызывается функция, которая что-то делает с объектами, смысл которых мне не известен...
Т.е., если я правильно вас понял, вы не понимаете, что делают объекты в программе (их "смысл") и пытаетесь ошибку найти?
Именно так.
Программа была написана другим человеком больше 10 лет назад. На Borland Builder. Потом мы вместе переводили её на GCC.
Перевели. Моя доработка заключалась в изменении способа передачи данных. И согласовании формата данных с теми программами, что я сам разрабатывал. В неё потом добавлялись некоторые отладочные печати для большего контроля входных данных.
Программа нормально работала. В версии 32 бита. И сейчас работает.
Но после перехода на 64 бита я попробовал её странслировать и запустить. Иногда она может некоторое время проработать. Потом вылетает. Чаще вылетает через 20-30 секунд работы.
В программе около 20 модулей (пар .cpp и .h) больше 25 тыс. строк. Я знаю только общие принципы её работы.
Спасибо сказали:
Аватара пользователя
Hephaestus
Сообщения: 3729
Статус: Многоуважаемый джинн...
ОС: Slackware64-14.1/14.2
Контактная информация:

Re: Как найти ошибку, из-за которой вылетает программа?

Сообщение Hephaestus »

MiK13 писал:
13.01.2021 15:28
Я знаю только общие принципы её работы.
Если программа изначально была под Borland Builder (вероятно, под DOS?),
а Вы перевели её на GCC (Linux?),
то по сути Вы портировали её на другую платформу.
Следовательно, Вы так или иначе вникали в суть кода.
По-другому просто не получится.
Если добиваться только успешной сборки, (устраняя ошибки сброки),
то логические нестыковки, конечно, останутся.
Однако, программа у Вас работала, следовательно, портировали её успешно.
Выполнить такую работу, не вникая в код и в логику работы, практически невозможно.
Поэтому Ваши слова выглядят странно.
Пускай скрипят мои конечности.
Я - повелитель бесконечности...
Мой блог
Спасибо сказали:
Аватара пользователя
devilr
Сообщения: 3665
ОС: Mandriva => Gentoo (~amd64)
Контактная информация:

Re: Как найти ошибку, из-за которой вылетает программа?

Сообщение devilr »

А просто расставить 100500 точек остановки и попытаться ограничить радиус поиска проблемы не поможет? Программа ведь вряд ли вылетает просто так. Должны быть причины.
Мудрость приходит с возрастом.
Иногда возраст приходит один.
Эхо разума
Спасибо сказали:
Аватара пользователя
olecya
Сообщения: 900
ОС: debian, fedora (i3-wm)

Re: Как найти ошибку, из-за которой вылетает программа?

Сообщение olecya »

А при падении дамп памяти сбрасывается на диск?
coredumpctl list
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20752
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Как найти ошибку, из-за которой вылетает программа?

Сообщение Bizdelnick »

olecya писала:
13.01.2021 16:41
дамп памяти
А зачем, если падение и под отладчиком воспроизвести не проблема?
Добавлено (17:24):
MiK13 писал:
30.12.2020 13:34

Код: Выделить всё

  const T* const &     operator[](int index)const{return M[index];};                 /// !!! (74)
  //    T*&           operator[](int index)     {return (T*)M[index];};
  //    const T*&     operator[](int index)const{return (T*)M[index];};
Похоже, что-то в этом месте всё же не так. Но моих познаний C++ не хватает, чтобы понять, что означает это нагромождение const и & (ну кроме того, что разработчики языка совершенно упоролись, если оно действительно что-то означает).
const, я так понимаю, Вы пробовали убирать. Что если убрать и &?
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Ответить