C программа, скомпилированная с cygwin в работах Windows, отказе сегментации в соответствии с Linux. cygwin GCC 'плохо'?

Вы можете использовать

.gsub(/[,()'".]+\z/,'')

Точка должна быть помещена в класс символов, класс отрицанных символов должен быть количественно определен с помощью + (1 или более вхождений), а якорь \z должен быть добавлен для подтверждения позиции в конце строки.

См. Демонстрацию Рубуляр .

13
задан Bill the Lizard 16 September 2012 в 15:53
поделиться

11 ответов

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

, Но да, проблема состоит в том, что существуют так многие зависимый платформы, а также в основном случайный, факторы, влияющие на программу C. Виртуальная память означает, что иногда , получая доступ к освобожденной памяти, будет казаться, будет работать, потому что Вы поражаете неиспользованную часть страницы, это было выделено в некоторой более ранней точке. Другие времена, это будет segfault, потому что Вы поражаете страницу, которая не была выделена Вашему процессу вообще. И это действительно невозможно предсказать. Это зависит от того, где Ваша память была выделена, было это в краю страницы, или в середине? Это до ОС и диспетчера памяти, и какие страницы были выделены до сих пор, и...... Вы получаете идею. Различные компиляторы, различные версии тех же компиляторов, другой OS'es, другое программное обеспечение, драйверы или аппаратные средства установили в системе, что-либо может измениться, получаете ли Вы segfault при доступе к освобожденной памяти.

Что касается заявления TA, что cygwin более "слаб", это - мусор по одной простой причине. Никакой компилятор не поймал ошибку! Если бы "собственный" компилятор GCC действительно был менее слабым, то он дал бы Вам ошибку во время компиляции. Segfaults не сгенерированы компилятором. Нет очень компилятора, может сделать, чтобы гарантировать, чтобы Вы получили segfault вместо программы, которая по-видимому работает.

8
ответ дан 1 December 2019 в 19:08
поделиться

Я не услышал ни о чем определенном относительно странности GCC под Cygwin, но в Вашем случае это, вероятно, была бы хорошая идея использовать - Стенной параметр командной строки к gcc, чтобы показать все предупреждения, видеть, находит ли это что-нибудь, что могло бы вызывать segfault в Вашем коде.

4
ответ дан 1 December 2019 в 19:08
поделиться

Я не означаю звучать грубым, но это - вероятно, Ваш код, это плохо, не компилятор.;) Проблемы как это на самом деле более распространены, чем Вы думали бы, потому что другая ОС и компиляторы будет иметь различные способы организовать данные Вашего приложения в стеке и "куче". Первый может быть особенно проблематичным, особенно если Вы заканчиваете тем, что перезаписали память на стеке или сослались на освобожденную память, которую система решила использовать для чего-то еще. Так в основном Вы могли бы иногда выходить сухим из воды, но другие времена Ваше приложение будут дросселировать и умирать. Так или иначе, если это segfaults, это - потому что Вы пытались сослаться на память, которую Вам не разрешили, таким образом, это - больше "счастливого совпадения", что это не отказало под другой системой/компилятором.

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

Редактирование : хорошо, я вижу то, что Вы имеете в виду теперь... Я думал, что Вы приезжали в эту проблему с "X, сосет, но Y работает просто великолепно!" отношение, но это, кажется, Ваш TA, кто получен это. ;)

Так или иначе, вот еще некоторые подсказки для отладки проблем как это:

  • Ищут адресную арифметику с указателями, ссылающуюся/разыменовывающую для возможного "doh!" ошибки. Любое место, где Вы добавляете/вычитаете один (иначе, ошибки на единицу при счете) является особенно подозреваемым.
  • Комментируют вызовы к malloc/free вокруг проблемной области и любые связанные области, где те указатели используются. Если код прекращает отказывать, то Вы идете в нужном направлении.
  • Принятие Вы, по крайней мере, определили общую область, где Ваш код отказывает, вставьте ранние операторы возврата там и найдите точку, где Ваш код не отказывает. Это может помочь найти область где-нибудь между той точкой и где Ваш код на самом деле отказывает. Помните, segfault как это не может обязательно произойти непосредственно в строке кода, где Ваша ошибка.
  • Использование средства отладки памяти, доступные в Вашей системе.
    • На Unix, выезд это руководство для отладки памяти на unix, и valgrind профилировщик (@Sol, благодарит напомнить мне об этом)
    • На Visual Studio / Windows, Ваш хороший 'ol приятель, CrtCheckMemory () входит довольно удобный. Кроме того, читайте на шаблоны отладки памяти CRT , поскольку они - одна из более хороших функций работы в VS. Часто времена, просто оставив открытым вкладки памяти в VS достаточно для диагностирования ошибок как это, после того как Вы запоминаете различные шаблоны.
    • В MAC OSX, можно установить точку останова на malloc_error_break (или от gdb или от XCode), который заставляет его отладчик повреждаться каждый раз, когда malloc обнаруживает повреждение памяти. Я не уверен, доступно ли это в других разновидностях Unix, но быстрый поиск Google, кажется, указывает, что это только для Mac. Кроме того, довольно "экспериментально" выглядящая версия valgrind, кажется, существует для OSX.
14
ответ дан 1 December 2019 в 19:08
поделиться

У Вас определенно есть ошибка где-нибудь в Вашем коде. Возможно, что диспетчер памяти Windows более слаб, чем диспетчер памяти Linux. В Windows Вы могли бы делать плохие вещи с памятью (как перезапись границ массива, утечек памяти, дважды-free'ing, и т.д.), но это позволяет Вам выйти сухим из воды. Известная история, связанная с этим, может быть найдена по телефону http://www.joelonsoftware.com/articles/APIWar.html (поиск "SimCity" на той (несколько длинной) статье).

3
ответ дан 1 December 2019 в 19:08
поделиться

Это - почти наверняка ошибка указателя или переполнение буфера, возможно, неинициализированная переменная.

неинициализированный указатель ни на что не будет обычно указывать, но иногда он будет указывать на что-то; чтение из него или запись в него будут обычно разрушать программу, но с другой стороны это не МОГЛО БЫ.

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

Эти ситуации зависят от точно, как стек, "куча" размечается и что делает время выполнения. Довольно возможно сделать плохую программу, которая работает над одним компилятором / комбинация во время выполнения и не другой, просто потому что на одном это перезаписывает что-то, что не имеет значения (так), или что неинициализированная переменная, "оказывается", содержит допустимое значение для контекста, в котором это используется.

2
ответ дан 1 December 2019 в 19:08
поделиться

Версия GCC является, вероятно, не проблемой. Это, более вероятно, будет различие в библиотеке времени выполнения и ошибка в Вашем коде, который не проявляется при выполнении против версии Windows времени выполнения. Вы могли бы хотеть отправить код, что segfaults и еще некоторая справочная информация, если Вы хотите более определенный ответ.

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

1
ответ дан 1 December 2019 в 19:08
поделиться

Версия Cygwin gcc может иметь другие флаги по умолчанию и настроила настройки (wchar_t быть 2 байтами, например), но я сомневаюсь, что это конкретно более "слабо" с кодом и несмотря на это - Ваш код не должен отказывать. Если это делает, то по всей вероятности существует ошибка в Вашем коде, для которого нужно, фиксируются. Например, Ваш код может зависеть от конкретного размера wchar_t или может выполнить код, это, как гарантируют, не будет работать вообще, как запись в строковые литералы.

при написании чистого кода затем, он работает также на Linux. Я в настоящее время запускаю Firefox и рабочий стол KDE, которые вместе состоят из миллионов строк C++, и я не вижу, что те приложения отказывают, :)

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

Тем временем, можно запустить программу в gdb, который является отладчиком для Linux. Можно также скомпилировать со всеми включенными проверками брызговика и со всеми включенными предупреждениями. брызговики проверяют Ваш код во времени выполнения для различных нарушений:

[js@HOST2 cpp]$ cat mudf.cpp
int main(void)
{
  int a[10];
  a[10] = 3;  // oops, off by one.
  return 0;
}
[js@HOST2 cpp]$ g++ -fmudflap -fstack-protector-all -lmudflap -Wall mudf.cpp
[js@HOST2 cpp]$ MUDFLAP_OPTIONS=-help ./a.out
  ... showing many options ...
[js@HOST2 cpp]$ ./a.out 
*******                 
mudflap violation 1 (check/write): time=1234225118.232529 ptr=0xbf98af84 size=44
pc=0xb7f6026d location=`mudf.cpp:4:12 (main)'                                   
      /usr/lib/libmudflap.so.0(__mf_check+0x3d) [0xb7f6026d]                    
      ./a.out(main+0xb9) [0x804892d]                                            
      /usr/lib/libmudflap.so.0(__wrap_main+0x4f) [0xb7f5fa5f]                   
Nearby object 1: checked region begins 0B into and ends 4B after                
mudflap object 0x9731f20: name=`mudf.cpp:3:11 (main) int a [10]'                
bounds=[0xbf98af84,0xbf98afab] size=40 area=stack check=0r/3w liveness=3        
alloc time=1234225118.232519 pc=0xb7f5f9fd                                      
number of nearby objects: 1                                                     
*** stack smashing detected ***: ./a.out terminated                             
======= Backtrace: =========
....

существует много проверок брызговика, которые можно сделать, и вышеупомянутые выполнения a.out использование опций по умолчанию. Другой оснащает, который помогает для подобных ошибок, valgrind, который может также помочь Вам найти утечки или прочь ошибками как вышеупомянутый. При установке переменной среды "MALLOC_CHECK _" к 1 распечатает сообщения для нарушений также. См. страницу справочника malloc для других возможных значений для той переменной.

Для проверки, где Ваши катастрофические отказы программы можно использовать gdb:

[js@HOST2 cpp]$ cat test.cpp
int main() {
    int *p = 0;
    *p = 0;
}
[js@HOST2 cpp]$ g++ -g3 -Wall test.cpp
[js@HOST2 cpp]$ gdb ./a.out
...
(gdb) r
Starting program: /home/js/cpp/a.out

Program received signal SIGSEGV, Segmentation fault.
0x080483df in main () at test.cpp:3
3           *p = 0;
(gdb) bt
#0  0x080483df in main () at test.cpp:3
(gdb)

Компиляция Ваш код с-g3 для включения многих отладочная информация, таким образом, gdb может помочь Вам найти точные строки, где Ваша программа отказывает. Все вышеупомянутые методы одинаково применимы для C и C++.

2
ответ дан 1 December 2019 в 19:08
поделиться

Вы делаете какие-либо определенные для платформы предположения, как размер типы данных , выравнивание структуры данных в struct с, или порядок байтов ?

1
ответ дан 1 December 2019 в 19:08
поделиться

Отказ сегментации означает, что Вы пытались получить доступ к памяти, Вы не могли, который обычно означает, что Вы попытались разыменовать нулевого указателя или Вас дважды удаленная память или получили дикий указатель. Существует две причины, почему Вы, возможно, казалось, были в порядке на cygwin а не на Linux: или это была проблема с диспетчерами памяти, или Вы стали более удачливыми на одном из них, чем другой. Это - почти наверняка ошибка с Вашим кодом.

Для фиксации этого посмотрите использование указателя. Рассмотрите заменяющие интеллектуальные указатели для необработанных указателей. Полагайте, что выполнение поиска удаляет и обнуление указателя сразу впоследствии (безопасно попытаться удалить нулевого указателя). Если можно получить трещину в Linux, попытайтесь получить отслеживание стека через gdb и посмотрите, существует ли что-нибудь, очевидно, неправильно в строке, это происходит. Исследуйте, как Вы используете все указатели, которые не инициализируются. Если у Вас есть доступ к средству отладки памяти, используйте его.

1
ответ дан 1 December 2019 в 19:08
поделиться

Некоторые подсказки:

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

  2. Включают предупреждения с -wall опция и исправляют любые проблемы, о которых сообщают. Снова, это может помочь сделать Вас лучшим программистом.

  3. Шаг через код с отладчиком. Помимо помощи Вам понять, где проблема, она поможет сделать Вас лучшим программистом.

  4. Продолжают использовать Подверсию или другую систему управления исходным кодом.

  5. Никогда не обвиняют компилятор (или ОС или аппаратные средства), пока Вы не уверены, что точно определили проблему. Даже затем с подозрением относитесь к своему собственному коду.

<час>

GCC на Linux является исходным кодом, идентичным GCC на Cygwin. Различия между платформами существуют, происходят из-за слоя эмуляции POSIX Cygwin и базового Windows API. Возможно, что дополнительные слои являются более прощающими, чем используемое оборудование, но это не рассчитываться.

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

1
ответ дан 1 December 2019 в 19:08
поделиться

Отказ сегментации является результатом доступа к памяти в несуществующем (или ранее освобожденный) адрес. То, что я нахожу очень интересными, - то, что код НЕ сделал segfault под cygwin. Это могло означать, что Ваша программа использовала дикий указатель на адресное пространство некоторых других процессов и на самом деле смогла считать его (удушье), или (более вероятно) код, который на самом деле вызвал segfault, не был достигнут, пока программа не была запущена в соответствии с Linux.

я рекомендую следующее:

  1. Вставка Ваш код, поскольку это - очень интересная проблема
  2. , Отправляет, копия этого cygwin разработчикам
  3. Получают дешевый Linux VPS, если Вы будете обязаны производить больше программ, которые работают в соответствии с Linux, это сделает Вашу жизнь намного легче.

Однажды Ваша работа в соответствии с Linux (т.е. окруженный в Ваш VPS), попытайтесь работать со следующими программами:

  • GDB
  • Valgrind
  • strace

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

Наконец, удостоверьтесь - Стена передается gcc, Вы хотите предупреждения, которые это передало бы.

1
ответ дан 1 December 2019 в 19:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: