Intereting Posts
Почему в VTT используется top_offset, реализованный gcc? iterator против reverse_iterator Каков наилучший способ прочитать двоичное изображение из blob SQLite и декодировать его с помощью OpenCV imdecode? Автоматически подсчитывать количество экземпляров classов в TMP? Как добиться следующего форматирования вывода C ++? Стоит ли вычислять векторный размер для циклов, каждая итерация? Почему необходим RTTI? Я хочу, чтобы вектор указателей производного classа назывался указателями базового classа Файл не распознан: Усеченная ошибка GCC файла Сбросить самый правый бит Реализация функции из C ++ в C # (MAKE_HRESULT – функция Windows) Почему предпочтительнее использовать конструктор std :: initializer_list при использовании скопированного списка инициализаторов? Qt скрыть столбец в QTableView Как проверить, является ли один вектор подмножеством другого? Документация файла заголовка C / C ++

Stackoverflow и указатели функций

Я совсем потерялся в этом, и я надеюсь, что кто-то здесь может помочь.

Мое приложение состоит из сотен функций, оценивающих числовой код (источник находится в диапазоне 5 МБ каждый), и я управляю функциями с помощью std::map для указателей на функции. Очевидно, что я получаю переполнение стека при попытке передать аргумент одной из функций, к которой обращается указатель на него:

Выход gdb:

 Program received signal SIGSEGV, Segmentation fault. 0x0000000001ec0df7 in xsectiond149 (sme=Cannot access memory at address 0x7fffff34b888 ) at xsection149.c:2 2 Poly3 xsectiond149(std::tr1::unordered_map & sme, EvaluationNode::Ptr ti[], ProcessVars & s) 

и xsection149.c: 2 имеет только открывающую скобу для определения функции.

/proc//map для процесса показывает диапазон адресов, ближайший к адресу, который вызывает ошибку только в этой строке:

 7ffffff74000-7ffffffff000 rw-p 7ffffff73000 00:00 0 [stack] 

поэтому адрес в вышеуказанной ошибке выходит за пределы.

Теперь мой вопрос: как решить эту проблему? Я не могу оборачивать голову тем, что я мог бы выделить в кучу …

Единственное, что происходит в моей основной рутине:

 // A map containing O(10^4) Poly3 (struct with 6 doubles) tr1::unordered_map smetemp; // populates smetemp computeSMEs(smetemp); // Map of function pointers of type, O(10^3) elements tr1::unordered_map diagfunctions = get_diagram_map(); 

Как это переполнение стека?

EDIT: я пытался запустить его в valgrind, это ошибка, которую я получаю, и Google не дал никакой значимой информации:

 valgrind: m_debuginfo/storage.c:417 (vgModuleLocal_addDiCfSI): Assertion 'cfsi.len < 5000000' failed. ==491== at 0x38029D5C: ??? (in /usr/lib64/valgrind/memcheck-amd64-linux) 

EDIT2 : Разборка функции до точки, где она терпит неудачу (0x0000000001ec0df7), дает мне:

 Dump of assembler code for function xsectiond149(std::tr1::unordered_map<int, Poly3, std::tr1::hash, std::equal_to, std::allocator<std::pair >, false>&, std::vector<boost::shared_ptr, std::allocator<boost::shared_ptr > >&, ProcessVars&): : push %rbp : mov %rsp,%rbp : push %r15 : push %r14 : push %r13 : push %r12 : push %rbx : sub $0xc96b58,%rsp : mov %rdi,%rbx : mov %rsi,-0xc8b078(%rbp) // this instr fails 

и первые несколько строк функции:

 Poly3 xsectiond149(std::tr1::unordered_map & sme, std::vector & ti, ProcessVars & s) { Poly3 sum(0,0,0,-2); Poly3 prefactor, expr; // CF*CA^2*NF*NA^(-2) double col0 = 0.5625000000000000000000000000; prefactor = col0*ti[0]->value()*s.Qtpow2*s.epow2*s.gpow6; expr = (128*(s.p1p2*sme[192]*s.mt - s.p1p2*sme[193]*s.mt + 1/2.*s.p1p2*sme[195]*s.mt - 1/2.*s.p1p2*sme[196]*s.mt - s.p1p2*sme[201]*s.mt + s.p1p2*sme[202]*s.mt + 1/2.*s.p1p2*sme[210]*s.mt - 1/2.*s.p1p2*sme[211]*s.mt - 1/4.*s.p1p2*sme[216]*s.mt + 1/4.*s.p1p2*sme[217]*s.mt - s.p1p2*sme[219]*s.mt + s.p1p2*sme[220]*s.mt - 1/8.*s.p1p2*sme[1209]*s.mt + 1/8.*s.p1p2*sme[1210]*s.mt + 1/2.*s.p1p2*sme[1215]*s.mt - 1/2.*s.p1p2*sme[1216]*s.mt + // ..... } 

(Обратите внимание, что я изменил подпись функции во время эксперимента)

Может ли кто-нибудь свести концы с концами к тому, что здесь происходит? Какая дополнительная информация вам нужна? Извините, но у меня почти нет опыта работы с asm.

EDIT3 : увеличение размера стека с помощью ulimit -s сделало трюк. Спасибо за вашу помощь!

Похоже, что функция xsectiond149 нуждается в кадре стека около 13 МБ (обратите внимание на инструкцию sub $0xc96b58,%rsp и сбой, как только он попытается записать что-то там, там две инструкции позже). Вы должны убедиться, что stream имеет достаточно большой стек (по умолчанию он не будет) перед вызовом функции.

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

Получите Valgrind и запустите свою программу под Valgrind (используя memcheck, инструмент по умолчанию) после его создания. Таким образом, вам будет легче найти источник неисправности.

Вы также можете запустить Valgrind в режиме, когда он разбивается на отладчик (обычно GDB), и затем вы можете использовать все classные команды GDB для проверки значений в кадрах стека вызывающих абонентов и так далее.

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

Что касается вашего редактирования, вот мой ответ (цитируя исходный код Valgrind, r11604 of storage.c):

 445 /* sanity */ 446 vg_assert(cfsi.len > 0); 447 /* If this fails, the implication is you have a single procedure 448 with more than 5 million bytes of code. Which is pretty 449 unlikely. Either that, or the debuginfo reader is somehow 450 broken. 5 million is of course arbitrary; but it's big enough 451 to be bigger than the size of any plausible piece of code that 452 would fall within a single procedure. */ 453 vg_assert(cfsi.len < 5000000);