Delphi privileged instruction ошибка

@avp, SetLength(...) как раз работает с кучей.

@ололо, а вам таки обязательно передавать явно указатель на массив в процедуру? В таком виде неплохо работает:

var a : bgra1darray;

procedure bps(a:bgra1darray; l:integer);
var x:integer;
begin
  for x := 1 to l do
  begin
    a[x].b:=77;
    if x mod 10 =0 then
    begin
      write (a[x].b);
      write(' ');
      writeln(x);
    end;
  end;
end;

begin
  setlength(a, 10001);
  bps(a,10000);
  readln;
end.

UPD0. Да, мне пришлось изменить определение:

bgra1darray  = array of tbgra;

UPD1. Когда вы передаете массив в процедуру, разумеется он не будет скопирован. В этом легко убедиться, посмотрев соответствующий ассемблерный код:

Project1.dpr.38: bps(a,10000);        //Privileged Instruction (EPrivilege), х=1480
0040B1B2 BA10270000       mov edx,$00002710
0040B1B7 A13C1E4100       mov eax,[$00411e3c]
0040B1BC E8FBDDFFFF       call bps

И в самой процедуре:

Project1.dpr.19: begin
00408FBC 55               push ebp
00408FBD 8BEC             mov ebp,esp
00408FBF 51               push ecx
00408FC0 53               push ebx
00408FC1 56               push esi
00408FC2 57               push edi
00408FC3 8BDA             mov ebx,edx
00408FC5 8945FC           mov [ebp-$04],eax
00408FC8 8B45FC           mov eax,[ebp-$04]
00408FCB E89CC6FFFF       call @DynArrayAddRef

Как видим, просто передается адрес динамического массива (через eax), а потом помещается в стек (mov [ebp-$04],eax).

Очевидно вы натыкались на эксепшен, потому что передавали в процедуру адрес динамического массива bps(@a, 10000), что приводило к двойному взятию указателя и вы просто влезали в чужую память в итоге.

Ллирик

0 / 0 / 1

Регистрация: 27.11.2016

Сообщений: 96

1

09.02.2017, 02:27. Показов 8811. Ответов 11

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

При попытке вызвать процедуру другой формы из другого юнита передаваемую как параметр, получаю

error privileged instruction

Delphi
1
2
3
4
5
6
7
8
9
10
unit Unit1;
.......................
procedure THeaderFooterForm.Button1Click(Sender: TObject);
begin
  ShowMessageModal(Self, changeqwesttext, @procedure
        begin
    changeqwest;
  TabControl1.TabIndex := 1;
        end);
end;
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
unit MessageModal;
......................
  Defproc = procedure;
......................
procedure ShowMessageModal(Self: TForm; const AMessage: string;
  ADefProc: Defproc);
var
  locMessageForm: TMessageForm;
begin
  locMessageForm := TMessageForm.Create(Self);
...............................
  locMessageForm.showModal(    procedure(Result: TModalResult)
    begin
      if Result = mrOk then
      begin
      ADefProc;  //ВЫЛЕТАЕТ
      locMessageForm.CloseModal;
      end;
      end);
end;

. Вызовов ShowMessageModal достаточно много и мне бы не хотелось описывать каждую передаваемую процедуру отдельно. Подскажите, пожалуйста, в чём моя ошибка?



0



5537 / 4322 / 1383

Регистрация: 14.04.2014

Сообщений: 19,381

Записей в блоге: 19

09.02.2017, 08:57

2

предположу что
defproc = reference to procedure

и собачка выглядит лишней



0



0 / 0 / 1

Регистрация: 27.11.2016

Сообщений: 96

09.02.2017, 17:01

 [ТС]

3

Цитата
Сообщение от krapotkin
Посмотреть сообщение

предположу что
defproc = reference to procedure
и собачка выглядит лишней

Тогда компилятор выдаёт

[dcc32 Error] Unit1.pas(1103): E2010 Incompatible types: ‘Defproc’ and ‘Procedure’



0



Stertor

Заблокирован

09.02.2017, 17:56

4

Цитата
Сообщение от Ллирик
Посмотреть сообщение

Код

unit Unit1;
.......................
procedure THeaderFooterForm.Button1Click(Sender: TObject);
begin
  ShowMessageModal(Self, changeqwesttext, @procedure
        begin
    changeqwest;
  TabControl1.TabIndex := 1;
        end);
end;

Вы передаёте указатель на анонимную функцию — оттого и вылетает. Жаль, что подобное **рьмо вообще компилируется. Эмбаркадеровцам жирный МИНУС.



0



0 / 0 / 1

Регистрация: 27.11.2016

Сообщений: 96

09.02.2017, 19:54

 [ТС]

5

Цитата
Сообщение от Stertor
Посмотреть сообщение

Вы передаёте указатель на анонимную функцию — оттого и вылетает. Жаль, что подобное **рьмо вообще компилируется. Эмбаркадеровцам жирный МИНУС.

И что Вы предлагаете сделать?



0



5537 / 4322 / 1383

Регистрация: 14.04.2014

Сообщений: 19,381

Записей в блоге: 19

09.02.2017, 19:56

6

а в чем проблема?
ява вон вся на анонимках стоит, живут же. каша в кода — это да, но иногда…
Ллирик,
посмотрите, как объявлен метод ShowModal и сделайте так же
вам же это нужно?



0



Stertor

Заблокирован

09.02.2017, 21:33

7

Цитата
Сообщение от Ллирик
Посмотреть сообщение

И что Вы предлагаете сделать?

Устроить деанон.

Добавлено через 1 час 16 минут
procedure ShowMessageModal(Self: TForm; const AMessage: string;
ADefProc: Defproc);
var
locMessageForm: TMessageForm;
begin
locMessageForm := TMessageForm.Create(Self);

банальное переполнение стека.



0



0 / 0 / 1

Регистрация: 27.11.2016

Сообщений: 96

09.02.2017, 21:51

 [ТС]

8

Цитата
Сообщение от Stertor
Посмотреть сообщение

Добавлено через 1 час 16 минут
procedure ShowMessageModal(Self: TForm; const AMessage: string;
ADefProc: Defproc);
var
locMessageForm: TMessageForm;
begin
locMessageForm := TMessageForm.Create(Self);
банальное переполнение стека.

Вы это вообще о чём?))



0



Stertor

Заблокирован

09.02.2017, 22:02

9

О том, что синтаксический сахар Self используется как аргумент.

Код

locMessageForm := TMessageForm.Create(Self);

В этом месте- неоднозначность, т.к. нельзя точно понять, подразумевается ли аргумент Self, или пространство имен Self.

Это мой последний пост в этой темке, думаю, что сообщил достаточно. Я сваливаю.



0



Ллирик

0 / 0 / 1

Регистрация: 27.11.2016

Сообщений: 96

09.02.2017, 22:20

 [ТС]

10

Цитата
Сообщение от krapotkin
Посмотреть сообщение

посмотрите, как объявлен метод ShowModal и сделайте так же
вам же это нужно?

Delphi
1
2
3
4
5
procedure TCommonCustomForm.ShowModal(const ResultProc: TProc<TModalResult>);
begin
  FResultProc := ResultProc;
  Show;
end;

FResultProc объявлена как внутренняя процедура TCommonCustomForm, а мне бы хотелось чтоб ShowMessageModal была внешней как ShowMessage, чтоб её можно было использовать и в последующий программах без лишней возни

Добавлено через 14 минут

Цитата
Сообщение от Stertor
Посмотреть сообщение

О том, что синтаксический сахар Self используется как аргумент.
Код
locMessageForm := TMessageForm.Create(Self);
В этом месте- неоднозначность, т.к. нельзя точно понять, подразумевается ли аргумент Self, или пространство имен Self.

Естественно подразумевается аргумент Self, ведь процедура внешняя и у неё нет пространства имен



0



krapotkin

5537 / 4322 / 1383

Регистрация: 14.04.2014

Сообщений: 19,381

Записей в блоге: 19

09.02.2017, 23:04

11

не надо использовать Self

все просто. я же говорю, смотрите на ShowModal

Кликните здесь для просмотра всего текста

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
unit Unit2;
 
interface
 
uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  FMX.Controls.Presentation, FMX.StdCtrls;
 
type
  TForm2 = class(TForm)
    b1: TButton;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form2: TForm2;
 
procedure ShowMess(OkProc:TProc);
 
implementation
 
{$R *.fmx}
procedure ShowMess(OkProc:TProc);
begin
  form2:=TForm2.Create(nil);
    Form2.ShowModal(
      procedure (R:TModalResult)
      begin
        if r=mrOk then
          OkProc();
      end);
end;
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  action:=TCloseAction.caFree;
end;
 
end.

и вызов

Delphi
1
2
3
4
5
6
procedure TForm1.b1Click(Sender: TObject);
begin
  ShowMess(procedure begin
    ShowMessage('All works');
  end );
end;

Добавлено через 38 секунд
на Form2 у кнопки установлен modalResult = mrOk



0



0 / 0 / 1

Регистрация: 27.11.2016

Сообщений: 96

10.02.2017, 04:31

 [ТС]

12

Цитата
Сообщение от krapotkin
Посмотреть сообщение

не надо использовать Self

Self я там использую для других целей)

Добавлено через 20 минут
krapotkin, спасибо Вам большое! Разобрался



0



    msm.ru

    Нравится ресурс?

    Помоги проекту!

    [!] Как относитесь к модерированию на этом форуме? Выскажите свое мнение здесь

    >
    Ошибка выполнения: <Privileged instruction>
    , Куды рыть?

    • Подписаться на тему
    • Сообщить другу
    • Скачать/распечатать тему



    Сообщ.
    #1

    ,
    29.10.07, 13:07

      Senior Member

      ****

      Рейтинг (т): 23

      При запуске приложения вылетает окошко критического сообщения с с текстом «Privileged instruction» :wall: :wall: :wall: .
      После чего программа продолжает свою роботу.

      Пока даже не знаю, с какой стороны к этой ошибке подступится и куды вообще рыть? Какую «опасную» инструкцию искать?


      Сан Иваныч



      Сообщ.
      #2

      ,
      29.10.07, 13:12

        В IDE под отладчиком проверь.


        Шурик П.



        Сообщ.
        #3

        ,
        29.10.07, 13:36

          Senior Member

          ****

          Рейтинг (т): 23

          прошёлся отладчиком по шагам, выяснил, что вылетает при работе следёющего кода:

          ExpandedWrap disabled

            void TStab::LoadIni(TIniFile *f, AnsiString sectName)

            {

              vyb   = f->ReadInteger(sectName,   «vyb», 10);  // Размеры выборок

              vybMS = f->ReadInteger(sectName, «vybMS», 10);

              // Количества учавствующих в расчёте тэгов

              qAn    = f->ReadInteger(sectName,   «qAn», 1); // Количество аналоговых входов

              qAnMS  = f->ReadInteger(sectName, «qAnMS», 1); // Количество аналоговых входов по МС

              qDig   = f->ReadInteger(sectName,  «qDig», 1); // Количество дискретных входов

              qDigMS = f->ReadInteger(sectName,»qDigMS», 0); // Количество дискретных входов по МС

              qSt    = f->ReadInteger(sectName,   «qSt», 1); // Количество стартовых условий

              AnsiString s = f->ReadString(sectName, «anCom0», «Параметр 1» ); // Вылетает после выполнения этой строки

            }

          при этом — строки с <f->ReadInteger> выполняются без ошибок, и, более того, сами значения считываются правильно.

          Насколько понимаю — причина не в строке с <f->ReadString(…)>, а где-то раньше портится память — вопрос в том — как отловить место порчи. И что конкретно означает <Privileged instruction> ?


          7inner



          Сообщ.
          #4

          ,
          29.10.07, 14:25

            Privileged instruction означает, что в программе была попытка, вызвать недопустимую в данный момент инструкцию (например асм-команду, из ринг3, которая может выполнится только в ринг0; sysexit, как вариант).


            FFF1



            Сообщ.
            #5

            ,
            29.10.07, 15:17

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

              Цитата

              AnsiString s = f->ReadString(sectName, «anCom0», «Параметр 1» );

              Какой третий параметр у ReadString()? Везде у тебя числа 1,0,10 а тут вдруг ANSI-строка, ещё и русскими символами. Я не шарю в стандартных классах и их методах, не знаю твой это ReadString() или готовый уже, но в любом случае диззасемблируй его.


              Шурик П.



              Сообщ.
              #6

              ,
              30.10.07, 05:53

                Senior Member

                ****

                Рейтинг (т): 23

                Цитата FFF1 @ 29.10.07, 15:17

                Какой третий параметр у ReadString()

                — это значение — возвращаемое по умолчанию (в случае, если считывание из ini-файла не удалось). А функция — стандартная Borland-овская — это метод класса TIniFile для считывания строковых параметров.

                В общем — понятно, надо искать порчу памяти в другом месте. сама по себе эта функция вряд ли сможет создать привелигированную инструкцию.

                Добавлено 30.10.07, 06:18


                А ларчик просто открывался, сразу надо было CodeGuard-ом пройтись. Ещё до считывания файла срабатывало событие OnDrawCell, а внутри него шло обращение к ещё не созданому объекту. вот память и портилась. Всем спасибо за подсказки и разьяснения.

                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)

                0 пользователей:

                • Предыдущая тема
                • Borland C++ Builder/Turbo C++ Explorer
                • Следующая тема

                Рейтинг@Mail.ru

                [ Script execution time: 0,0371 ]   [ 16 queries used ]   [ Generated: 3.06.23, 23:55 GMT ]  

                @avp, SetLength(...) как раз работает с кучей.

                @ололо, а вам таки обязательно передавать явно указатель на массив в процедуру? В таком виде неплохо работает:

                var a : bgra1darray;
                
                procedure bps(a:bgra1darray; l:integer);
                var x:integer;
                begin
                  for x := 1 to l do
                  begin
                    a[x].b:=77;
                    if x mod 10 =0 then
                    begin
                      write (a[x].b);
                      write(' ');
                      writeln(x);
                    end;
                  end;
                end;
                
                begin
                  setlength(a, 10001);
                  bps(a,10000);
                  readln;
                end.
                

                UPD0. Да, мне пришлось изменить определение:

                bgra1darray  = array of tbgra;
                

                UPD1. Когда вы передаете массив в процедуру, разумеется он не будет скопирован. В этом легко убедиться, посмотрев соответствующий ассемблерный код:

                Project1.dpr.38: bps(a,10000);        //Privileged Instruction (EPrivilege), х=1480
                0040B1B2 BA10270000       mov edx,$00002710
                0040B1B7 A13C1E4100       mov eax,[$00411e3c]
                0040B1BC E8FBDDFFFF       call bps
                

                И в самой процедуре:

                Project1.dpr.19: begin
                00408FBC 55               push ebp
                00408FBD 8BEC             mov ebp,esp
                00408FBF 51               push ecx
                00408FC0 53               push ebx
                00408FC1 56               push esi
                00408FC2 57               push edi
                00408FC3 8BDA             mov ebx,edx
                00408FC5 8945FC           mov [ebp-$04],eax
                00408FC8 8B45FC           mov eax,[ebp-$04]
                00408FCB E89CC6FFFF       call @DynArrayAddRef
                

                Как видим, просто передается адрес динамического массива (через eax), а потом помещается в стек (mov [ebp-$04],eax).

                Очевидно вы натыкались на эксепшен, потому что передавали в процедуру адрес динамического массива bps(@a, 10000), что приводило к двойному взятию указателя и вы просто влезали в чужую память в итоге.

                Написал простенький код для отправки почты по смтп с авторизацией.Вчера вроде все нормально работало седня только только F9 нажал запустил код и раз ,выкидует эту ошибку :eek: Ошибка вылазит как раз когда отрабатывает ф-ция кодирующая в base64

                void Base64_code(const char* strIn, AnsiString &strOut)
                {
                 const static char base64ABC[] = «ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/»;

                 
                 strOut = «»;
                 const size_t len = strlen(strIn);

                 
                  for(unsigned int i=0; i<len; i+=3) {
                    LONG l = ( ((LONG)strIn[i ])<<16 ) |
                             (((i+1) < len) ? (((LONG)strIn[i+1])<<8 ) : 0 ) |
                             (((i+2) < len) ? ( (LONG)strIn[i+2] ) : 0 );
                    strOut += base64ABC[(l>>18) & 0x3F];
                    strOut += base64ABC[(l>>12) & 0x3F];
                    if (i+1 < len) strOut += base64ABC[(l>> 6) & 0x3F];
                    if (i+2 < len) strOut += base64ABC[(l ) & 0x3F];
                  }
                  switch (len%3) {
                    case 1:
                  strOut += ‘=’;
                    case 2:
                  strOut += ‘=’;
                  }
                }

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

                Понравилась статья? Поделить с друзьями:
              • Delphi getlasterror текст ошибки
              • Delphi exception код ошибки
              • Delphi ds150e коды ошибок
              • Delphi dateseparator ошибка
              • Delphi copyfile коды ошибок