SIGSEGV с TDBLookupComboBox на модальной форме

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Re: SIGSEGV с TDBLookupComboBox на модальной форме

Сообщение vitaly_l » 07.03.2017 16:08:02

tema писал(а):Как только я убрал второй рефреш всё встало на свои места.

рефреш??? <== Но ведь это же бред! Я могу сделать 100 рефрешей подряд, и 100% буду уверен что, это никак не повлияет на работу программы. Согласны? Приведите сюда этот кусок кода, чтобы все посмотрели, зачем там сделали эти два рефреша? Только всю функцию, пожалуйста.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: SIGSEGV с TDBLookupComboBox на модальной форме

Сообщение pupsik » 07.03.2017 18:03:07

Я же указал на конкретную ошибку и объяснил конкретную причину
нет. По мне вы "попали" на причину и подтащили под себя. Почему у вас всё происходит именно так как вы описывали - вы не выяснили. Поэтому волшебство: боксы, модальность и т.д.. Ещё и "второй рефреш" нарисовался. Надеюсь он поэтапно возрастать не будет.

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

Это не нужно, чтобы не мусорить...
это было относительно нормальное предложение. Это нечто похоже на вашу проблему: виноваты боксы и модальность. Хотя: не столь серьезна и касаема только внутренней законченности приложения.
pupsik
энтузиаст
 
Сообщения: 1154
Зарегистрирован: 20.08.2014 16:20:13

Re: SIGSEGV с TDBLookupComboBox на модальной форме

Сообщение tema » 08.03.2017 00:42:39

vitaly_l писал(а):
tema писал(а):Как только я убрал второй рефреш всё встало на свои места.

рефреш??? <== Но ведь это же бред! Я могу сделать 100 рефрешей подряд, и 100% буду уверен что, это никак не повлияет на работу программы. Согласны? Приведите сюда этот кусок кода, чтобы все посмотрели, зачем там сделали эти два рефреша? Только всю функцию, пожалуйста.

Ок. Поймали. Термин указал неверный. Не рефреш, а рекреат. Функция вся вот:
Код: Выделить всё
{------------------------------------------------------------------------------
  TCustomForm ShowModal
------------------------------------------------------------------------------}
function TCustomForm.ShowModal: Integer;

  function HasVisibleForms: Boolean;
  var
    i: integer;
    AForm: TCustomForm;
  begin
    Result := False;
    for i := 0 to Screen.CustomFormZOrderCount - 1 do
    begin
      AForm := Screen.CustomFormsZOrdered[i];
      if (AForm <> Self) and not (AForm.FormStyle = fsMDIChild) and
        (AForm.Parent = nil) and AForm.Visible and AForm.HandleAllocated then
      begin
        Result := True;
        break;
      end;
    end;
  end;

  procedure RaiseShowModalImpossible;
  var
    s: String;
  begin
    DebugLn('TCustomForm.ShowModal Visible=',dbgs(Visible),' Enabled=',dbgs(Enabled),
      ' fsModal=',dbgs(fsModal in FFormState),' MDIChild=',dbgs(FormStyle = fsMDIChild));
    s:='TCustomForm.ShowModal for '+DbgSName(Self)+' impossible, because';
    if Visible then
      s:=s+' already visible (hint for designer forms: set Visible property to false)';
    if not Enabled then
      s:=s+' not enabled';
    if fsModal in FFormState then
      s:=s+' already modal';
    if FormStyle = fsMDIChild then
      s:=s+' FormStyle=fsMDIChild';
    raise EInvalidOperation.Create(s);
  end;

  procedure RestoreFocusedForm;
  begin
    // needs to be called only in ShowModal
    Perform(CM_DEACTIVATE, 0, 0);
    if Screen.FSaveFocusedList.Count > 0 then
    begin
      Screen.FFocusedForm := TCustomForm(Screen.FSaveFocusedList.First);
      Screen.FSaveFocusedList.Remove(Screen.FFocusedForm);
    end
    else
      Screen.FFocusedForm := nil;
  end;

var
  DisabledList: TList;
  SavedFocusState: TFocusState;
  ActiveWindow: HWnd;
  SavedCursor: TCursor;
begin
  if Self = nil then
    raise EInvalidOperation.Create('TCustomForm.ShowModal Self = nil');
  if Application.Terminated then
    ModalResult := 0;
  // cancel drags
  DragManager.DragStop(false);
  // close popupmenus
  if ActivePopupMenu <> nil then
    ActivePopupMenu.Close;
  if Visible or (not Enabled) or (fsModal in FFormState) or (FormStyle = fsMDIChild) then
    RaiseShowModalImpossible;
  // Kill capture when opening another dialog
  if GetCapture <> 0 then
    SendMessage(GetCapture, LM_CANCELMODE, 0, 0);
  ReleaseCapture;

  Application.ModalStarted;
  try
    Include(FFormState, fsModal);
    if (PopupMode = pmNone) and HandleAllocated then
      RecreateWnd(Self); // need to refresh handle for pmNone because ParentWindow changes if (fsModal in FFormState) - see GetRealPopupParent
    ActiveWindow := GetActiveWindow;
    SavedFocusState := SaveFocusState;
    SavedCursor := Screen.Cursor;
    Screen.FSaveFocusedList.Insert(0, Screen.FFocusedForm);
    Screen.FFocusedForm := Self;
    Screen.MoveFormToFocusFront(Self);
    Screen.Cursor := crDefault;
    ModalResult := 0;

    try
      if WidgetSet.GetLCLCapability(lcModalWindow) = LCL_CAPABILITY_NO then
        DisabledList := Screen.DisableForms(Self)
      else
        DisabledList := nil;
      Show;
      try
        // activate must happen after show
        Perform(CM_ACTIVATE, 0, 0);
        TWSCustomFormClass(WidgetSetClass).ShowModal(Self);
        repeat
          { Delphi calls Application.HandleMessage
            But HandleMessage processes all pending events and then calls idle,
            which will wait for new messages. Under Win32 there is always a next
            message, so it works there. The LCL is OS independent, and so it uses
            a better way: }
          try
            WidgetSet.AppProcessMessages; // process all events
          except
            if Application.CaptureExceptions then
              Application.HandleException(Self)
            else
              raise;
          end;
          if Application.Terminated then
            ModalResult := mrCancel;
          if ModalResult <> 0 then
          begin
            CloseModal;
            if ModalResult<>0 then break;
          end;

          Application.Idle(true);
        until False;

        Result := ModalResult;
        if HandleAllocated and (GetActiveWindow <> Handle) then
          ActiveWindow := 0;
      finally
        { guarantee execution of widgetset CloseModal }
        TWSCustomFormClass(WidgetSetClass).CloseModal(Self);
        // set our modalresult to mrCancel before hiding.
        if ModalResult = 0 then
          ModalResult := mrCancel;
        // We should always re-enabled the forms before issuing Hide()
        // Because otherwise we will for a short amount of time have
        // all forms disabled, and some systems, like WinCE, will interprete this
        // as a problem in the application and hide it.
        // See bug 22718
        Screen.EnableForms(DisabledList);
        Hide;
        RestoreFocusedForm;
      end;
    finally
      RestoreFocusState(SavedFocusState);
      Screen.Cursor := SavedCursor;
      if LCLIntf.IsWindow(ActiveWindow) then
        SetActiveWindow(ActiveWindow);
      Exclude(FFormState, fsModal);
      if ((PopupMode = pmNone) and HandleAllocated) and not (csDestroying in ComponentState) then
        RecreateWnd(Self); // need to refresh handle for pmNone because ParentWindow changes if (fsModal in FFormState) - see GetRealPopupParent
    end;
  finally
    Application.ModalFinished;
  end;
end;
tema
постоялец
 
Сообщения: 375
Зарегистрирован: 24.03.2011 20:19:27

Re: SIGSEGV с TDBLookupComboBox на модальной форме

Сообщение vitaly_l » 08.03.2017 09:55:01

tema писал(а):Ок. Поймали. Термин указал неверный. Не рефреш, а рекреат. Функция вся вот:

Код: Выделить всё
if ((PopupMode = pmNone) and HandleAllocated) and not (csDestroying in ComponentState) then
        RecreateWnd(Self); // need to refresh handle for pmNone because ParentWindow changes if (fsModal in FFormState) - see

Команда RecreateWnd вызывается только при определённых условиях, которые судя по коду, при втором вызове - УЖЕ являются сбоем. И второй вызов RecreateWnd, что-то вроде костыля, на случай "если вдруг всё ещё не ..., то в любом случае сделать RecreateWnd" т.к. ParentWindow changes. Из этого следует что, ошибка и сбой находятся раньше, т.к. при вызове приведённой функции, вызывается команда "на случай если ВДРУГ всё ещё (PopupMode = pmNone), то обязательно RecreateWnd". Соответственно, PopupMode - почему-то всё еще pmNone... Почему?

Я смотрел Вашу форму Form2 и у меня там почему-то на форме лежало три одинаковых SQL-connection, которые завязаны на одну дату. На мой взгляд когда они все три единовременно и параллельно пытаются подключиться и потом записать информацию в дату - происходит обрушение. Я думаю у Вас неправильная организация интерфейса с взаимосвязями между компонентами и как следствие обрушение. И это приводит к тому что, PopupMode - почему-то всё еще pmNone... Хотя давно уже всё "ShowModal"

Добавлено спустя 5 минут 55 секунд:
С другой стороны, костыль с повторным вызовом RecreateWnd - говорит, о том что, всё же там что-то иногда было, ещё при создании модуля и это что-то попытались исправить/защитить таким костылём. Соответственно возможно "баг" есть, но он не в этой функции, т.к. здесь только костыль.

И естественно, когда Вы делаете нетипичную организацию интерфейса - происходит двойное обрушение и PopupMode - всё еще pmNone. Вы должны ясно понимать, что ShowModal - используют все... Если бы там был баг, то... об этом орали бы все программисты... Но говорите об этом только Вы.
Делайте выводы и ищите баг в своём коде и организации интерфейса.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: SIGSEGV с TDBLookupComboBox на модальной форме

Сообщение tema » 09.03.2017 04:25:30

Изображение
tema
постоялец
 
Сообщения: 375
Зарегистрирован: 24.03.2011 20:19:27

Re: SIGSEGV с TDBLookupComboBox на модальной форме

Сообщение zub » 09.03.2017 06:09:39

tema
Зря кривляешся, 99.[9]% баг у тебя, а не в лазаре
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

Re: SIGSEGV с TDBLookupComboBox на модальной форме

Сообщение vitaly_l » 09.03.2017 10:28:27

zub писал(а):Зря кривляешся, 99.[9]% баг у тебя, а не в лазаре

У него такой же баг, как у меня тогда, когда Вы с бородатым Пупсиком заставили меня найти причину сбоя. Помнится я тоже орал, что виноват TModalResult, а в итоге оказалось что, сбой совершенно в другом месте. А tema - не понимает, что для получения такого же бага, который он описал - достаточно забыть освободить TStrings или ещё чего нить.

.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: SIGSEGV с TDBLookupComboBox на модальной форме

Сообщение tema » 09.03.2017 10:44:30

zub писал(а):tema
Зря кривляешся, 99.[9]% баг у тебя, а не в лазаре

Я сделал и прикрепил на багтреккере минимальную программу. Если в большом проекте ещё можно было говорить, что я не заметил багу в своей программе, то тут просто глупо. Тут просто негде ошибаться. Программа состоит из двух форм и трёх запросов. Всё сделано начисто на новой версии. Оно же на старой версии работает. Файл, который глючит найден. При замене файла в новой версии, опять же, работает. При исправлении указанных строк так же работает. Так что утверждать, что баг у меня просто я даже не знаю как это прокомментировать. Это напоминает политические прения беспощадные и бессмысленные. Если бы взяли ту прогу минимальную и сказали "ну вот же ошибка, вот тут!", то был бы смысл, а просто говорить " у тебя ошибка".. С таким же успехом можно просто отвечать "нет ошибки".
tema
постоялец
 
Сообщения: 375
Зарегистрирован: 24.03.2011 20:19:27

Re: SIGSEGV с TDBLookupComboBox на модальной форме

Сообщение vitaly_l » 09.03.2017 10:51:44

tema писал(а):Если бы взяли ту прогу минимальную и сказали "ну вот же ошибка, вот тут!", то был бы смысл, а просто говорить " у тебя ошибка".. С таким же успехом можно просто отвечать "нет ошибки".

У меня Ваш пример вообще не запускается.

Добавлено спустя 44 минут 44 секунд:
tema писал(а):Программа состоит из двух форм и трёх запросов.

И ещё она состоит из неправильной организации интерфейса второй формы, которая и приводит к обрушению при открытии второго окна, т.к. там что-то не туда привязано. А скорее всего, совсем не, то и не туда привязано, т.к. я например совершенно иначе коммутировал компоненты даты ( примеров полно в вики Лазаруса ). В Лазарусе лучше коммутировать, так, как оно описано в вики. Но постольку поскольку я не могу запустить Ваш пример, то и проверить я не могу.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: SIGSEGV с TDBLookupComboBox на модальной форме

Сообщение pupsik » 09.03.2017 11:18:21

Ну надыбал человек баг. Ну считает он что версия 1.7 хуже 1.6 (больше странных глюков)...
Ну и пущай. Часто с одной вышки трудно увидеть: где. А другие вышки - не показатель.

п.с.
tema есть причина и следствие. Вы, по моему мнению, ковыряете следствие. Ну и пускай. Лишь бы работало.
pupsik
энтузиаст
 
Сообщения: 1154
Зарегистрирован: 20.08.2014 16:20:13

Re: SIGSEGV с TDBLookupComboBox на модальной форме

Сообщение java73 » 14.03.2017 15:09:16

Наконец-то! Спасибо огромное. То, что выше все накритиковали может оно и правильно, вот только у меня в 1.6.4 резко началась похожая проблема, отредактировал customforms как предлагается в патче и ошибка исчезла. Тоже я виноват?
У меня ошибка возникает в связи со следующим: есть основная форма, на которой периодически собирается статистическая информация с БД, то бишь перебираются таблицы по всем строкам. Поскольку Lookup компоненты привязаны к таблице, у них видимо тоже изменение курсора в таблице БД влечет какие-то действия, даже если форма с указанным компонентом не открывалась до этого. Факт есть факт - ошибка перестала возникать.
Ошибок в своем коде у меня нет, так как всё работало два года и снова наконец-то работает))
java73
постоялец
 
Сообщения: 257
Зарегистрирован: 21.11.2013 09:08:10

Re: SIGSEGV с TDBLookupComboBox на модальной форме

Сообщение pupsik » 14.03.2017 15:41:22

Ох.. писец/песцовый.... Да откуда же вы такие безошибочные берётесь.
У каждого что то крутое и без ошибок. А все остальные только баги руками гребут.

java73 вполне логичные вопросы:
1. Вы то же считаете что версия 1.6 лучше транка?
2.
Тоже я виноват?
у вас есть понимание причины и следствия?

п.с.
кстати... мучила утечка в avl. В транке поправили. Может и мне откат на ниже версию сделать, пущай дальше течОт?

резко началась похожая проблема
хм... как бы "резко прижало, а до этого не жало" :mrgreen:
pupsik
энтузиаст
 
Сообщения: 1154
Зарегистрирован: 20.08.2014 16:20:13

Re: SIGSEGV с TDBLookupComboBox на модальной форме

Сообщение tema » 14.03.2017 15:55:01

java73 писал(а):Наконец-то! Спасибо огромное. То, что выше все накритиковали может оно и правильно, вот только у меня в 1.6.4 резко началась похожая проблема, отредактировал customforms как предлагается в патче и ошибка исчезла. Тоже я виноват?
У меня ошибка возникает в связи со следующим: есть основная форма, на которой периодически собирается статистическая информация с БД, то бишь перебираются таблицы по всем строкам. Поскольку Lookup компоненты привязаны к таблице, у них видимо тоже изменение курсора в таблице БД влечет какие-то действия, даже если форма с указанным компонентом не открывалась до этого. Факт есть факт - ошибка перестала возникать.
Ошибок в своем коде у меня нет, так как всё работало два года и снова наконец-то работает))

Спасибо за оценку :)
Хоть кто-то не покритиковал :)
tema
постоялец
 
Сообщения: 375
Зарегистрирован: 24.03.2011 20:19:27

Re: SIGSEGV с TDBLookupComboBox на модальной форме

Сообщение vitaly_l » 14.03.2017 15:57:33

tema писал(а):Спасибо за оценку
Хоть кто-то не покритиковал

Хитренький... нашёл соратника, по объявлению: "Мой код безупречен"

java73 писал(а):отредактировал customforms как предлагается в патче и ошибка исчезла. Тоже я виноват?

В патче запускается HandleNeeded и создаёт, то, что по идее уже должно быть присвоено ещё при Create; Или я неправ?
Так вот вопрос: Почему при Create; не было сделано HandleNeeded ???

Может быть там баг в Create, а не здесь в ShowModal? :twisted:

Может вы оба забыли Create; сделать и обращаетесь к просто объявленной форме?
:roll: Попробуйте сделать HandleNeeded перед вызовом ShowModal... спецы... :wink:

.
Последний раз редактировалось vitaly_l 14.03.2017 15:59:35, всего редактировалось 1 раз.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: SIGSEGV с TDBLookupComboBox на модальной форме

Сообщение java73 » 14.03.2017 15:59:35

java73 вполне логичные вопросы

Вот как раз логики-то и не увидел. Два года работала программа. Без сбоев. Решил улучшить, добавить кое-что. Перед этим смотрю - новая версия вышла, дай, думаю, обновлюсь. Обновился. Ошибки появились. В том числе перестал работать компонент GeckoBrowser на отображение. С геко быстро разобрался, а вот SIGSEGV этот вообще не уловимый был. При закрытии одной формы он вылетал на файл dblookup.inc (88 строка, если интересно), при закрытии другой - в ассемблер вылетал. Для меня причины вообще не очевидные были. Сделал как автор темы предложил - все без ошибок работает.
Это еще я говорю, в своем коде ничего еще и не правил. Просто пересобрал под новой версией.

Добавлено спустя 3 минуты 20 секунд:
vitaly_l писал(а):Может вы оба забыли Create; сделать и обращаетесь к просто объявленной форме?

У меня ошибка вылетала даже в том случае, если форму, на которой lookup компоненты лежат, даже и не открывал никто.
Вот совершенно абсурдная ситуация:
1. запускается программа
2. открывается форма, на которой всего лишь одна таблица dbgrid и ничего вообще больше
3. закрывается форма - вылетает ошибка, отладчик падает на строки кода, связанный с lookup компонентами, которые есть, но на других формах, которые даже не открывали. И кто виноват?
java73
постоялец
 
Сообщения: 257
Зарегистрирован: 21.11.2013 09:08:10

Пред.След.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot], Yandex [Bot] и гости: 41

Рейтинг@Mail.ru