Попинал проект слегка, чтобы совсем уж не слежался.
По ходу выяснил, какой я былинный дятел. Долбический.
Для понтов и удобства у меня отладочная информация извлекается из екзешника/длл во внешний файл, чтобы потом этот екзешник/длл обработать strip и, по возможности, upx. Меньше четырёхсот килобайт, что.
Я не дурак (думал, что) поэтому файл с отладочной инфой подписывается md5 суммой екзешника
Выглядит это так: из лазаруса вызывается build.bat, в котором стоит последовательность
- удалить старый екзешник
- удалить старую отладочную инфу
- скомпилировать
- извлекатор отладочной инфы
- strip+upx
- подписатор отладочной инфы, прописывающий md5 уже окученного екзешника.
Но закралось маааленькое такое западло. -gl для фри паскаля - скорее необязательная рекомендация, некоторые верси могут сгенерировать отладочную инфу или не сгенерировать - по желанию левой пятки.
Всё бы ничего, но с некоторой версии пор лазарус перестал отображать в своей консоли вывод извлекатора и подписатора, насрав на галочку "Show all". То есть, чтобы увидеть, что с этим происходит, надо вручную запускать build.bat из консоли. 
Всё бы ничего, но один шибко рассеянный дятел, когда перепахивал проект, забыл вставить в батник команды на удаление старой отладочной инфы.
И... Извлекатор ничего не находит и ничего не делает. Подписатор находит старую тухлятину и на голубом глазу подписывает её заново. Прога крашится. Один шибко умный дятел идёт, куда его послал отладочный вывод, и начинает там искать причину аццесс виолейшена, постепенно охреневая...
Пилите, Шура, пилите 
Добавлено спустя 15 минут 31 секунду:З.Ы. Хаха, нет! Погибель моя таилась в совсем другом месте.
Связано с тем, что dll (и отладочная инфа вместе с нею) перед запуском копируются во временную папку чтобы позволить перекомпиляцию во время выполнения. И угадайте, кто только копировал файлы, не удаляя лишние?
 Исправил
- Код: Выделить всё
   procedure TModule.Load;
    procedure CopyOne(a, b: TFileNameString; CrashIfMissing: boolean = false);
    begin
     if FileExists(a) or CrashIfMissing then begin
       if Mother^.Debug.Verbose then AddLog('   ..copying file %0 to %1', [a,b]);
       chCopyFile(a, b);
     end
     else begin
       if Mother^.Debug.Verbose then AddLog('   ..no such file: %0', [a]);
     end;
    end;
  begin  
  
  ...
  
        if Mother^.State.DeveloperMode then begin
          CopyOne(_Fromdir + _FName, _ToDir + _FName, true);
          CopyOne(_Fromdir + ChangeFileExt(_FName, TFileNameString('.zdwarf2')),
                  _ToDir + ChangeFileExt(_FName, TFileNameString('.zdwarf2')));
          CopyOne(_Fromdir + 'bin' + DS + 'lineinfo' + DS + ChangeFileExt(_FName, TFileNameString('.zdwarf2')),
                  _ToDir + ChangeFileExt(_FName, TFileNameString('.zdwarf2')));
          CopyOne(_Fromdir + ChangeFileExt(_FName, TFileNameString('.zstabs')),
                  _ToDir + ChangeFileExt(_FName, TFileNameString('.zstabs')));
          CopyOne(_Fromdir + 'bin' + DS + 'lineinfo' + DS + ChangeFileExt(_FName, TFileNameString('.zstabs')),
                  _ToDir + ChangeFileExt(_FName, TFileNameString('.zstabs')));
          _dllname:= _ToDir + _Fname;  
на
- Код: Выделить всё
   procedure TModule.Load;
    procedure CopyOne(a, b: TFileNameString; CrashIfMissing: boolean = false);
    begin
     if FileExists(a) or CrashIfMissing then begin
       if Mother^.Debug.Verbose then AddLog('   ..copying file %0 to %1', [a,b]);
       chCopyFile(a, b);
     end
     else begin
       if Mother^.Debug.Verbose then AddLog('   ..no such file: %0', [a]);
       if FileExists(b) then begin
         if Mother^.Debug.Verbose then AddLog('   ..deleting existing: %0', [b]);
         DeleteFile(b);
       end;
     end;
    end;
  begin   
..скольких страданий можно было бы избежать, скольких часов проведённых за отладкой, бессмыссленной и беспощадной.
Добавлено спустя 17 минут 36 секунд:..ооокей, я в полном... в непонятках, короче.
Фри паскаль 3.0.4
- если вызвать с одной -gl (по идее, Stabs по умолчанию?) - генерирует Dwarf2
- если вызвать с -gl -gw2 (прямым текстом потребовать Dwarf2) - генерирует Stabs
- если вызвать батник из лазаруса - *гарантировано* ничего не генерирует. Только из консоли.
КАКОГО. 
Добавлено спустя 18 минут 56 секунд:То есть, я *могу* использовать фпц 3, и *всё работает*, но я обязательно должен запускать build.bat из консоли, не из лазаруса!
..какое гемороище.
Добавлено спустя 11 часов 53 минуты 39 секунд:З.Ы. Длл генерируется Ок, с включённой stabs. Это извлекатор глючит.
Потом добавлю журналирование, разберусь почему.
Добавлено спустя 12 часов 37 минут 7 секунд:Всё оказалось *гораздо* интереснее! 
Обновил лазарус с 1.4.4 до 1.8.4, коий зело многословнее - выяснилось, что у него встроенный интерпретатор .BAT файлов, причём - неполноценный! Он парсит батник при запуске, вычисляя переменные окружения и вштыривая их напрямую.
И получалось, что переменная окружения, которая задавалась ниже по течению, внутри блока if, тупо не работала! 
 И екзешник собирался с неправильными ключами.
Может, из-за этого были все мои проблемы с фпц 3?
Перенёс все определения в самое начало - сразу всё заработало!