Bug #35916 logging to stderr in a UDF does not work if MySQL is run as service

Submitted: 8 Apr 2008 22:58 Modified: 21 Oct 2009 6:51
Reporter: Roland Bouman Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: User-defined functions ( UDF ) Severity:S2 (Serious)
Version:5.1.23 OS:Windows (xp pro)
Assigned to: CPU Architecture:Any

[8 Apr 2008 22:58] Roland Bouman
Description:
When writing to stderr when inside a UDF the line should appear in the mysql error log (file pointed to by log_error server variable)

When starting mysqld from the commandline, this works. It does not work when MySQL is run as a windows service.

How to repeat:
compile attached source file using this line:

cl udf_lightspeed_sequence.c /link /dll /out:udf_lightspeed_sequence.dll

(or with MS VC++)

put it i the plugin dir and create the function:

CREATE FUNCTION lightspeed RETURNS INTEGER SONAME 'udf_lightspeed_sequence.dll';

SELECT lightspeed()

this logs 3 lines in the error log when mysql is ran from the command line. However, if mysql is stopped and ran as service, the logging does not take place

Suggested fix:
please log even when running as service
[8 Apr 2008 22:59] Roland Bouman
UDF

Attachment: udf_lightspeed_sequence.c (text/x-csrc), 462 bytes.

[8 Apr 2008 23:13] Vladislav Vaintroub
Verified as described. Additionally, to get debug info, one may compile
with /Zi /MTd.

Partial Workaround: don't use stdout/stderr in UDF directly, fopen the .err file with "a+".
[10 Apr 2008 20:50] Roland Bouman
I would like to add that I don't really see the workaround working.

A proposed workaround would be to have the UDF open a file (possibly the error log) itself. However this can never be a serious alternative in a production environment - first of all it would put a tremendous burden on system administrators in purging all those logs, second it would complicate the UDF implementors job of writing production level UDFs. 

I gathered from Vladislav that stderr/stdout is not really supposed to work at all when running a windows service - but in that case, I am wonder what that would mean for all other occurrences of fprintf(stderr,...) in the mysql source code.
[20 Jun 2008 7:45] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/48217

2672 Alexey Botchkov	2008-06-20
      Bug#35916 logging to stderr in a UDF does not work if MySQL runs as a service.
      
      When MySQL works as a service on Windows fprintf(stderr,..) doesn't work in dll.
      Besides writing to the errlog with the plain fprintf(stderr, ) doesn't work well - we
      need to provide sql_print_error function somehow.
      So this function is provided by calling setup_log_function() from the udf's library.
[18 Aug 2008 13:20] Alexey Botchkov
This problem is addressed by WL#2940
[4 Nov 2008 16:23] Sergei Golubchik
It's expected behavior.
windows services cannot write to stdout/stderr. So, if your UDF is loaded in the server which is run as a service, it'll be subject to the same limitation.
[14 Oct 2009 7:36] Sergei Golubchik
clarification: windows service don't get a console,
but if stdout/stderr are redirected to a file, they should work.

MySQL does redirect stderr to a file, but (according to Vlad) because file handles and streams are implemented in C runtime and mysqld.exe is linked with it statically, UDF gets its own copy of C runtime, and its own stderr.

This is something we could fix, I think.
[14 Oct 2009 9:34] Vladislav Vaintroub
The actual problem is that server and UDF are using different C runtime libraries . Server is linked with static C runtime, and this means UDF necessarily uses another C runtime. Posix file descriptors are specific to C runtime and not shared between the mysqld executable and UDF's DLL.

If server redirects its stderr to a file, UDF's C runtime would not know this.

Still, the logging to stderr should be possible with the some mix of Windows API and C runtime functionality like below.

void use_server_stderr()
{
  int server_out_fd = _open_osfhandle((intptr_t)GetStdHandle (STD_ERROR_HANDLE),0);
dup2(server_out_fd, fileno(stderr));
}

This code retrieves Windows STD_ERROR HANDLE (which is correctly set when server did freopen()), creates a C-runtime file descriptor from this HANDLE and makes stderr use this descriptor.
[21 Oct 2009 6:51] Roland Bouman
Hi all,

just want to say, I don't understand why this was triaged as a feature request. If I understand Vladislav's comments correctly, it seems to me that the is a bug in the way the error file was opened under windows.
[26 Jul 2010 8:17] Roel Van de Paar
Any updates on this?

Portions of this website are copyright © 2001, 2002 The PHP Group

Page generated in 0.071 sec. using MySQL 8.4.7-u6-cloud

Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the respective copyright holders.
It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.