On Thu, Nov 06, 2014 at 03:03:18PM +0100, Gustaf Neumann wrote:

> The seemingly same write() operation, which refuses to write to
> the access.log in driver.c works fine when called directly 
> in nslog.c.

> https://bitbucket.org/naviserver/naviserver/commits/4cb76f20a8464fde98ac3147c6184a90442a2808

Wow, weird.  I tried turning your new fix on/off, and confirm the
behavior you see.  Yet as you said, the new code you added to
NsAsyncWrite() is the same as the old/normal code in NsAsyncWrite()!

So what could the difference possibly be?  Since we're not actually
using the async writer thread feature at all, it's even the same
thread calling _write() in both cases.  LogTrace() is in nslog.dll
while NsAsyncWrite() is in libnsd.dll, but I don't see how/why that
could possibly matter.

Microsoft's docs for _write() and _open() don't mention anything
suspicious:

  http://msdn.microsoft.com/en-us/library/1570wh78%28v=vs.100%29.aspx
  http://msdn.microsoft.com/en-us/library/z0kc8e3z%28v=vs.100%29.aspx

WinDbg thinks the source file used for Microsoft's _write() was:
  "f:\dd\vctools\crt_bld\self_x86\crt\src\write.c" 
Naturally I don't have that exact path, but I do have this, which
seems to be the same thing:
  "c:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\crt\src\write.c" 

For binary files, _write() is a reasonably simple wrapper around
WriteFile(), but it's surprisingly complicated for text-mode files.

My access log seems to always be file descriptor 3, so in WinDbg I set
a breakpoint like this:

  bu NsAsyncWrite ".if (fd >= 0n3) {} .else {gc}" 

Naviserver opens its access log in text mode; that's the default, and
by stepping through in WinDbg I do see it enter some of the text-mode
sections in _write_nolock().

As a little experiment, in LogOpen() I added a _O_BINARY flag, so it
opened the access log like this:

    fd = open(logPtr->file, O_APPEND|O_WRONLY|O_CREAT|_O_BINARY, 0644); 

That made no difference to the behavior.  (I did NOT run that under
WinDbg to confirm, but presumably it was in binary mode like I asked.)
So this lost writes bug doesn't seem to depend on text vs. binary
mode, it's the same for both.

So, I have no idea.  The only ways I can imagine to try further to
track this down would be:

1. See if the bug is replicable in a standalone, non-Naviserver C
program.  Maybe with two different DLLs involved.

2. Or, in NsAsyncWrite, do not use _write(), instead call WriteFile()
directly and see what happens.

That sounds like a lot of work though, much more than this really
warrants.  I'm really glad you found a work-around, Gustaf!  I suggest
we just leave it as is, but add some comments about why it's there.

-- 
Andrew Piskorski <a...@piskorski.com>

------------------------------------------------------------------------------
_______________________________________________
naviserver-devel mailing list
naviserver-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/naviserver-devel

Reply via email to