Ошибка зафиксировала с четырьмя nops в, если (0), мир больше не имеет смысл

Ответ на первоначальный вопрос:

with s as (select 'the ID''s are [tag1] , [tag2] , [tag3]' str from dual)
select
regexp_replace(regexp_replace(regexp_replace(str, '\[.*?\]', '221'  , 1, 1)
                                                , '\[.*?\]', '342'  , 1, 1)
                                                , '\[.*?\]', '13412', 1, 1) as str
from s;

STR
------------------------------
the ID's are 221 , 342 , 13412

Ответ на вопрос:

with s as (select 'the ID''s are [tag1] , [tag2] , [tag3]' str from dual)
select
replace(replace(str, ']'), '[') str
from s;

STR
-------------------------------
the ID's are tag1 , tag2 , tag3
6
задан Casey Rodarmor 7 April 2009 в 15:37
поделиться

9 ответов

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

Корневая проблема состояла в том, что я не учел операторы возврата в рекурсивной функции. Я имел:

bool function() {
    /* lots of code */
    function()
}

Когда это должно было быть:

bool function() {
    /* lots of code */
    return function()
}

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

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

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

6
ответ дан 8 December 2019 в 02:11
поделиться

Это происходит в отладке и выпускает сборку режима (с символами и без)? Это ведет себя тот же способ использовать отладчик? Код moultithreaded? Вы компилируете с оптимизацией? Можно ли попробовать другую машину?

3
ответ дан 8 December 2019 в 02:11
поделиться

Это - дефектная адресная арифметика с указателями, любой непосредственно (через указатель) или косвенно (путем движения мимо конца массива). Проверьте все свои массивы. Не забывайте это, если Ваш массив

 int a[4];

затем [4] не существует.

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

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

Одним путем Вы могли бы добавлять, что что-то к обратному адресу путем движения мимо конца локального массива или параметра, например

  int a[4];
  a[4]++;
13
ответ дан 8 December 2019 в 02:11
поделиться

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

15
ответ дан 8 December 2019 в 02:11
поделиться

Мое предположение является повреждением стека - хотя gcc должен оптимизировать что-либо в, если бы (0), я думал бы.

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

Вы уверены, что выполняете то, что Вы думаете, что работаете? (немой вопрос, но это происходит.)

2
ответ дан 8 December 2019 в 02:11
поделиться

Можно ли подтвердить, что Вы действительно получаете различные исполняемые файлы, когда Вы добавляете если (0) {nops}? Я не вижу nops в своей системе.

$ gcc --version
powerpc-apple-darwin9-gcc-4.0.1 (GCC) 4.0.1 (Apple Inc. build 5490)

$ cat nop.c
void foo()
{
    if (0) {
        __asm__("nop");
        __asm__("nop");
        __asm__("nop");
        __asm__("nop");
    }
}

$ gcc nop.c -S -O0 -o -
    .
    .
_foo:
    stmw r30,-8(r1)
    stwu r1,-48(r1)
    mr r30,r1
    lwz r1,0(r1)
    lmw r30,-8(r1)
    blr

$ gcc nop.c -S -O3 -o -
    .
    .
_foo:
    blr
3
ответ дан 8 December 2019 в 02:11
поделиться

Похож на Вас, должен будет вставить некоторую тяжелую работу и тяжелую работу

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

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

Я приблизился бы к проблеме как так:

  1. Вспыхните свой любимый отладчик
  2. Начните ступать через свой код и наблюдайте стек вызовов и локальные переменные и ищите подозрительное действие
  3. Сделайте системный сбой
  4. Фокус в том, туда, где система перестала работать

Внимание на итерацию Ваших изменений кода:

  1. внесение изменений кода, которые "сделают системный сбой"
  2. выполнение/отладка и наблюдение
  3. Если это хорошо работает, Вы смотрите/пробуете неправильная вещь, и необходимо попробовать что-то еще. Если Вы заставляете его перестать работать затем, Вы сделали успехи к нахождению ошибки.
  4. Если Вы не знаете, где или как системные сбои Вы не сможете решить проблему.

Это будет хорошей возможностью создать Вашу отладку навыков. Для большего количества справки при создании Вашей отладки чтения навыков проверяют книгу "9 правил для отладки".

Вот плакат из книги:

9 Rules of debugging image
(источник: google.com)


Конкретные предложения:

  1. Если Вы думаете, что это - компилятор, то выполненный другая платформа/ОС/компилятор.
  2. После того как Вы исключили платформу/ОС/компилятор, затем попытайтесь реструктурировать код. Ищите "умные" части кода и посмотрите, делают ли они на самом деле то, что код означал делать..., возможно, умное решение не было на самом деле умно и делает что-то еще.
2
ответ дан 8 December 2019 в 02:11
поделиться

Я - автор "Отладки" так любезно ссылаемого выше Trevor Boyd Smith. У него есть он право - ключевые правила здесь являются № 2, Делают Это Сбоем (который Вы, кажется, делаете хорошо), и Взгляды Выхода № 3 и Взгляд. Догадки выше очень хороши (демонстрирующее мастерство правила № 1 - Понимают Систему - в этом случае способ, которым размер кода может изменить ошибку). Но на самом деле наблюдая это привести к сбою с отладчиком покажет Вам, что на самом деле происходит без догадок.

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

Вспыхните что одна функция в отдельный.c файл (или .cpp или безотносительно). Скомпилируйте просто, что один файл с nops и без них, в.s файлы и сравнивает их.

Попробуйте старую версию gcc. Возвратитесь 5 или 10 лет и посмотрите, становятся ли вещи более странными.

0
ответ дан 8 December 2019 в 02:11
поделиться
Другие вопросы по тегам:

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