[ 
https://issues.apache.org/jira/browse/AXIS2C-884?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12556935#action_12556935
 ] 

wtmitchell3 edited comment on AXIS2C-884 at 1/9/08 1:21 PM:
--------------------------------------------------------------

Upon re-examining the code in op_client.c, I uncovered the 
axis2_options_set_xml_parser_reset, which when set to false allows the 
application to suppress call to xmlCleanupParser on every op_client 
termination.  So someone has obviously figured this all out before.  

I tried disabling parser_reset for all the terminations except the last.  It 
turns out that this can still crash libxml2 in getGlobalState when issued from 
a thread different from the initial thread.  (This is essentially the same as 
the traceback above when the parser cleanup was issued after each operation and 
the parser re-initialized for the next operation.)

        ntdll.dll!7c918fea()    
        [Frames below may be incorrect and/or missing, no symbols loaded for 
ntdll.dll] 
        kernel32.dll!7c80e98b()         
>       msvcr80d.dll!_nh_malloc_dbg(unsigned int nSize=12, int nhFlag=0, int 
> nBlockUse=0, const char * szFileName=0x0000239c, int nLine=40631000)  Line 
> 268 + 0x15 bytes        C++
        msvcr80d.dll!malloc(unsigned int nSize=16744212)  Line 154 + 0x15 bytes 
C++
        libxml2.dll!xmlGetGlobalState()  Line 570       C
        00000001()

I apologize for not figuring this out as a user error early on, but as you can 
see from the traces above, even with debug enabled to see where the failure 
happens, xmlCleanupParser is not where the crash happens, rather the crash 
happens in axis2_libxml2_reader_wrapper_free, or it may appear as a standalone 
crash in xmlGetGlobalState with no calling information available.  

So the suggestion I made above would be a source fix to ensure that users of 
Axis2c don't have this problem at all, but it may spend effort that would be 
better spent making guththila fully functional.  As an alternative simple 
suggestion, comments could be added in reader_wrapper_free to remind the human 
that a crash at that point is likely caused by an earlier call to cleanup 
parser.  As well, a simple use count would allow a reminder message to be 
dropped one time in the axis2.trace when cleanup is called after multiple 
initializations or multiple concurrent initializations; this would likely be in 
the trace near the spot of the failure if the user forgot to turn off 
xml_parser_reset.  

In a true multi-threaded case, the only way for the application to be assured a 
way to cleanup the libxml parser is if new entry points are created so that the 
application can perform the initialization in a persistent thread, and not 
allow the parser initialization to happen in just whichever thread happens to 
first create a stub/svc client.

      was (Author: wtmitchell3):
    Upon re-examining the code in op_client.c, I uncovered the 
axis2_options_set_xml_parser_reset, which when set to false allows the 
application to suppress call to xmlCleanupParser on every op_client 
termination.  So someone has obviously figured this all out before.  I have 
verified that one can set this option back to true on the last termination and 
libxml2 is not upset to be terminating in a different thread than the initial 
"main" thread, even when the main thread no longer exists.  

I apologize for not figuring this out as a user error early on, but as you can 
see from the traces above, even with debug enabled to see where the failure 
happens, xmlCleanupParser is not where the crash happens, rather the crash 
happens in axis2_libxml2_reader_wrapper_free.  

So the suggestion I made above would be a source fix to ensure that users of 
Axis2c don't have this problem at all, but it may spend effort that would be 
better spent making guththila fully functional.  As an alternative simple 
suggestion, comments could be added in reader_wrapper_free to remind the human 
that a crash at that point is likely caused by an earlier call to cleanup 
parser.  As well, a simple use count would allow a reminder message to be 
dropped one time in the axis2.trace when cleanup is called after multiple 
concurrent initializations; this would likely be in the trace near the spot of 
the failure if the user forgot to turn off xml_parser_reset.  
  
> Seg fault in libxml when svc client torn down in a multithreaded client
> -----------------------------------------------------------------------
>
>                 Key: AXIS2C-884
>                 URL: https://issues.apache.org/jira/browse/AXIS2C-884
>             Project: Axis2-C
>          Issue Type: Bug
>          Components: core/deployment
>    Affects Versions: Current (Nightly)
>         Environment: Windows XP, Visual Studio 2005, libxml 2.6.25 and libxml 
> 2.6.30, libcurl
>            Reporter: Bill Mitchell
>         Attachments: axis2.trace, desc_builder_diff.txt
>
>
> In a multithreaded application, if the stub/svc client is freed in a thread 
> different from that used when the svc client was built, libxml crashes.  The 
> trace below shows the information available from a release build with debug 
> information embedded.  
> I have verified this is not an effect of combining debug and release C 
> runtimes, or different versions of the C runtime.  Rebuilding all the libxml 
> related dlls with the same runtime as is used for Axis and the client app 
> does not solve the problem.  
> Interestingly, rebuilding libxml with threads disabled does make the crash go 
> away.  But the default build of libxml commonly available has native threads 
> enabled, and building without thread support may make the library not thread 
> safe.  
> By adding debug trace statements in the axis2.trace file, I have verified 
> that the xml_reader being torn down when the crash happens is the one used to 
> read the axis2.xml file when the configuration was first read.  (axis2.trace 
> file attached.)
> Looking at the code in libxml, it appears that libxml decides to close the 
> reader using an internal close routine intended for closing compressed 
> channels through zlib.  Apparently the C runtime library returns a -1 EOF 
> status when closing a file opened for read.  The close routine, gzio.c in 
> zlib, treats this as an error, and when libxml attempts to report the error 
> and determines that it is in a different thread, things really go downhill 
> fast.  I have not isolated why the EnterCriticalSection call crashes in the 
> system, but it does.  
> One way to avoid the problem would be to guarantee that the stub/svc client 
> is freed in the same thread as created it.  In my multithreaded client 
> application, though, I work hard to share the stub across threads 
> deliberately to reduce the number of distinct service clients and the 
> associated demand on the server.  
> Windows call traceback at time of crash:
>       ntdll.dll!7c918fea()    
>       [Frames below may be incorrect and/or missing, no symbols loaded for 
> ntdll.dll] 
>       msvcr80.dll!78134d09()  
>       ntdll.dll!7c910e91()    
>       ntdll.dll!7c9106eb()    
>       msvcr80.dll!78134d83()  
>       ntdll.dll!7c90104b()    
> >     libxml2.dll!xmlGetGlobalState()  Line 570       C
>       libxml2.dll!__xmlLastError()  Line 709 + 0x5 bytes      C
>       libxml2.dll!__xmlRaiseError(void (void *, _xmlError *)* 
> schannel=0x00000000, void (void *, const char *, <no type>)* 
> channel=0x00000000, void * data=0x00000000, void * ctx=0x00000000, void * 
> nod=0x00000000, int domain=8, int code=0, xmlErrorLevel level=XML_ERR_ERROR, 
> const char * file=0x00000000, int line=0, const char * str1=0x00c5d420, const 
> char * str2=0x00000000, const char * str3=0x00000000, int int1=0, int col=0, 
> const char * msg=0x00c5d360, ...)  Line 452 + 0x5 bytes  C
>       libxml2.dll!__xmlSimpleError(int domain=8, int code=0, _xmlNode * 
> node=0x00000000, const char * msg=0x00c5d360, const char * extra=0x00c5d420)  
> Line 657 + 0x2d bytes   C
>       libxml2.dll!__xmlIOErr(int domain=8, int code=0, const char * 
> extra=0x00c5d420)  Line 417 + 0x1a bytes  C
>       libxml2.dll!xmlGzfileClose(void * context=0x03301f80)  Line 1155 + 0x10 
> bytes   C
>       libxml2.dll!xmlFreeParserInputBuffer(_xmlParserInputBuffer * 
> in=0x03304578)  Line 2207 + 0x5 bytes      C
>       libxml2.dll!xmlTextReaderClose(_xmlTextReader * reader=0x03304760)  
> Line 2244 + 0x6 bytes       C
>       axis2_parser.dll!axis2_libxml2_reader_wrapper_free(axiom_xml_reader * 
> parser=0x03301e00, const axutil_env * env=0x031aa150)  Line 510   C
>       axiom.dll!axiom_stax_builder_free(axiom_stax_builder * 
> om_builder=0x03271aa8, const axutil_env * env=0x031aa150)  Line 886      C
>       axis2_engine.dll!axis2_desc_builder_free(axis2_desc_builder * 
> desc_builder=0x03301d58, const axutil_env * env=0x031aa150)  Line 141     C
>       axis2_engine.dll!axis2_conf_builder_free(axis2_conf_builder * 
> conf_builder=0x03301d70, const axutil_env * env=0x031aa150)  Line 128     C
>       axis2_engine.dll!axis2_dep_engine_free(axis2_dep_engine * 
> dep_engine=0x031aa2e8, const axutil_env * env=0x031aa150)  Line 380   C
>       axis2_engine.dll!axis2_conf_free(axis2_conf * conf=0x0330cad8, const 
> axutil_env * env=0x031aa150)  Line 328     C
>       axis2_engine.dll!axis2_conf_ctx_free(axis2_conf_ctx * 
> conf_ctx=0x00000000, const axutil_env * env=0x031aa150)  Line 439 C
>       axis2_engine.dll!axis2_svc_client_free(axis2_svc_client * 
> svc_client=0x031aa1a8, const axutil_env * env=0x031aa150)  Line 1303  C
>       axis2_engine.dll!axis2_stub_free(axis2_stub * stub=0x031aa198, const 
> axutil_env * env=0x031aa150)  Line 131     C

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to