Segmentation fault 11 mac os что это

Обновлено: 04.07.2024

В вычислении , а ошибки сегментации (часто сокращается до Segfault ) или нарушение прав доступа является неисправность или состояние отказа, поднятый аппаратными средствами с защитой памяти , уведомляя об операционной системе (ОС) программа пытается получить доступ к закрытой области памяти (а нарушение доступа к памяти). На стандартных компьютерах x86 это форма общей неисправности защиты . В ответ ядро ОС обычно выполняет некоторые корректирующие действия, обычно передавая ошибку процессу- нарушителю , посылая процессу сигнал . В некоторых случаях процессы могут устанавливать собственный обработчик сигналов, что позволяет им восстанавливаться самостоятельно, но в противном случае используется обработчик сигналов ОС по умолчанию, что обычно вызывает аварийное завершение процесса ( сбой программы ), а иногда и дамп ядра .

Ошибки сегментации - это распространенный класс ошибок в программах, написанных на таких языках, как C, которые обеспечивают низкоуровневый доступ к памяти и мало или совсем не проверяют безопасность. Они возникают в первую очередь из-за ошибок в использовании указателей для адресации виртуальной памяти , особенно из-за незаконного доступа. Другой тип ошибки доступа к памяти - это ошибка шины , которая также имеет разные причины, но сегодня встречается гораздо реже; это происходит в первую очередь из-за неправильной адресации физической памяти или из-за неправильного доступа к памяти - это ссылки памяти, которые оборудование не может адресовать, а не ссылки, которые процессу не разрешено адресовать.

Многие языки программирования могут использовать механизмы, предназначенные для предотвращения ошибок сегментации и повышения безопасности памяти. Например, язык программирования Rust использует модель, основанную на «владении», чтобы гарантировать безопасность памяти. Другие языки, такие как Lisp и Java , используют сборку мусора, которая позволяет избежать определенных классов ошибок памяти, которые могут привести к ошибкам сегментации.

СОДЕРЖАНИЕ

Обзор



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

Термин «сегментация» используется в вычислительной технике по-разному; в контексте «ошибки сегментации», термина, используемого с 1950-х годов, он относится к адресному пространству программы. С защитой памяти только собственное адресное пространство программы доступно для чтения, и из этого только стек и часть для чтения / записи сегмента данных программы доступны для записи, в то время как данные только для чтения и сегмент кода не доступны для записи. Таким образом, попытка чтения за пределами адресного пространства программы или запись в сегмент адресного пространства, доступный только для чтения, приводит к ошибке сегментации, отсюда и название.

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

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

На уровне операционной системы эта ошибка перехватывается, и сигнал передается процессу-нарушителю, активируя обработчик процесса для этого сигнала. В разных операционных системах используются разные имена сигналов, указывающие на то, что произошла ошибка сегментации. В Unix-подобных операционных системах сигнал, называемый SIGSEGV (сокращенно от нарушения сегментации ), отправляется процессу-нарушителю. В Microsoft Windows вызывающий нарушение процесс получает исключение STATUS_ACCESS_VIOLATION .

Причины

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

Ниже приведены некоторые типичные причины ошибки сегментации:

  • Попытка доступа к несуществующему адресу памяти (вне адресного пространства процесса)
  • Попытка доступа к памяти, на которую программа не имеет прав (например, к структурам ядра в контексте процесса)
  • Попытка записи в постоянную память (например, сегмент кода)

Это, в свою очередь, часто вызвано ошибками программирования, которые приводят к недопустимому доступу к памяти:

  • Разыменование нулевого указателя , который обычно указывает на адрес, не являющийся частью адресного пространства процесса.
  • Разыменование или присвоение неинициализированному указателю ( дикий указатель , указывающий на случайный адрес памяти)
  • Разыменование или присвоение освобожденному указателю ( висячий указатель , который указывает на память, которая была освобождена / освобождена / удалена)
  • Переполнение буфера
  • Переполнение стека
  • Попытка выполнить некорректную компиляцию программы. (Некоторые компиляторы выводят исполняемый файл, несмотря на наличие ошибок времени компиляции.)

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

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

Умение обращаться

Действие по умолчанию для ошибки сегментации или ошибки шины - ненормальное завершение процесса, который ее вызвал. Файл ядра может быть создан , чтобы помочь отладки, а также другие действия зависит от платформы также могут быть выполнены. Например, системы Linux , использующие патч grsecurity, могут регистрировать сигналы SIGSEGV для отслеживания возможных попыток вторжения с использованием переполнения буфера .

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

Примеры


Запись в постоянную память

Запись в постоянную память вызывает ошибку сегментации. На уровне ошибок кода это происходит, когда программа записывает в часть своего собственного сегмента кода или часть сегмента данных, доступную только для чтения, поскольку они загружаются ОС в постоянную память.

Вот пример кода ANSI C , который обычно вызывает ошибку сегментации на платформах с защитой памяти. Он пытается изменить строковый литерал , что является неопределенным поведением в соответствии со стандартом ANSI C. Большинство компиляторов не улавливают это во время компиляции и вместо этого компилируют это в исполняемый код, который выдает сбой:

При компиляции программы, содержащей этот код, строка «hello world» помещается в раздел rodata исполняемого файла программы : раздел сегмента данных только для чтения . После загрузки операционная система помещает его вместе с другими строками и константными данными в сегмент памяти, доступный только для чтения. При выполнении переменная s устанавливается так, чтобы указывать на местоположение строки, и делается попытка записать символ H через переменную в память, что вызывает ошибку сегментации. Компиляция такой программы с помощью компилятора, который не проверяет назначение мест только для чтения во время компиляции, и запуск ее в Unix-подобной операционной системе приводит к следующей ошибке времени выполнения :

Несмотря на то, что строковые литералы не должны изменяться (это имеет неопределенное поведение в стандарте C), в C они относятся к static char [] типу, поэтому в исходном коде нет неявного преобразования (который указывает char * на этот массив), тогда как в C ++ они из static const char [] типа, и , таким образом , существует неявное преобразование, поэтому составители, как правило , поймать эту конкретную ошибку.

Разыменование нулевого указателя

В языках C и C-подобных языках нулевые указатели используются для обозначения «указателя на отсутствие объекта» и в качестве индикатора ошибки, а разыменование нулевого указателя (чтение или запись через нулевой указатель) является очень распространенной ошибкой программы. Стандарт C не говорит, что нулевой указатель совпадает с указателем на адрес памяти 0, хотя на практике это может иметь место. Большинство операционных систем отображают адрес нулевого указателя таким образом, что доступ к нему вызывает ошибку сегментации. Это поведение не гарантируется стандартом C. Разыменование нулевого указателя является неопределенным поведением в C, и соответствующая реализация может предполагать, что любой указатель, который разыменован, не является нулевым.

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

Разыменование нулевого указателя и последующее присвоение ему (запись значения несуществующей цели) также обычно вызывает ошибку сегментации:

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

Переполнение буфера

Следующий код обращается к массиву символов s за его верхней границей. В зависимости от компилятора и процессора это может привести к ошибке сегментации.

Переполнение стека

Другой пример - рекурсия без базового случая:

что вызывает переполнение стека, что приводит к ошибке сегментации. Бесконечная рекурсия не обязательно может привести к переполнению стека в зависимости от языка, оптимизаций, выполняемых компилятором, и точной структуры кода. В этом случае поведение недоступного кода (оператор return) не определено, поэтому компилятор может исключить его и использовать оптимизацию хвостового вызова, которая может привести к отсутствию использования стека. Другие оптимизации могут включать в себя перевод рекурсии в итерацию, что, учитывая структуру функции примера, приведет к тому, что программа будет работать вечно, при этом, вероятно, не переполняется ее стек.

Ошибка сегментации (англ. Segmentation fault или сокращённо segfault ) — ошибка программного обеспечения, возникающая при попытке обращения к недоступным для записи участкам памяти либо при попытке изменения памяти запрещённым способом. В системах на основе процессоров Motorola 68000 эти ошибки, как правило, известны как ошибки адреса или шины.

Сегментная адресация памяти является одним из подходов к управлению и защите памяти в операционной системе. Для большинства целей она была вытеснена страничной памятью, однако в документациях по традиции используют термин «Ошибка сегментации». Некоторые операционные системы до сих пор используют сегментацию на некоторых логических уровнях, а страничная память используется в качестве основной политики управления памятью.

Пример

Вот пример кода ANSI C, который приводит к ошибке сегментации на платформах с защитой памяти:

Когда программа, содержащая этот код, скомпилирована, строка «hello world» размещена в секции программы с бинарной пометкой «только для чтения». При запуске операционная система помещает её с другими строками и константами в сегмент памяти, предназначенный только для чтения. После запуска переменная s указывает на адрес строки, а попытка присвоить значение символьной константы H через переменную в памяти приводит к ошибке сегментации.

Компиляция и запуск таких программ на

В отличие от этого, gcc 4.1.1 на Linux возвращает ошибку ещё во время компиляции:

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

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

Ещё один способ вызвать ошибку сегментации заключается в том, чтобы вызвать функцию main рекурсивно, что приведёт к переполнению стека:

См. также

Ссылки

Микроядро • Монолитное ядро • Гибридное ядро • Пространство ядра (kernel space) • Модульное ядро • Наноядро • Драйвер • Пространство пользователя • Область пользователя • Экзоядро

Защита памяти • Сегментация памяти • Страничная память (Paging) • Блок управления памятью • Ошибка сегментации • Общая ошибка защиты

Wikimedia Foundation . 2010 .

Полезное

Смотреть что такое "Segmentation fault" в других словарях:

Segmentation fault — A segmentation fault (often shortened to segfault) is a particular error condition that can occur during the operation of computer software. A segmentation fault occurs when a program attempts to access a memory location that it is not allowed to … Wikipedia

Segmentation Fault — Erreur de segmentation Pour les articles homonymes, voir Segmentation. Une erreur de segmentation (en anglais segmentation fault, parfois appelé en abrégé segfault), est un plantage d une application qui a tenté d accéder à un emplacement mémoire … Wikipédia en Français

Segmentation fault — Erreur de segmentation Pour les articles homonymes, voir Segmentation. Une erreur de segmentation (en anglais segmentation fault, parfois appelé en abrégé segfault), est un plantage d une application qui a tenté d accéder à un emplacement mémoire … Wikipédia en Français

segmentation fault — noun A software error that occurs when a program attempts to access a memory location that it is not permitted to access. Syn: access violation, segfault … Wiktionary

Если делаю ввод с клавиатуры (gets), то программа работает без проблем. Но если считываю из файла в массив, то вылетает SegFault 11, хотя массив заполняется.

64.8k 6 6 золотых знаков 47 47 серебряных знаков 102 102 бронзовых знака


Уточните вопрос. В каком месте происходит ошибка. Какие данные в файле. Из Вашего вопроса следует, что Вы используете gets , но в коде я не нашел вызова этой функции. Вашу проблему не удаётся воспроизвести. Покажите данные. @Sergey Gornostaev , я скомпилировал данный код на винде и он нормально работает. Но на macOS выдаёт Segmentation fault 11

Подопытный код (взят из реального вопроса):

Компилируем его с отладочной информацией:

Пробуем запустить и закономерно получаем ошибку сегментирования после ввода произвольной строки. Открываем подопытного в отладчике:

Запускам программу командой отладчика run и вводим строку

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

Вводим команду backtrace для просмотра стека вызовов. В такой примитивной программе, как наш пример, можно обойтись и без этого, но в более серьёзных - это важный этап анализа проблемы:

В подавляющем большинстве случаев проблема не в системных или библиотечных вызовах, поэтому стоит обратить внимание на вызовы в своём коде. В нашем случае - это только третий кадр стека. На него и переключимся:

И сразу увидим строчку, в которой произошло падение. Проверяем куда указывает buf

Указатель buf содержит NULL . Автор программы не выделил память. Завершаем работу программы и отладчика вводом соответствующих команд

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

. при попытке скомпилировать приложение Swift. Я использую Xcode 6.1, пытаясь построить для iPhone 5 на iOS 8.1.

Код

текст ошибки!

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

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

Error message

для меня, это было вызвано изменением в синтаксис SDK разбора в Swift 2.0. Если используется синтаксический анализ и выполняется обновление до Swift 2.0, изменяется следующий синтаксис:

Swift 1.2:

Swift 2.0:

удаление первого " ("и последнего") " является причиной самой большой проблемы. Мне понадобилась целая вечность, чтобы найти это!

Я нажал эту ошибку. После некоторого разочарования я попробовал Xcode clean, и все снова начало работать. Просто оставляю это здесь на будущее.

Я нашел причину после отката назад каждого шага, который я сделал. отливка силы в int на Double переменная

для меня это было вызвано некоторыми из моих код. Подробный вывод компилятора в XCode фактически указал метод, в котором он сбой.

затем я прокомментировал весь код в методе, заставил его вернуть ноль, и он скомпилировался. Затем я повторно реализовал метод, используя другой и гораздо более простой код, и он сработал.

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

у меня была аналогичная проблема с Xcode 7.3 и iOS 9.3. Command failed due to signal: Segmentation fault: 11

Screenshot

основные шаги, такие как чистый (cmd+shift+k) код, удаление производных данных и выход из Xcode не работали.

в моем коде был какой-то преступник.

в вашем случае просмотрите свой код и исправьте виновника.

одним из случаев является то, что вы назвали тип данных переменной getter как ее имя. Например:

простое исправление при использовании git.

1) В терминала:

2) ошибка Seg исчезает.

3) выполнить приложение.

4) В терминала:

5) Xcode теперь говорит вам о реальной проблеме.

Я избавился от этой ошибки следующий.

У меня было много фреймворков, добавленных в" Link Binary With Libraries", и я также использовал заголовок моста.

Я снова добавил все фреймворки и снова добавил заголовок моста. Это решило мою проблему.

Я использую Xcode 8.3 / Swift 3

я использовал ответ @Ron B., Чтобы пройти через весь код и прокомментировать различные функции, пока я не получил успешную сборку. Оказывается, это было async trailing closures это вызвало мою ошибку:

мои трейлинг закрытия:

однажды я использовал синтаксис автозаполнения на Segmentation fault: 11 был ушел

enter image description here

У меня такая же проблема, поэтому я попытался переключиться на уровень оптимизации Быстрая Оптимизация С Одним Файлом [- O] вместо Быстрая Оптимизация Всего Модуля затем он работал, строился, архив для успеха Appstore.

некоторые фреймворки, которые мы использовали, нуждаются в рефакторинге для адаптации с Быстрая Оптимизация Всего Модуля

У меня был этот код 11 при попытке построить схему выпуска. Он указал на один класс viewcontroller (swift), который имел этот кусок кода внутри:

проблема заключалась в том, что когда я добавил к нему суперкласс, я забыл также реализовать init. Так что супер.init вызвал ошибку компилятора ошибка сегментации: 11 Поэтому, если у вас есть такая проблема, неплохо проверить и любые суперклассы.

у меня также была ошибка сегментации 11, при импорте фреймворка, сделанного мной (да, чувствовал себя очень глупо).

после разработки фреймворка в течение нескольких месяцев и интеграции его в основной проект с смешанными Obj-C и Swift, импорт в Obj-C не был проблемой, но как только я написал import MySwiftProject в Swift, весь ад вырвался на свободу.

короче говоря, проблема в том, что я создал некоторые пользовательские методы, которые обеспечивают типизации NSNotifications С помощью замыканий, для пример:

(собственно, код выше, я сделал с шаблоном, но это другая история)

главный виновник? Это:

по-видимому, Apple может использовать NSObjectProtocol в объявлении NSNotification методы, но когда я это делаю, он вводит Segfault 11 . Замена NSObjectProtocol до AnyObject решается аварии.

к сожалению, это может не решить вашу проблему, так как segfault 11-это просто общий сбой компилятора, но вы можете предпринять шаги решить ее. Мне потребовалось около 2 часов, но это то, что я сделал:

в моем случае причиной было объявление класса в другом классе в пределах расширения.

Это вызвало ошибку с моей стороны. У меня было несколько фреймворков в моем проекте, но раньше этого не было.

Я также некоторое время боролся с этим. Я обновил свой код до Swift 2 с помощью Xcode 7.2, и для меня проблема заключалась в следующем:

который мне пришлось изменить на:

Я получил эту ошибку, когда переопределял свойство в подклассе, и я не повторил объявление свойства точно.

override var foo: String // missing the implicit unwrap operator

для меня это потому, что у меня есть два пакета с тем же именем.

в моем случае я столкнулся с этой ошибкой, потому что я использовал один '=' вместо double '=' по ошибке в if-statement.

ссылаясь на это так:

дал ошибку. Но, переключившись на это, он ушел:

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

в моем случае я объявил следующее свойство в одном из моих подклассов ViewControllers:

Я думаю, что это противоречило уже существующим title в собственность ViewController . Я переименовал это свойство во что-то другое и изменил его использование, и ошибка исчезла.

в моем случае это было вызвано попыткой использовать функцию, которая возвращала NSNumber в качестве аргумента, где ожидался Double. Мой совет-будьте осторожны, смешивая объекты Objective C с типами данных Swift. И как многие другие предложили, комментируйте строки, пока вы не укажете, какая из них вызывает ошибку. (Даже если вы создаете другие ошибки при этом, вы можете просто игнорировать их и видеть, что делает ошибку ошибки сегментации уйти.)

для меня я блокировал основной поток.

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

у меня ошибка сегментации на моем Mac Mini с использованием ботов Xcode. Ошибка seg произошла только на этапе сборки тестирования, а не во время построения или локального запуска. Только в Xcode ботах на этапе сборки тестирования.

Я использую macOS Sierra и Xcode 8, с кодом, преобразованным в Swift 2.3.

Я, наконец, нашел строку, вызывающую ошибку seg, это было вызвано:

который был объявлен вне класса как константа. Изменение его для проверки userInterfaceIdiom во время выполнения Исправлена проблема.

надеется, что это поможет кому-то еще!

это журнал ошибок для моей ошибки seg:

когда ваша цель разработки не поддерживает какой-либо UIControl

В моем случае я использую StackView в проекте с целью разработки 8.0 . Эта ошибка может произойти, если цель разработки не поддерживает UIControl.

когда вы устанавливаете неправильный элемент

в нижней строке, если вы оставите цель по умолчанию "target" вместо self, то произойдет ошибка сегментации 11.

Читайте также: