On Fri, 2010-07-09 at 13:26 +0200, Akos Marton wrote: > You had better send the corresponding code of the certain stack-trace. > -can be interesting.
This is a bit more complicated because the code lives in multiple source files ... Initially I was rather thinking about "how is it supposed to work"? Anyway, here is something like an "aggregated source code": // My "business logic" which is a non-static C++ method of an C++ // object: axiom_node_t * SoapSrv::invokeFunc(const axutil_env_t * env, axiom_node_t * node) { if(axiom_node_get_node_type(node, env) == AXIOM_ELEMENT) { axiom_element_t * element = (axiom_element_t *) axiom_node_get_data_element(node, env); if(element != NULL) { axis2_char_t * op_name = axiom_element_get_localname(element, env); if(op_name == NULL) { // no server function ... log error return NULL; } axiom_node_t * respNode = NULL; DataObjectPtr req = dataObjFromAxiom(node); DataObjectPtr resp = ... do something(op_name, req); respNode = dataObjToAxiom(resp); if(respNode == NULL) { // log error } return respNode; } } return NULL; } // To call the non-static method above I have wrapped this in // a separate static function, which is registered with the server // skeleton: extern "C" axiom_node_t * AXIS2_CALL soapSrvInvoke( axis2_svc_skeleton_t * skel, const axutil_env_t * env, axiom_node_t * node, axis2_msg_ctx_t * msg_ctx) { return SoapSrv::getInstance()->invoke(skel, env, node, msg_ctx); } // and (this is actually not needed anymore but should not hurt): axiom_node_t * SoapSrv::invoke(axis2_svc_skeleton_t * svc_skeleton, const axutil_env_t * env, axiom_node_t * node, axis2_msg_ctx_t * msg_ctx) { return SoapSrv::getInstance()->invokeFunc(env, node); } // The axiom to SDO conversion: axiom_node_t * Soap::dataObjToAxiom(DataObjectPtr o) { if(m_ax == NULL) { m_ax = AxiomHelper::getHelper(getEnv()); } axiom_document_t * doc = m_ax->toAxiomDoc(o); axiom_node_t * ret = (doc == NULL) ? NULL : axiom_document_get_root_element(doc, m_ax->getEnv()); return ret; } DataObjectPtr Soap::dataObjFromAxiom(axiom_node_t * n) { if(m_ax == NULL) { m_ax = AxiomHelper::getHelper(getEnv()); } return m_ax->toSdo(n, m_mdg); } Finally, the SDO AxiomHelper is attached. Many thx!! tge > > On Fri, Jul 9, 2010 at 1:02 PM, Thomas Gentsch <t...@e-tge.de> wrote: > > > > Hi all, > > > > I encountered a problem which I'm not sure how to handle - whether it is > > my own fault because I did something wrong? > > > > I have a Axis2c server, which generally works nicely. The actual service > > deals with Tuscany SDO objects, so I transform the Axiom objects to/from > > SDOs when processing a request (this is actually a detail which should > > not matter as the question is more general): > > > > In my service, I have something like this (following the example here: > > http://www.dimuthu.org/blog/2008/10/02/understanding-apache-axis2c-services) > > > >> Service logic > >> Just create a function with the following format. > >> axiom_node_t *axis2_echo_echo( > >> const axutil_env_t * env, > >> axiom_node_t * input_node) { > >> > >> /* Write your business logic Right Here */ > >> } > >> Here you extract out the input parameters from the the input_node and > >> build the return node based on your output parameters. (Note that even > >> though this is an echo example you can’t return the same input node as > >> the output node, instead you have to replicate the input node and > >> return it to avoid the double freeing) > > > > So I create a returned axiom_node_t but eventually end up with a memory > > leak: > > ------------------ > > ==3461== 20,164 (40 direct, 20,124 indirect) bytes in 1 blocks are > > definitely lost in loss record 975 of 980 > > ==3461== at 0x4025C1C: malloc (vg_replace_malloc.c:195) > > ==3461== by 0x47C1CFC: axutil_allocator_malloc_impl (allocator.c:75) > > ==3461== by 0x47A2E1C: axiom_stax_builder_create > > (om_stax_builder.c:70) > > ==3461== by 0x4712A66: > > commonj::sdo_axiom::AxiomHelper::toAxiomDoc(commonj::sdo::RefCountingPointer<commonj::sdo::DataObject>, > > char const*, char const*) (sdo_axiom.cpp:146) > > ==3461== by 0x4438CB8: > > dataObjToAxiom(commonj::sdo::RefCountingPointer<commonj::sdo::DataObject>) > > (in /opt/bes/itm/modules/libimsoap.so) > > ==3461== by 0x4439839: invokeFunc(axutil_env const*, axiom_node*) > > (im_soapsrv.cpp:160) > > ==3461== by 0x4439396: invoke(axis2_svc_skeleton*, axutil_env const*, > > axiom_node*, axis2_msg_ctx*) (im_soapsrv.cpp:79) > > ==3461== by 0x4C31C8D: soapSrvInvoke (im_soapsrvax.cpp:37) > > ==3461== by 0x474B0D6: > > axis2_raw_xml_in_out_msg_recv_invoke_business_logic_sync > > (raw_xml_in_out_msg_recv.c:209) > > ==3461== by 0x474A433: axis2_msg_recv_invoke_business_logic > > (msg_recv.c:481) > > ==3461== by 0x474AB34: axis2_msg_recv_receive_impl (msg_recv.c:403) > > ==3461== by 0x474A4B3: axis2_msg_recv_receive (msg_recv.c:520) > > ------------------ > > > > Who is going to free the axiom_node_t I return? In theory this must > > happen inside of Axis2c when serializing the data to the network, right? > > So, there is actually nothing I can do? > > Under which circumstances might this not be done? > > Am I possibly doing something wrong? > > > > > > Secondly, how is it supposed to work the other way around? In my > > service, I receive an axiom node, transform it to a SDO etc. > > Who is in charge of freeing the original axiom_node_t? > > I don't do it in my code, so the result is another memory leak: > > > > ----------------------- > > ==3461== 8,737 (56 direct, 8,681 indirect) bytes in 1 blocks are > > definitely lost in loss record 970 of 980 > > ==3461== at 0x4025C1C: malloc (vg_replace_malloc.c:195) > > ==3461== by 0x47C1CFC: axutil_allocator_malloc_impl (allocator.c:75) > > ==3461== by 0x47A022B: axiom_output_create (om_output.c:79) > > ==3461== by 0x4712381: > > commonj::sdo_axiom::AxiomHelper::toSdo(axiom_node*, > > commonj::sdo::RefCountingPointer<commonj::sdo::DataFactory>, char > > const*) (sdo_axiom.cpp:214) > > ==3461== by 0x4438D9F: dataObjFromAxiom(axiom_node*) > > (in /opt/bes/itm/modules/libimsoap.so) > > ==3461== by 0x44397C0: invokeFunc(axutil_env const*, axiom_node*) > > (im_soapsrv.cpp:152) > > ==3461== by 0x4439396: invoke(axis2_svc_skeleton*, axutil_env const*, > > axiom_node*, axis2_msg_ctx*) (im_soapsrv.cpp:79) > > ==3461== by 0x4C31C8D: soapSrvInvoke (im_soapsrvax.cpp:37) > > ==3461== by 0x474B0D6: > > axis2_raw_xml_in_out_msg_recv_invoke_business_logic_sync > > (raw_xml_in_out_msg_recv.c:209) > > ==3461== by 0x474A433: axis2_msg_recv_invoke_business_logic > > (msg_recv.c:481) > > ==3461== by 0x474AB34: axis2_msg_recv_receive_impl (msg_recv.c:403) > > ==3461== by 0x474A4B3: axis2_msg_recv_receive (msg_recv.c:520) > > ----------------------- > > > > Any hints are greatly appreciated!! > > > > Many thx + regards, > > tge > > > > > > --------------------------------------------------------------------- > > To unsubscribe, e-mail: c-user-unsubscr...@axis.apache.org > > For additional commands, e-mail: c-user-h...@axis.apache.org > > > > > > >
/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* $Rev: 498972 $ $Date: 2007-01-23 10:06:47 +0000 (Tue, 23 Jan 2007) $ */ #if defined(WIN32) || defined (_WINDOWS) #pragma warning(disable: 4786) #endif #include "sdo_axiom.h" using namespace commonj::sdo; using namespace std; namespace commonj { namespace sdo_axiom { int AxiomHelper::axiswritercount = 0; AxiomHelper* AxiomHelper::getHelper(axutil_env_t * env) { return new AxiomHelper(env); } void AxiomHelper::releaseHelper(AxiomHelper* h) { if (h) delete h; } void AxiomHelper::deleteEnv() { if (the_env && (! privateEnv)) axutil_env_free(the_env); } void AxiomHelper::createEnv() { the_env = axutil_env_create_all("tuscany_sdo_axiom.log",AXIS2_LOG_LEVEL_WARNING); if (the_env == 0) return; return; } AxiomHelper::AxiomHelper(axutil_env_t * env) : the_env(env), privateEnv(false) { if(the_env == 0) { privateEnv = true; createEnv(); } } AxiomHelper::~AxiomHelper() { deleteEnv(); } axutil_env_t* AxiomHelper::getEnv() { return the_env; } axiom_node_t* AxiomHelper::toAxiomNode(DataObjectPtr dob, const char* targetNamespaceURI, const char* elementName) { axiom_document_t* doc = toAxiomDoc(dob, targetNamespaceURI, elementName); if (!doc) { return 0; } axiom_node_t* root_node = axiom_document_get_root_element(doc, the_env); if (!root_node) { cout << "No Root Element in the document" << endl; return 0; } return root_node; } axiom_document_t* AxiomHelper::toAxiomDoc(DataObjectPtr dob, const char* targetNamespaceURI, const char* elementName) { DataFactoryPtr df = dob->getDataFactory(); XSDHelperPtr xs = HelperProvider::getXSDHelper(df); XMLHelperPtr xm = HelperProvider::getXMLHelper(df); if (!the_env) { cout << "No Axis Environment" << endl; return 0; } XMLDocumentPtr doc = xm->createDocument( dob, targetNamespaceURI, elementName); char * str = xm->save(doc); //if (str) { // cout << "toAxiomDoc " << str << endl; //} axiom_xml_reader_t * reader = axiom_xml_reader_create_for_memory(the_env, (void*)str, strlen(str), (const axis2_char_t *)"UTF-8", AXIS2_XML_PARSER_TYPE_BUFFER); if (!reader) { cout << "No Axis Reader" << endl; return 0; } axiom_stax_builder_t* builder = axiom_stax_builder_create(the_env, reader); if (!builder) { cout << "No Axis Builder" << endl; axiom_xml_reader_free(reader, the_env); return 0; } axiom_document_t* document = axiom_stax_builder_get_document(builder, the_env); if (!document) { cout << "No Axis Document" << endl; axiom_stax_builder_free(builder, the_env); return 0; } axiom_node_t* root_node = axiom_document_get_root_element(document, the_env); if (!root_node) { cout << "No Root Element in the document" << endl; axiom_stax_builder_free(builder, the_env); return 0; } axiom_document_build_all(document, the_env); return document; } DataObjectPtr AxiomHelper::toSdo(axiom_document_t* document, DataFactoryPtr factory, const char* targetNamespaceURI) { if (!the_env) { cout << "No Axis Environment" << endl; return 0; } axiom_node_t* root_node = axiom_document_get_root_element(document, the_env); return toSdo(root_node,factory, targetNamespaceURI); } DataObjectPtr AxiomHelper::toSdo(axiom_node_t* root_node, DataFactoryPtr factory, const char* targetNamespaceURI) { if (!the_env) { cout << "No Axis Environment" << endl; return 0; } XMLHelperPtr helper = HelperProvider::getXMLHelper(factory); axiom_xml_writer_t* writer = axiom_xml_writer_create_for_memory( the_env, NULL, AXIS2_TRUE, 0, AXIS2_XML_PARSER_TYPE_BUFFER); axiom_output_t* output = axiom_output_create(the_env, writer); if (!root_node) { cout << "No Root Element in the document" << endl; axiom_output_free(output, the_env); return 0; } axiom_node_serialize(root_node, the_env, output); axis2_char_t* buffer = (axis2_char_t*)axiom_xml_writer_get_xml(writer, the_env); // cout << "toSDO: '" << buffer << "'" << endl; XMLDocumentPtr theXMLDocument = helper->load(buffer, targetNamespaceURI); if (theXMLDocument != 0) { return theXMLDocument->getRootDataObject(); } cout << "The XML document returned from load was zero" << endl; return 0; } void AxiomHelper::output(axiom_document_t* document) { if (!the_env) { cout << "No Axis Environment" << endl; return; } axiom_xml_writer_t* writer = axiom_xml_writer_create_for_memory( the_env, NULL, AXIS2_TRUE, 0, AXIS2_XML_PARSER_TYPE_BUFFER); axiom_output_t* output = axiom_output_create(the_env, writer); axiom_node_t* root_node = axiom_document_get_root_element(document, the_env); if (!root_node) { cout << "No Root Element in the document" << endl; axiom_output_free(output, the_env); return; } axiom_node_serialize(root_node, the_env, output); axis2_char_t* buffer = (axis2_char_t*)axiom_xml_writer_get_xml(writer, the_env); printf("Output XML:n %s ", buffer); axiom_output_free(output, the_env); return; } } }
--------------------------------------------------------------------- To unsubscribe, e-mail: c-user-unsubscr...@axis.apache.org For additional commands, e-mail: c-user-h...@axis.apache.org