|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Сен 17, 2004 07:19:09 n0p ЗЫ: не воспринимайте меня всерьез - я слишком пъян. По-нашенски :) Значит WriteConsole всему причина? А она в сорцах двутоника есть? Надо глянуть... :) |
|
|
Дата: Сен 17, 2004 07:36:15 Посмотрел в сорцах винды. WriteConsoleOutput вызывает WriteConsoleOutputInternal. А там муть какая-то... Но никаких намеков на \b или \t я не увидел... Вот файл: %W2K_SRC_ROOT%\private\ntos\w32\ntcon\client\iostubs.c Там есть тело WriteConsoleOutputInternal. Вот еще: %W2K_SRC_ROOT%\private\ntos\w32\ntcon\client\stream.c Там описана WriteConsole и WriteConsoleInternal. В ней видно, что юзается несколько функций, похоже native api, Может дело в них. Их имена: - CsrAllocateCaptureBuffer - CsrCaptureMessageBuffer - RtlCopyMemory - CsrClientCallServer - CsrFreeCaptureBuffer Никакие другие функции внутри WriteConsoleInternal вроде не юзаются. Скорее всего дело в одной из них. Я бы и сами файлы припостил, да боюсь товарищ Беспощадный Даос обидется :) |
|
|
Дата: Сен 17, 2004 12:37:13 · Поправил: S_T_A_S_ Хмм.. а почему именно WriteConsole?
extern "C" int __cdecl printf(const char * format, ...)
{
char szBuff[1024];
int retValue;
DWORD cbWritten;
va_list argptr;
va_start( argptr, format );
retValue = wvsprintf( szBuff, format, argptr );
va_end( argptr );
WriteFile( GetStdHandle(STD_OUTPUT_HANDLE), szBuff, retValue, &cbWritten, 0 );
return retValue;
} |
|
|
Дата: Сен 17, 2004 12:57:41 · Поправил: q_q S_T_A_S_ Imho wvsprintf/wsprintf нельзя считать достойной заменой printf'у - не поддерживают вывод вещественных и 64-хбитных чисел. А WriteFile в отличие от WriteConsole не делится на UNICODE и ANSI версии, т.е. необходимы дополнительные усилия. |
|
|
Дата: Сен 17, 2004 15:31:48 Хмм.. а почему именно WriteConsole? Если вызвать WriteFile с хендлом стандартного вывода в 1-м параметре, то мы как раз в WriteConsole и попадаем. вот проверка на std_out_handle: .text:77E94A7E mov eax, edi .text:77E94A80 and eax, 10000003h .text:77E94A85 cmp eax, 3 .text:77E94A88 jz short loc_77E94AD7этот jz перескакивает вызов NtWriteFile, а дальше: .text:77E94AD7 loc_77E94AD7: ; CODE XREF: WriteFile+64j .text:77E94AD7 push [ebp+lpReserved] ; lpReserved .text:77E94ADA push ebx ; lpNumberOfCharsWritten .text:77E94ADB push [ebp+nNumberOfCharsToWrite] ; nNumberOfCharsToWrite .text:77E94ADE push [ebp+lpBuffer] ; lpBuffer .text:77E94AE1 push edi ; hConsoleOutput .text:77E94AE2 call WriteConsoleA .text:77E94AE7 jmp short loc_77E94AC6 .text:77E94AE7 WriteFile endp |
|
|
Дата: Сен 18, 2004 05:01:40 Дело не в WriteFile / WriteConsole. Возможно (?) дело вообще не в них. Поскольку у мя давно установлен SP на XP, то проверитьь я не могу, а так бы попробовал заменить библиотечный printf на код выше. Да ещё и из DOS сессии б попечатал. А так кто его знает, может быть проблема, например, в обработчике SEH.. _printf proc near
push 0Ch
push offset __sehtable$_printf
call __SEH_prolog
xor esi, esi
cmp [ebp+8], esi
jnz short loc_30
call __errno
mov dword ptr [eax], 16h
push esi
push esi
push esi
push esi
push esi
call __invalid_parameter
add esp, 14h
or eax, 0FFFFFFFFh
jmp short loc_8B
loc_30: ; CODE XREF: _printf+11j
call ___iob_func
push 20h ; ' '
pop edi
add eax, edi
push eax
push 1
call __lock_file2
pop ecx
pop ecx
mov [ebp-4], esi
call ___iob_func
add eax, edi
push eax
call __stbuf
pop ecx
mov esi, eax
lea eax, [ebp+0Ch]
push eax
push dword ptr [ebp+8]
call ___iob_func
add eax, edi
push eax
call __output
mov [ebp-1Ch], eax
call ___iob_func
add eax, edi
push eax
push esi
call __ftbuf
add esp, 14h
or dword ptr [ebp-4], 0FFFFFFFFh
call $LN6
$LN9:
mov eax, [ebp-1Ch]
loc_8B: ; CODE XREF: _printf+2Ej
call __SEH_epilog
retn
_printf endp |
|
|
Дата: Сен 18, 2004 07:51:02 Привет! Заглянул ;) я тоже попробовал на вин 2к сп4 - живет а за хр без сп скажу - стояла у меня такая ;) если щелкнуть по регулятору громкости второй раз, пока не появился первый - вывалит около сотни регуляторов - задолбаешься закрывать ;) |
|
|
Дата: Сен 18, 2004 11:58:52 S_T_A_S_ Возможно (?) дело вообще не в них. Я тоже думаю, что баг сидит где-то на низком уровне, по крайней мере в kernel-mode однозначно. Я уже высказывал догадку насчет '\b', попробую изложить ее подробнее: где-то в недрах системы код посимвольно выводит строку, наращивая указатель, скажем, на видеопамять, встретив '\b', указатель уменьшается. И если забоев было больше, чем табуляций, указатель в итоге смотрит на недоступный для записи участок, за пределы страницы, например. А вообще искать баг уже не актуально, т.к. сервис-паки его исправляют. |
|
|
Дата: Сен 19, 2004 06:40:51 S_T_A_S_ Поскольку у мя давно установлен SP на XP, то проверитьь я не могу, а так бы попробовал заменить библиотечный printf на код выше. Да ещё и из DOS сессии б попечатал. У меня XPюшка без сервиспаков. Заменил, попечатал - пашет нормально, не падает. Кривая реализация printf'а? А почему тогда с сервиспаками все нормально? |
|
|
Дата: Сен 19, 2004 07:30:49 krid24 > Заменил, попечатал - пашет нормально, не падает. Интересно.. а мне уже начало казаться, что я где-то читал про подобный глюк, только вывод на экран производился из DOS сессии.. Есть ещё один вариант - возможно (?), ошибка в программе _DEN_а. Если это так, то такой код должен работать нормально: #include <stdio.h>
void main ()
{
while( printf("\t\t\b\b\b") ) ;
}
> Кривая реализация printf'а? А почему тогда с сервиспаками все нормально? В том-то и дело, что прога 3го кольца сваливать систему не должна по идее.. Какие там ЕЩЁ функции (кроме WriteFile / WriteConsole) вызывает код из libc даже думать страшно :) |
|
|
Дата: Сен 20, 2004 02:57:24 S_T_A_S_ Всмысле? Какая у меня может быть ошибка, если суть проги, что она убивает винду, и винда у меня мрет безошибочно |
|
|
Дата: Сен 20, 2004 06:21:06 _DEN_ > Какая у меня может быть ошибка.. Ты пробовал мой вариант цикла ? Если он ведёт себя точно так же, значит, некоректное использование printf в твоём варианте не влияет на то, что сваливается виндос. Также имеется и другая проблема. Одной из причин того, что комитет ISO/ANSI по Си++ требует, чтобы оператор new возбуждал исключение, если он не может выделить память, заключается в том, что кто-то провел исследование и обнаружил, что какая-то смехотворная доля ошибок времени выполнения в реальных программах вызвана людьми, не побеспокоившимися проверить, не вернула ли функция malloc() значение NULL. По причинам, обсуждаемым позже, я не думаю, что исключение должно быть использовано вместо возврата ошибки просто для защиты программистов от себя самих, но оно срабатывает с new, потому что эта ошибка обычно в любом случае неисправима. Лучшим примером может быть функция printf(). Большинство программистов на Си даже не знают, что printf() возвращает код ошибки. (Она возвращает количество выведенных символов, которое может быть равно 0, если на диске нет места). Программисты, которые не знают о возврате ошибки, склонны ее игнорировать. А это не очень хорошо для программы, которая осуществляет запись в перенаправленный стандартный вывод, продолжать, как будто все в порядке, поэтому можно считать хорошей идеей возбудить здесь исключение. |
|
|
Дата: Сен 20, 2004 09:20:03 Ты пробовал мой вариант цикла ? Я пробовал, результат тот же. и винда у меня мрет безошибочно :=) |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.047 |