Форум » [x]Harbour » Почему CTRL-BREAK срубает Harbour ? » Ответить

Почему CTRL-BREAK срубает Harbour ?

Sergy: В процессе расследования "необъяснимых" вылетов программы родилась мысль: при запуске программы запускать вторую ее копию. Это чтобы не муздыкаться с батниками, всякими loader.exe и прочими вариантами на множестве рабочих мест. Первая копия дожидается завершения второй копии, сохраняет содержимое экрана в лог и завершает работу, как ни в чем не бывало. Во время "домашнего" тестирования всё работало прекрасно, пока я не наткнулся на комбинацию кнопок CTRL-BREAK. Мало того, что ей чихать на установку SETCANCEL(FALSE), так еще получается, что вырубаются оба приложения: и родительское и вторая его копия. Т.е. копия экрана не создается ни при каких условиях, если в вызванном приложении нажата эта комбинация... Простой пример: [more][pre2] #define CRLF CHR(13)+CHR(10) #define TRUE .T. FUNC Main() LOCAL i SETCANCEL(.F.) //doesn't matter ? Call2nd() CLEAR SCREEN FOR i:=8 TO 15 @ i,i SAY "Hello, world." NEXT i @ 20,10 SAY "If you press any key - screen will be logged, if CTRL-BREAK - not. Why?" INKEY(0) RETURN * ----------------- * STATIC FUNC Call2nd() LOCAL sx:=DOSPARAM(),fname:="screen.log",i,s IF ("/2nd" $ sx) RETURN ENDIF RUN(EXENAME()+" "+sx+" /2nd") Alert("Program terminated, screen saved.") STRFILE(CRLF+PADC(" Screen capture: "+DTOC(DATE())+" "+TIME()+" ",MAXCOL()+1,CHR(196))+CRLF,fname,TRUE) FOR i:=0 TO MAXROW() s:=CHARODD(SAVESCREEN(i,0,i,MAXCOL())) IF !EMPTY(s) STRFILE(s+CRLF,fname,TRUE) ENDIF NEXT i STRFILE(REPL(CHR(196),MAXCOL()+1)+CRLF,fname,TRUE) QUIT RETURN [/pre2][/more]

Ответов - 16

AlexMyr: Хотел протестировать, но получил d:/tmp/hbmk_8ecjyv.dir/serg.o:serg.c:(.data+0x88): undefined reference to `HB_FUN_DOSPARAM' d:/tmp/hbmk_8ecjyv.dir/serg.o:serg.c:(.data+0xa8): undefined reference to `HB_FUN_EXENAME' d:/tmp/hbmk_8ecjyv.dir/serg.o:serg.c:(.data+0x88): undefined reference to `HB_FUN_STRFILE' d:/tmp/hbmk_8ecjyv.dir/serg.o:serg.c:(.data+0xe8): undefined reference to `HB_FUN_CHARODD' c:/mingw/bin/../lib/gcc/mingw32/4.7.2/../../../../mingw32/bin/ld.exe: d:/tmp/hbmk_8ecjyv.dir/serg.o: bad reloc address 0xf in section `.text.startup' c:/mingw/bin/../lib/gcc/mingw32/4.7.2/../../../../mingw32/bin/ld.exe: final link failed: Invalid operation collect2.exe: error: ld returned 1 exit status Давайте начинать с самодостаточных примеров, скомпилил, запустил, посмотрел результат, а уж потом добавлять другие ф-и.

Sergy: Эти функции из Clipper Tools, ныне hbct. Я обычно все свои примеры компилирую так: hbmk2 test.prg -prgflag=/v d:\harbour\contrib\hbct\hbct.hbc, поэтому забыл. Сорри.

AlexMyr: Собирать можно так hbmk2 test.prg -prgflag=/v hbct.hbc Под терминалом gtwvt тестировали?


Dima: AlexMyr пишет: Под терминалом gtwvt тестировали? Под ним нет такого эффекта.

Sergy: AlexMyr пишет: Собирать можно так hbmk2 test.prg -prgflag=/v hbct.hbc Под терминалом gtwvt тестировали? Работаю под GTWIN. Знаю о "вкусностях" второго терминала, но хочу для начала полностью перейти с Clipper на Harbour - сделать стабильное и надежное приложение. После чего заняться апгрейдом программы на полную катушку.

AlexMyr: Заменил RUN на hb_processRun, стал появляться screen.log

Sergy: AlexMyr пишет: Заменил RUN на hb_processRun, стал появляться screen.log У меня нет пока возможности проверить, скажите пожалуйста: в логе есть Harbour сообщение "Cancelled at ..." и стек вызовов (как обычно) ? Alert появляется ? Спасибо.

AlexMyr: Вот что в screen.log [pre2] ────────────────────── Screen capture: 10/14/13 11:54:48 ─────────────────────── C:\prg_hrb\test\sergy\>serg.exe ──────────────────────────────────────────────────────────────────────────────── [/pre2] Sergy пишет: Alert появляется ? Да.

Sergy: AlexMyr пишет: Вот что в screen.log ────────────────────── Screen capture: 10/14/13 11:54:48 ─────────────────────── C:\prg_hrb\test\sergy\>serg.exe ──────────────────────────────────────────────────────────────────────────────── У меня получилось аналогично. Все хорошо, но где содержимое экрана ?

AlexMyr: Sergy пишет: Все хорошо, но где содержимое экрана ? валится вторая задача, потому содержимое первого экрана.

Sergy: AlexMyr пишет: валится вторая задача, потому содержимое первого экрана. Тут я не очень понимаю. Почему тогда на экране строки "Hello world" видны (в момент Alert()), а SAVESCREEN вызывашей задачи не может их забрать к себе ? Почему он может это сделать, если не был нажат CTRL-BREAK ?

Dima: Sergy пишет: Почему он может это сделать, если не был нажат CTRL-BREAK ? При нажатии любой клавиши снимок экрана так же пуст и все после замены RUN на hb_processRun. Оно как бы и понятно почему , так как hb_processRun выполняется в отдельном окне.

Sergy: Dima пишет: При нажатии любой клавиши снимок экрана так же пуст и все после замены RUN на hb_processRun. +1 Обнаружил тоже самое. Оно как бы и понятно почему , так как hb_processRun выполняется в отдельном окне. А вот это - не очень понятно. У меня все четко, один процесс запускает другой: Только в случае с "обычным" RUN() или __Run() между двумя задачами возникает прослойка в виде cmd.exe

Sergy: Сделал так: [pre2]--------------------- i2test.prg ------------------ #define CRLF CHR(13)+CHR(10) #define TRUE .T. FUNC Main() LOCAL i SETCANCEL(.F.) IF "/save" $ DOSPARAM() SavePrevConsole() ELSE CLEAR SCREEN FOR i:=8 TO 15 @ i,i SAY "Hello, world." NEXT i @ 20,10 SAY "If you press any key - screen will be saved, if CTRL-BREAK - may be yes or not. Why?" INKEY(0) ENDIF RETURN * ------------------------- * STATIC FUNC SavePrevConsole() LOCAL fname:="report.!!!",i,s STRFILE(CRLF+PADC(" Screen capture: "+DTOC(DATE())+" "+TIME()+" ",MAXCOL()+1,CHR(196))+CRLF,fname,TRUE) FOR i:=0 TO MAXROW() s:=CHARODD(SAVESCREEN(i,0,i,MAXCOL())) IF !EMPTY(s) STRFILE(s+CRLF,fname,TRUE) ENDIF NEXT i STRFILE(REPL(CHR(196),MAXCOL()+1)+CRLF,fname,TRUE) ? "Program terminated, screen saved" WAIT RETURN --------------------- loader.prg ------------------ FUNC Main() HB_ProcessRUN("i2test.exe") HB_ProcessRUN("i2test.exe /save") RETURN[/pre2] Что получается: если вызывать программу через RUN() - CTRL-BREAK рубит все подряд. Если вызывать два экзешника через батник - появляется вопрос: "Завершить выполнение бат-файла [Да/нет]?" и в зависимости от результата, экран сохраняется или нет. Если вызывать через HB_ProcessRun() - все работает ок. Пофигу, какие кнопки нажаты.

Sergy: Сделал так: loader.prg: [pre2] FUNC Main() HB_ProcessRUN("i2test.exe") STRFILE(CHARODD(SAVESCREEN()),"loader.!!!") // тест HB_ProcessRUN("i2test.exe /save") RETURN[/pre2] Почему так получается, что из программы loader.exe SAVESCREEN "не видит" содержимого экрана (loader.!!! пустой, там только c:\path\loader.exe внизу), а из другого процесса - все ок ??? А если сделать в loader.prg так: [pre2]FUNC Main() IF "/save" $ DOSPARAM() STRFILE(CHARODD(SAVESCREEN()),"loader.!!!") // сохраняем в другой файл, чтобы не путать ELSE HB_ProcessRUN("i2test.exe") // рисуем на экране что угодно HB_ProcessRUN("loader.exe /save") // сохраняем вызовом самих себя ENDIF RETURN[/pre2] то получается, что экран легко сохраняется.

Sergy: Вот так все работает, пофиг на CTRL-BREAK, только мне совсем непонятно, почему... [pre2] #define CRLF CHR(13)+CHR(10) #define TRUE .T. FUNC Main() SETCANCEL(.F.) IF "/save" $ DOSPARAM() SavePrevConsole() ELSEIF "/do" $ DOSPARAM() DoSomething() ELSE HB_ProcessRun(EXENAME()+" /do") HB_ProcessRun(EXENAME()+" /save") ENDIF RETURN * --------------------- * STATIC FUNC DoSomething() LOCAL i CLEAR SCREEN FOR i:=8 TO 15 @ i,i SAY "Hello, world." NEXT i @ 20,10 SAY "If you press any key - screen will be saved, if CTRL-BREAK - not. Why?" INKEY(0) RETURN * ------------------------- * STATIC FUNC SavePrevConsole() LOCAL fname:="report.!!!",i,s STRFILE(CRLF+PADC(" Screen capture: "+DTOC(DATE())+" "+TIME()+" ",MAXCOL()+1,CHR(196))+CRLF,fname,TRUE) FOR i:=0 TO MAXROW() s:=CHARODD(SAVESCREEN(i,0,i,MAXCOL())) IF !EMPTY(s) STRFILE(s+CRLF,fname,TRUE) ENDIF NEXT i STRFILE(REPL(CHR(196),MAXCOL()+1)+CRLF,fname,TRUE) ? "Program terminated, screen saved" WAIT RETURN // EOF here [/pre2]



полная версия страницы