Когда программа работает правильно во время отладки, но в противном случае нет? [Дубликат]

Короткий ответ на ваш вопрос - «нет».

В строгом смысле, на уровне базы данных подготовленные операторы позволяют привязывать параметры только к битам «values» инструкции SQL.

. Один из способов думать об этом - «вещи, которые можно заменить во время выполнения инструкции без изменения ее значения». Имя (и) таблицы не является одним из этих значений времени выполнения, поскольку оно определяет правильность самого оператора SQL (то есть, какие имена столбцов являются допустимыми) и изменение его во время выполнения потенциально может изменить, является ли оператор SQL действительным.

На немного более высоком уровне даже в интерфейсах базы данных, которые эмулируют подстановку подготовленного оператора, а не фактически посылают подготовленные операторы в базу данных, такие как PDO, которые могли бы позволить вам использовать местозаполнитель в любом месте (поскольку placeholder заменяется перед отправкой в ​​базу данных в этих системах), значение заполнителя таблицы будет строкой и вложено как таковое в SQL, отправленное в базу данных, поэтому SELECT * FROM ? с mytable в качестве параметра на самом деле заканчивается (f4) в базу данных, которая является недопустимой SQL.

Лучше всего продолжать работу с

SELECT * FROM {$mytable}

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

13
задан Bhargav Rao 17 August 2019 в 07:05
поделиться

11 ответов

string myString = sourceString.Remove(sourceString.IndexOf(removeString),removeString.Length);

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

-121--876754-

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

-121--1888630-

Имеется heisenbug .

Отладчик может инициализировать значения

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

Выпуск может быть построен с оптимизацией

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

Могут быть другие причины для heisenbugs.

23
ответ дан 1 December 2019 в 07:27
поделиться

Очевидно, stackoverflow не позволяет мне публиковать ответ, содержащий только одно слово :)

VALGRIND

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

У вас есть диалоги, поэтому в вашем приложении могут быть потоки. Если есть потоки, есть вероятность состояния гонки.

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

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

Вот распространенная ошибка, которая может привести к Heisenbug (любите это имя!):

    // Sanity check - this should never fail
    ASSERT( ReleaseResources() == SUCCESS);

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

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

    ASSERT( foo() == true );  // Confirm that call to foo() was successful
    VERIFY( bar() == true );  // Confirm that call to bar() was successful

В отладочной сборке два вышеуказанных макроса ведут себя идентично. Однако в сборке выпуска они по существу эквивалентны:

    ;       // Confirm that call to foo() was successful
    bar();  // Confirm that call to bar() was successful



Между прочим, если ваша среда определяет макрос ASSERT () , но не VERIFY ( ) макрос, вы можете легко определить свой собственный:

    #ifdef _DEBUG
       // DEBUG build: Define VERIFY simply as ASSERT
    #  define VERIFY(expr)  ASSERT(expr)
    #else
       // RELEASE build: Define VERIFY as the expression, without any checking
    #  define VERIFY(expr)  ((void)(expr))
    #endif

Надеюсь, что это поможет.

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

Какой язык программирования вы используете. Некоторые языки, такие как C ++, ведут себя немного по-разному в выпускаемых и отладочных сборках. В случае C ++ это означает, что когда вы объявляете переменную, такую ​​как int i; , в отладочных сборках она будет инициализирована значением 0, а в сборках выпуска она может принимать любое значение (независимо от того, что было сохранено в его ячейке памяти раньше).

0
ответ дан 1 December 2019 в 07:27
поделиться

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

Примером того, где это может произойти, является физическое моделирование в реальном времени с переменным шагом по времени, основанным на истекшем системном времени. Вот почему есть такие статьи: http://gafferongames.com/game-physics/fix-your-timestep/

0
ответ дан 1 December 2019 в 07:27
поделиться

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

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

В дополнение к тому, что сказал ДжеффХ, вы должны учитывать, имеет ли развертывающий компьютер (или сервер) ту же среду / библиотеки / все, что связано с программой.

Иногда очень трудно правильно отладить, если вы отлаживаете с другими условиями.

Джованни

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

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

Для MSVC это можно отключить с помощью env-var _NO_DEBUG_HEAP = 1 . (Куча отладки работает медленно, поэтому это помогает, если ваши отладочные запуски тоже ужасно медленные ..).

Другой способ получить то же самое - запустить процесс вне отладчика, чтобы получить нормальный запуск, затем дождаться первой строки в main и присоединить отладчик к процессу. Это должно работать для «любой» системы. при условии, что вы не упадете перед main. (Тогда вы можете дождаться ctor на статически созданном предварительно созданном объекте ...)

Но у меня нет опыта работы с gcc / gdb в этом вопросе, но там может быть что-то похожее ... )

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

Один реальный пример гейзенбага из Raymand Zhang .

/*-------------------------------------------------------------- 
GdPage.cpp : a real example to illustrate Heisenberg Effect
   related with guard page by Raymond Zhang, Oct. 2008
--------------------------------------------------------------*/
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
  LPVOID lpvAddr;               // address of the test memory
  lpvAddr = VirtualAlloc(NULL, 0x4096,
                         MEM_RESERVE | MEM_COMMIT,
                         PAGE_READONLY | PAGE_GUARD);
  if(lpvAddr == NULL) 
  {
    printf("VirtualAlloc failed with %ld\n", GetLastError());
    return -1;
  }

  return *(long *)lpvAddr;  
}

Программа аномально завершила бы компиляцию с Debug или Release, потому что при установке флага PAGE_GUARD, страницы в регионе становятся защищенными:

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

Таким образом, при попытке получить доступ к *lpvAddr вы получите STATUS_GUARD_PAGE . Но если Вы используете отладчик, загрузите программу и посмотрите *lpvAddv или выполните последнее утверждение , вернув *(длинную *)lpvAddr сборку по сборке, то отладчик увидит страницу охраны, чтобы определить значение *lpvAddr.Таким образом, отладчик очистит нас от охранной сигнализации перед доступом к *lpvAddr.

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

Одна из основных причин заключается в том, что код отладки может определять макрос _DEBUG, который можно использовать в коде для добавления дополнительных материалов в отладочные сборки.

Для многопоточного кода оптимизация может повлиять на порядок, что может повлиять на состояние гонки.

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

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

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

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