Intereting Posts
Почему вы должны вызвать delete для локальных переменных функции, которые хранятся в куче? Как перекрестно скомпилировать из windows g ++ cygwin, чтобы получить исполняемый файл linux Лучший подход для полнотекстового поиска со списком целых чисел unordered_map безопасность streamов c ++ 03: конструктор по умолчанию для встроенных типов в std :: map Доступ к пикселям вдоль кривой / пути с использованием opencv Изменение элементов массива с помощью встроенной сборки Оптимизация пустого базового classа теперь является обязательной оптимизацией (по крайней мере, для classов стандартного макета)? JNI_CreateJavaVM () завершается с кодом завершения 1 Как назначить значение classа другим вложенным classам в C ++ Добавление большего количества элементов, чем выделенное пространство Что не так с этой функцией обратной строки c ++ boost binary_oarchive работает по-разному для разных компиляторов Добавление std :: vector в себя, неопределенное поведение? Что означает ошибка с плавающей запятой -1. # J?

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);