LCC Как да спрете счупването на дебъгера при стартиране на приложението?

Не съм сигурен колко потребители има там, които използват LCC C компилатора и WEdit GUI за Windows, но той има „функция“, която може да бъде доста досадна. Когато стартирате приложение с дебъгера, той прекъсва приложението в началото на основната функция. Как мога да прекъсна това, така че дебъгерът незабавно да изпълни кода, докато не го спра или достигне точка на прекъсване, която съм създал?


person RLH    schedule 10.08.2011    source източник
comment
Добър въпрос! Използвал съм LCC-Win32 в миналото за преподаване на C и за начинаещи това е добра функция, но виждам как може да стане досадно. Опитах да настроя и премахна точка на прекъсване в отварящата скоба в main(), но така или иначе спира дотук. Разгледах параметрите на командния ред на Wedit (IDE за LCC-Win32), но няма флагове, които да контролират какво прави при стартиране.   -  person Jay Elston    schedule 10.08.2011
comment
Не съм запознат с LCC, но от потребителската документация - Можете да видите всички точки на прекъсване, които имате, и да ги редактирате/премахнете, като изберете от менюто Compiler-›Breakpoints (или Debug-›Edit breakpoints). Видяхте ли точка на прекъсване на main() тук?   -  person Sergei Nikulov    schedule 26.08.2011
comment
Няма точка на прекъсване. Раздразнението е, че независимо дали е зададена точка на прекъсване или не, дебъгерът/редакторът винаги прекъсва на първия ред на метода main().   -  person RLH    schedule 26.08.2011
comment
в Windbg и VS има програмна опция за управление на това. Може това да ти се случва   -  person Jim Deville    schedule 19.11.2011
comment
Това не е ли специфично за lcc-win32, за разлика от оригиналния lcc, на който се основава? Ако е така, може да искате да редактирате заглавието.   -  person Keith Thompson    schedule 20.11.2011
comment
Преди често използвах Lcc-Win32. Доколкото знам, не е възможно да се предотврати това поведение (поне от GUI), доколкото знам. Въпреки това разработчиците на Lcc-Win32 евентуално могат да ви помогнат, ако се свържете с тях.   -  person Waxhead    schedule 29.11.2011
comment
@waxhead-- Всъщност направих актуализация, като споменах, че всички потребители трябва любезно да поискат това като функция за актуализация. Той беше премахнат и премахнат (вижте редакциите на Kev‹› в моя пост.)   -  person RLH    schedule 30.11.2011
comment
Момчета, закърпих двоичния файл вместо вас.   -  person expert    schedule 16.12.2011


Отговори (1)


Уау, хората все още използват LCC... Последният път, когато го използвах, беше преди ~10 години.

Декомпилирах wedit.exe и мога да потвърдя, че няма официален начин за деактивиране на това поведение.

Поправих двоичния файл, ако това работи за вас. Качих го тук.

За тези, които се притесняват от вируси и други подобни, направих корекция wedit, взета от тук. Относно кутията казва, че е версия 4.0, компилирана на 16 септември 2009 г.

Ето коригирана функция за тези, които се интересуват:

int __cdecl sub_44CF0D(HANDLE hProcess)
{
  int result; // eax@1
  int v2; // ST0C_4@10
  int v3; // eax@20
  int v4; // eax@23
  int v5; // eax@25
  int v6; // [sp+10h] [bp-68h]@11
  int v7; // [sp+14h] [bp-64h]@1
  struct _DEBUG_EVENT DebugEvent; // [sp+18h] [bp-60h]@1

  v7 = 1;
  result = WaitForDebugEvent(&DebugEvent, dwMilliseconds);
  if ( result )
  {
    sub_44C67A(&DebugEvent);
    if ( DebugEvent.dwDebugEventCode == 1 )
    {
      if ( DebugEvent.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_ACCESS_VIOLATION
        && !(dword_482860 & 1)
        && !dword_484328
        && DebugEvent.u.Exception.dwFirstChance )
      {
        sub_44E1A5(0);
        sub_44CEB2(v2);
        return ContinueDebugEvent(DebugEvent.dwProcessId, DebugEvent.dwThreadId, 0x80010001u);
      }
      v6 = 0;
      v7 = sub_44D2C4((int)&DebugEvent, hProcess, (int)&v6);
      if ( v6 && DebugEvent.u.Exception.dwFirstChance )
        return ContinueDebugEvent(DebugEvent.dwProcessId, DebugEvent.dwThreadId, 0x80010001u);
      goto LABEL_41;
    }
    if ( DebugEvent.dwDebugEventCode == 3 )
    {
      if ( dword_483C94 )
      {
        dword_48428C = 1;
LABEL_41:
        if ( dword_483C6C )
          sub_44ECDC();
        if ( v7 )
        {
          result = ContinueDebugEvent(DebugEvent.dwProcessId, DebugEvent.dwThreadId, 0x10002u);
        }
        else
        {
          dword_49BF68 = 1;
          ResetEvent(dword_484AE4);
          dword_4843C8 = DebugEvent.dwThreadId;
          result = sub_4524CD();
        }
        return result;
      }
      Sleep(0x32u);
      dword_49BF64 = 1;
      dword_49BF68 = 1;
      qword_483C74 = __PAIR__(
                       (unsigned int)DebugEvent.u.Exception.ExceptionRecord.ExceptionAddress,
                       DebugEvent.u.Exception.ExceptionRecord.ExceptionInformation[2]);
      if ( dword_484288 )
        ::hProcess = (HANDLE)DebugEvent.u.Exception.ExceptionRecord.ExceptionFlags;
      else
        ::hProcess = hProcess;
      dword_483C84 = DebugEvent.dwProcessId;
      hThread = DebugEvent.u.Exception.ExceptionRecord.ExceptionRecord;
      dword_483C9C = (HANDLE)DebugEvent.u.Exception.ExceptionRecord.ExceptionCode;
      dwThreadId = DebugEvent.dwThreadId;
      dword_483C94 = 0;
      if ( sub_45A83A() )
      {
        v4 = sub_4026A6(28);
        dword_484330 = v4;
        *(_DWORD *)(v4 + 4) = hThread;
        *(_DWORD *)(v4 + 8) = dwThreadId;
        if ( dword_484288 )
        {
          sub_455B58();
        }
        else
        {
          Sleep(0x64u);
          v5 = sub_45AAFC();
          if ( !v5 )
            return PostMessageA(dword_4849EC, 0x111u, 0x64u, 0);
          if ( dword_484354 )
            goto LABEL_50;
          sub_455B58();
          if ( dword_483C70 && *(_DWORD *)(dword_483C70 + 52) )
            *(_DWORD *)(*(_DWORD *)(dword_483C70 + 52) + 36) = sub_451577(**(_DWORD **)(dword_483C70 + 52), 1u);
          v5 = *(_DWORD *)(dword_483C70 + 52);
          if ( v5 && *(_DWORD *)(v5 + 36) )
          {
LABEL_50:
            if ( !dword_483C6C )
              sub_44E92A(v5);
            sub_44CC3D();
            sub_451600();
            PostMessageA(dword_4849EC, 0x111u, 0x154u, 0);
          }
          else
          {
            sub_4029CA("Imposible to find %s\nRunning without source display", *(_DWORD *)(dword_483C70 + 20));
            dword_484344 = 1;
            v7 = 1;
            PostMessageA(dword_4849EC, 0x111u, 0x154u, 0);
          }
        }
        goto LABEL_41;
      }
      dword_484338 = 1;
      v3 = sub_44DB56(qword_483C74);
      if ( v3 )
        *(_BYTE *)(v3 + 29) &= 0xFDu;
      result = ContinueDebugEvent(DebugEvent.dwProcessId, DebugEvent.dwThreadId, 0x10002u);
    }
    else
    {
      if ( DebugEvent.dwDebugEventCode != 5 )
        goto LABEL_41;
      if ( DebugEvent.dwProcessId != dword_483C84 )
      {
        v7 = 1;
        goto LABEL_41;
      }
      dword_49BF64 = 0;
      dword_49BF68 = 1;
      dword_481614 = 0;
      result = sub_402A32(4520, SLOBYTE(DebugEvent.u.Exception.ExceptionRecord.ExceptionCode));
      if ( !dword_483C6C )
        result = sub_40B155(lpCmdLine);
    }
  }
  else
  {
    if ( dword_483C6C )
      result = sub_44ECDC();
  }
  return result;
}

if под LABEL_50 е това, което закърпих (от 0x75 на 0xEB).

Беше лесно да забележа мястото, защото очаквах WriteProcessMemory, който да се използва за запис на 0xCC във входната точка на приложението, което се отстранява.

person expert    schedule 16.12.2011
comment
Е, исках да изчакам известно време, преди да маркирам това като отговор, просто в случай, че се появи друго решение. Това със сигурност решава проблема, но не толкова елегантно, колкото се надявах. Благодаря за решението! - person RLH; 03.01.2012