You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4cxx-user@logging.apache.org by Arunkumar <av...@appsecinc.com> on 2006/05/30 16:11:45 UTC

Build works + OutputDebugAppender + Unicode

Hi guys,

The head revision builds and the dll works for VS.Net 2003. The problem was
dumb. My application was loading an older log4cxxd.dll from a different path
(aaargh) and hence the linker and runtime errors popped up as the lib file
did not match the dll. It's just not your day (or days) sometimes. :)

But now that I have it working I have some issues:
1) OutputDebugAppender has a bug. If you do not specify a layout pointer it
crashes at runtime. The following code WORKS in case someone wants to try
it. 

------------------------- Working Code -----------------------------------
log4cxx::LoggerPtr LoggerMain(log4cxx::Logger::getLogger("LoggingMain"));

log4cxx::LogString logPatStrMain = (log4cxx::logchar*) L"%d [%t] %l %p -
%m%n";
	
//Create the pattern layout using the string used above
log4cxx::PatternLayoutPtr PatLayoutMain = new
log4cxx::PatternLayout(logPatStrMain);

//Add the OutputDebugString Appender to the Main Logger
log4cxx::nt::OutputDebugStringAppender* pTestODA = new
log4cxx::nt::OutputDebugStringAppender();

pTestODA->setLayout(PatLayoutMain);

LoggerMain->addAppender(pTestODA);
---------------------------------------------------------------------------

BUT if you remove pTestODA->setLayout(PatLayoutMain); then you will see that
the program crashes.
The cause of the crash is the line layout->format(buf, event, p); in the
append function located in outputdebugstringappender.cpp.
If buf is null it crashes.

void OutputDebugStringAppender::append(const spi::LoggingEventPtr& event,
Pool& p)
{
        LogString buf;
        layout->format(buf, event, p);
#if LOG4CXX_HAS_WCHAR_T
        LOG4CXX_ENCODE_WCHAR(wstr, buf);
        ::OutputDebugStringW(wstr.c_str());
#else
        LOG4CXX_ENCODE_CHAR(str, buf);
        ::OutputDebugStringA(str.c_str());
#endif
}
#endif


2) Hey Curt / Andreas even after building the dll with -Dhas.wchar_t=1, I
still see the raw Unicode strings in the console and ?????? in the text
file. Can you guys point me in the correct direction for testing
multi-lingual string logging with log4cxx.

Thanks
Arun




Re: Build works + OutputDebugAppender + Unicode

Posted by Andreas Fester <af...@apache.org>.
Arunkumar wrote:
> Hey Curt,
> Thanks for your suggestions. I will try to make the suggested changes and
> see what happens.
> 
> My test bed is:
> OS: Windows XP SP2
> VisualStudio.Net 2003
> Text Editor: Notepad or MS Word (after your email, downloaded the SuperEdi
> Editor)

In the windows cmd.exe console, you can try setting the code page
to UTF-8 (which is codepage 65001):

C:\> chcp 65001

Then you should be able to see the correct glyphs from UTF-8 output in this
console, provided that you have set a proper console font (LucidaConsole
contains some greek characters, but I have not yet found a font which includes
CJK glyphs for example). "Complete" unicode fonts like Arial Unicode MS do not
work because they are no fixed fonts.

See also
http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q247815

Regards,

	Andreas



RE: Build works + OutputDebugAppender + Unicode

Posted by Arunkumar <av...@appsecinc.com>.
Hey Curt,
Thanks for your suggestions. I will try to make the suggested changes and
see what happens.

My test bed is:
OS: Windows XP SP2
VisualStudio.Net 2003
Text Editor: Notepad or MS Word (after your email, downloaded the SuperEdi
Editor)

Thanks
Arun

-----Original Message-----
From: log4cxx-user-return-1590-aviswanathan=appsecinc.com@logging.apache.org
[mailto:log4cxx-user-return-1590-aviswanathan=appsecinc.com@logging.apache.o
rg] On Behalf Of Curt Arnold
Sent: Tuesday, May 30, 2006 2:51 PM
To: Log4CXX User
Subject: Re: Build works + OutputDebugAppender + Unicode


On May 30, 2006, at 9:11 AM, Arunkumar wrote:

> Hi guys,
>
> The head revision builds and the dll works for VS.Net 2003. The  
> problem was
> dumb. My application was loading an older log4cxxd.dll from a  
> different path
> (aaargh) and hence the linker and runtime errors popped up as the  
> lib file
> did not match the dll. It's just not your day (or days) sometimes. :)
>
> But now that I have it working I have some issues:
> 1) OutputDebugAppender has a bug. If you do not specify a layout  
> pointer it
> crashes at runtime. The following code WORKS in case someone wants  
> to try
> it.
>
> ------------------------- Working Code  
> -----------------------------------
> log4cxx::LoggerPtr LoggerMain(log4cxx::Logger::getLogger 
> ("LoggingMain"));
>
> log4cxx::LogString logPatStrMain = (log4cxx::logchar*) L"%d [%t] %l  
> %p -
> %m%n";
> 	
> //Create the pattern layout using the string used above
> log4cxx::PatternLayoutPtr PatLayoutMain = new
> log4cxx::PatternLayout(logPatStrMain);
>
> //Add the OutputDebugString Appender to the Main Logger
> log4cxx::nt::OutputDebugStringAppender* pTestODA = new
> log4cxx::nt::OutputDebugStringAppender();
>
> pTestODA->setLayout(PatLayoutMain);
>
> LoggerMain->addAppender(pTestODA);
> ---------------------------------------------------------------------- 
> -----
>
> BUT if you remove pTestODA->setLayout(PatLayoutMain); then you will  
> see that
> the program crashes.
> The cause of the crash is the line layout->format(buf, event, p);  
> in the
> append function located in outputdebugstringappender.cpp.
> If buf is null it crashes.
>
> void OutputDebugStringAppender::append(const spi::LoggingEventPtr&  
> event,
> Pool& p)
> {
>         LogString buf;
>         layout->format(buf, event, p);
> #if LOG4CXX_HAS_WCHAR_T
>         LOG4CXX_ENCODE_WCHAR(wstr, buf);
>         ::OutputDebugStringW(wstr.c_str());
> #else
>         LOG4CXX_ENCODE_CHAR(str, buf);
>         ::OutputDebugStringA(str.c_str());
> #endif
> }
> #endif


Thanks.  It should have checked that layout was non-null.  That check  
is provided for most appenders in WriterAppender, but since  
OutputDebugStringAppender doesn't inherit from that class, it was  
overlooked.


>
>
> 2) Hey Curt / Andreas even after building the dll with - 
> Dhas.wchar_t=1, I
> still see the raw Unicode strings in the console and ?????? in the  
> text
> file. Can you guys point me in the correct direction for testing
> multi-lingual string logging with log4cxx.
>
> Thanks
> Arun
>

There are several unit tests that check whether character encoding is  
working as expected.  I suspect that you are passing the unit tests,  
so the basic encoding framework is working tolerably.

The ???? in the text files suggest that the text editor that you are  
using is assuming an encoding different from the one being used to  
write the file.  You might try explicitly setting the encoding in  
either the text editor or in the logging configuration file.  Setting  
the encoding to "UTF-16" would be a good first option since a two- 
byte encoding is unlikely to be misinterpreted.  Since you were  
interested in Asian characters, then your best single byte option  
would be UTF-8 (since it can represent any character in the Unicode  
character set), however your text editor may need to be explicitly  
told to interpret the file as UTF-8.

On the console, you have another issue coming into play.  Most C RTL  
provide both a byte-oriented console and a wide-character console but  
do not support an application writing to both streams.  log4cxx  
checks fwide() and follows whatever orientation has previously been  
established.  If nothing else has written to the console, then it  
will use fputs() which will mark the console as byte-oriented.  From  
your reports, it appears that your default encoding is not UTF-8  
(likely it is ISO-8859-1, Cp1252 or similar) and so characters that  
can be not represented in your default encoding are rendered as Java- 
style unicode escape sequences.

Your options are:

a) Set the console stream to wide-character orientation by calling  
fwide(stdout, 1) or outputting something using fputws() before  
log4cxx logs anything.  However, if your application writes to the  
console using a byte-oriented call (printf, puts, and the like), then  
output may be garbled or discarded.

b) Compile log4cxx with LOG4CXX_FORCE_WIDE_CONSOLE which will force  
use of wide-character console output.  Again this may interfere with  
any use of byte-oriented writes to the console.

c) Specify your locale to use UTF-8 as its default encoding.

You didn't mention what operating system, editors, etc, that you are  
using which limits the ability for us to give you advice.



Re: Build works + OutputDebugAppender + Unicode

Posted by Curt Arnold <ca...@apache.org>.
On May 30, 2006, at 9:11 AM, Arunkumar wrote:

> Hi guys,
>
> The head revision builds and the dll works for VS.Net 2003. The  
> problem was
> dumb. My application was loading an older log4cxxd.dll from a  
> different path
> (aaargh) and hence the linker and runtime errors popped up as the  
> lib file
> did not match the dll. It's just not your day (or days) sometimes. :)
>
> But now that I have it working I have some issues:
> 1) OutputDebugAppender has a bug. If you do not specify a layout  
> pointer it
> crashes at runtime. The following code WORKS in case someone wants  
> to try
> it.
>
> ------------------------- Working Code  
> -----------------------------------
> log4cxx::LoggerPtr LoggerMain(log4cxx::Logger::getLogger 
> ("LoggingMain"));
>
> log4cxx::LogString logPatStrMain = (log4cxx::logchar*) L"%d [%t] %l  
> %p -
> %m%n";
> 	
> //Create the pattern layout using the string used above
> log4cxx::PatternLayoutPtr PatLayoutMain = new
> log4cxx::PatternLayout(logPatStrMain);
>
> //Add the OutputDebugString Appender to the Main Logger
> log4cxx::nt::OutputDebugStringAppender* pTestODA = new
> log4cxx::nt::OutputDebugStringAppender();
>
> pTestODA->setLayout(PatLayoutMain);
>
> LoggerMain->addAppender(pTestODA);
> ---------------------------------------------------------------------- 
> -----
>
> BUT if you remove pTestODA->setLayout(PatLayoutMain); then you will  
> see that
> the program crashes.
> The cause of the crash is the line layout->format(buf, event, p);  
> in the
> append function located in outputdebugstringappender.cpp.
> If buf is null it crashes.
>
> void OutputDebugStringAppender::append(const spi::LoggingEventPtr&  
> event,
> Pool& p)
> {
>         LogString buf;
>         layout->format(buf, event, p);
> #if LOG4CXX_HAS_WCHAR_T
>         LOG4CXX_ENCODE_WCHAR(wstr, buf);
>         ::OutputDebugStringW(wstr.c_str());
> #else
>         LOG4CXX_ENCODE_CHAR(str, buf);
>         ::OutputDebugStringA(str.c_str());
> #endif
> }
> #endif


Thanks.  It should have checked that layout was non-null.  That check  
is provided for most appenders in WriterAppender, but since  
OutputDebugStringAppender doesn't inherit from that class, it was  
overlooked.


>
>
> 2) Hey Curt / Andreas even after building the dll with - 
> Dhas.wchar_t=1, I
> still see the raw Unicode strings in the console and ?????? in the  
> text
> file. Can you guys point me in the correct direction for testing
> multi-lingual string logging with log4cxx.
>
> Thanks
> Arun
>

There are several unit tests that check whether character encoding is  
working as expected.  I suspect that you are passing the unit tests,  
so the basic encoding framework is working tolerably.

The ???? in the text files suggest that the text editor that you are  
using is assuming an encoding different from the one being used to  
write the file.  You might try explicitly setting the encoding in  
either the text editor or in the logging configuration file.  Setting  
the encoding to "UTF-16" would be a good first option since a two- 
byte encoding is unlikely to be misinterpreted.  Since you were  
interested in Asian characters, then your best single byte option  
would be UTF-8 (since it can represent any character in the Unicode  
character set), however your text editor may need to be explicitly  
told to interpret the file as UTF-8.

On the console, you have another issue coming into play.  Most C RTL  
provide both a byte-oriented console and a wide-character console but  
do not support an application writing to both streams.  log4cxx  
checks fwide() and follows whatever orientation has previously been  
established.  If nothing else has written to the console, then it  
will use fputs() which will mark the console as byte-oriented.  From  
your reports, it appears that your default encoding is not UTF-8  
(likely it is ISO-8859-1, Cp1252 or similar) and so characters that  
can be not represented in your default encoding are rendered as Java- 
style unicode escape sequences.

Your options are:

a) Set the console stream to wide-character orientation by calling  
fwide(stdout, 1) or outputting something using fputws() before  
log4cxx logs anything.  However, if your application writes to the  
console using a byte-oriented call (printf, puts, and the like), then  
output may be garbled or discarded.

b) Compile log4cxx with LOG4CXX_FORCE_WIDE_CONSOLE which will force  
use of wide-character console output.  Again this may interfere with  
any use of byte-oriented writes to the console.

c) Specify your locale to use UTF-8 as its default encoding.

You didn't mention what operating system, editors, etc, that you are  
using which limits the ability for us to give you advice.