Hi, I don't understand what's going on inside the Axis2/C client. My test client crashes. I looked at the Axis source code and did some debugging (mostly, I've added a lots of AXIS2_LOG_DEBUG(...) to the Axis source code and recompiled - I have a fast enough computer, and this way you can receive repeating results, something that hard to get with a debugger), and run a client code with valgrind.
I think there might be some mix up in the the axis2_op_client_add_msg_ctx() function, which causes the memory that is not supposed to be freed by the Axis library (specifically, the payload data that is allocated by the client application before it calls the axis2_svc_client_send_receive()). Then, when the axis2_svc_client_send_receive() returns to my client code, the client tries to free the payload it allocated, at which moment the client crashes - either silently, or with the glibc reporting "double free or corruption". Now that I've got your attention, here are the details (sorry, this is a long message): First, I'm using Ubuntu 7.10, and I downloaded and compiled sources of Axis2/C 1.3.0. I compiled a SOAP service - virtually unchanged code of the example from the user guide, but the service looks to be OK, there is a problem with the client. I compiled a SOAP client - absolutely unchanged code of the client from the user guide (http://ws.apache.org/axis2/c/docs/hello/client/hello.c.html). When I'm starting the Axis server (for example, stand-alone axis2_http_server application), the client works OK, it sends something to the service and receives some response. No crashes. But if I start the client application _without_ starting a server (that is, I expect some kind of timeout or some error about inability to conect to the server), the client application crashes. Here is what I found: The axis2_svc_client_send_receive() calls axis2_svc_client_send_receive_with_op_qname() function that implements the sending and receiving of the SOAP messages. If there is an error in the low-level sending/receiving of the messages (which really happens in my case, because I did not start the SOAP server for this test), the res_msg_ctx variable will be NULL, and in the conditional statement in the lines 864-872 of the file axis2_svc_client.c is executed the 'else' alternative, which calls the axis2_op_client_add_msg_ctx() function, passing the res_msg_ctx value (which is NULL) to it. In the axis2_op_client_add_msg_ctx() function, right before the 'if' statement in the lines 274-296 (file axis_op_client.c): if (out_msg_ctx && !mc) value of the out_msg_ctx is not NULL, and value of the mc is not NULL (I checked this using the debug logging), so the body of this statement is executed. In this body, right before the 'if' statement on the line 290: if (axutil_strcmp(dump_value, AXIS2_VALUE_TRUE)) the value of the dump_value is NULL (again checked by the debug logging), and the axutil_strcmp() returns -1 (which is interpreted as a 'true' boolean value), and thus the body of the statement, including the call (line 292) axis2_msg_ctx_free(out_msg_ctx, env); is executed. The out_msg_ctx here points to the same message context object that was created in the axis2_svc_client_send_receive_with_op_qname() function, before sending the SOAP request - I saw using the debug logging that the pointer value returned by the axis2_msg_ctx_create() call in the axis2_svc_client_send_receive_with_op_qname() (line 834) is the same as the value of the pointer out_msg_ctx here. But this message context object contains a soap_envelop object that, in turn, contains the payload object (tree of the object model nodes) that my client application allocated before calling the axis2_svc_client_send_receive() (specifically, this soap_envelop is filled with the payload in the call axis2_svc_client_fill_soap_envelope() (line 838, function axis2_svc_client_send_receive_with_op_qname(), file axis2_svc_client.c). So, returning back to the the axis2_op_client_add_msg_ctx() function, this payload object (tree) gets freed here. Then, later, when my client application tries to free the payload object after the axis2_svc_client_send_receive() returns to it, the application crashes, because this memory is already freed. So, finally, my questions: What strategy the client application that calls axis2_svc_client_send_receive() should use regarding allocating/freeing memory? From the current implementation of Axis2/C, it looks like a) if the response was received successfully, the client application should free the payload, but b) if there was a communication error, the Axis library will free the payload itself. Is this correct? Is this a 'by design' feature of the Axis2/C or is this a bug and (in theory) there should be more sane rules regarding memory control? (And, is there somewhere published the memory management rules for the Axis2/C?) Second thing I've noticed when browsing the code of the axis2_svc_client_send_receive_with_op_qname() is something that looks suspiciously as a potential memory leak. Look at the line 838 of fileaxis2_svc_client.c. Here a message context object is created (by calling the axis2_msg_ctx_create(), wich allocates a memory for the message control object (using an allocator from the environment, which is normally malloc()?). Notice that the pointer to the allocated message context object is stored in the _local_ variable msg_ctx. After this follows an 'if' statement (lines 838-842) that calls axis2_svc_client_fill_soap_envelope() and if the result is 'false', it executes 'return NULL'. The axis2_svc_client_fill_soap_envelope() could return a wrong result for different reasons, for example, just because the 'soap_version_uri' is not set in the client options (line 407, file svc_client.c) - basically, I did not see any guarantee that this function will not return 'false' if the message context object was successfully allocated. So, if the axis2_svc_client_fill_soap_envelope() returns 'false', the 'if' statement on lines 838-842 just returns NULL, and the axis2_svc_client_send_receive_with_op_qname() exits, without freeing the memory allocated for the mesasge context object. Because the pointer to this memory was stored in the local variable msg_ctx, this memory is lost. (Or, at least I think it is lost - I might be wrong and there is far more complex processing here to prevent memory leaks that I did not recognize :) ) Thank you, alex. --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]