soap call in C++ thread crashes

I am calling a java web service method from shared library(which uses soap calls generated by gsoap tools) in C++ thread.when I run this code
its generating core file.I debug and found its failing at shared library
function 2nd line(lines starts with DocumentumToolPortBindingProxy).
This works fine if i don't call this in threads.
Please check below code and advise how to go about..


shared library function:
int DownloadImgFrmServer(unsigned long lDocID , char **buffer, unsigned long **buflen)
{
struct soap *soap = soap_new1(SOAP_ENC_MTOM);
DocumentumToolPortBindingProxy MyReq(*soap);
:
:
return 0;
}
This snippet does not show enough to tell what the problem is.
Generally: Any modification of a shared resource across threads might cause a problem.
Please find the below code:

============================= calling program in threads===========

void *temp(void *id)
{
int success = 0;
struct soap *soap = soap_new1(SOAP_ENC_MTOM);
DocumentumToolPortBindingProxy MyReq(*soap);
success = DownloadImgFrmServerLib(&MyReq,(unsigned long)id);


printf("\n server success status :%d\n", success);

if(success == 1) {
printf("Failed to retrieve data\n");
soap_destroy((struct soap*)soap); // dealloc C++ data
soap_end((struct soap*)soap); // dealloc data and clean up
soap_done((struct soap*)soap); // detach soap struct
free(soap);
MyReq.destroy();
return 1;
}
soap_destroy((struct soap*)soap); // dealloc C++ data
soap_end((struct soap*)soap); // dealloc data and clean up
soap_done((struct soap*)soap); // detach soap struct
free(soap);
MyReq.destroy();
return NULL;

}

int main()
{
pthread_t thread_id;
int i=0,ret = 0;

printf("\n main started \n");
for(i=1 ; i<=1 ; i++)
{
ret = pthread_create(&thread_id, NULL, temp, (void*)i);
if(ret)
{
printf("error: pthread_create ret: %d\n", ret);
return 1;
}
}

printf("\n After pthread create \n");
// while (i > 0) {
pthread_join(thread_id, NULL);
printf ("thread completion: %d\n", thread_id);
i--;
// };
}


2) Library function:
int DownloadImgFrmServerLib(DocumentumToolPortBindingProxy *MyReq,unsigned long lDocID)
{
char ServiceEp[MAX_PATH_LEN] = "";
char to_string_value[16] ;
char DocID[MAX_PATH_LEN] = "" ;
write_log(" before soap memory intialization \n");
ErrorLog("Documentumlib", ERR_INFO, "%s:%d INFRAIUT code",__FUNCTION__,__LINE__);
write_log(" after soap memory intialization \n");

write_log("sk after soap memory execution call\n");
ErrorLog("Documentumlib", ERR_INFO, "%s:%d INFRAIUT code",__FUNCTION__,__LINE__);
int fd = 0;
ns1__sample_USCOREDownloadTxnImagesResponse Response;
std::string doc_id("");
snprintf(DocID, sizeof(DocID ) -1 ,"%ld", lDocID);
write_log("sk before serviceEp check \n");
ErrorLog("Documentumlib", ERR_INFO, "%s:%d INFRAIUT code",__FUNCTION__,__LINE__);
int fd = 0;
ns1__sample_USCOREDownloadTxnImagesResponse Response;
std::string doc_id("");

snprintf(DocID, sizeof(DocID ) -1 ,"%ld", lDocID);

write_log("sk before serviceEp check \n");
ErrorLog("Documentumlib", ERR_INFO, "%s:%d INFRAIUT code",__FUNCTION__,__LINE__);
sprintf(ServiceEp, "%s", DOCUMENTUMServiceEndPoint);
ErrorLog("Documentumlib", ERR_INFO, "%s:%d INFRAIUT code",__FUNCTION__,__LINE__);
if (strcmp(ServiceEp,"")== NULL)
{
printf("TPAM Service End point not set in OPER_ENVIR.ksh!");
exit(-1);
}
write_log("sk after serviceEp check \n");
printf("%s:%d TPAM Service End :%s\n",__FUNCTION__,__LINE__,ServiceEp);

int Res = MyReq->sample_USCOREDownloadTxnImages(ServiceEp,NULL,DocID,Response); //ServiceEp
ErrorLog("Documentumlib", ERR_INFO, "%s:%d INFRAIUT code, docid: %s",__FUNCTION__,__LINE__,DocID);
write_log("After txn images call check \n");
if (Res != SOAP_OK )
{
return 1;
}


write_log("sk success img tx from server \n");
printf("%s:%d TPAM Service End :%s\n",__FUNCTION__,__LINE__,ServiceEp);
doc_id = *Response.ResultDocumentObject->docID;
write_log("sk success img tx from server \n");

printf("%s:%d TPAM Service End :%s\n",__FUNCTION__,__LINE__,ServiceEp);
ioc_id = *Response.ResultDocumentObject->docID;
printf("%s:%d TPAM Service End :%s\n",__FUNCTION__,__LINE__,ServiceEp);
doc_id = *Response.ResultDocumentObject->docID;

write_log("sk going to write data to file \n");
for (int i = 0; i < Response.ResultDocumentObject->size; i++) {
sprintf(to_string_value,"_%d",i);
string file = doc_id + to_string_value + ".TIF";
fd = open (file.c_str(),O_WRONLY|O_CREAT,0640);
if (fd == -1 )
{
fprintf(stderr, "Unable to open file %s\n", file.c_str());
return 1;
}

write_log("sk going to write data to file \n");
for (int i = 0; i < Response.ResultDocumentObject->size; i++) {
sprintf(to_string_value,"_%d",i);
string file = doc_id + to_string_value + ".TIF";
fd = open (file.c_str(),O_WRONLY|O_CREAT,0640);
if (fd == -1 )
{
fprintf(stderr, "Unable to open file %s\n", file.c_str());
return 1;
}

write_log("sk start writing data to file \n");


if(write(fd,(char*)Response.ResultDocumentObject->fileList[i].__ptr, Response.ResultDocumentObject->fileList[i].__size) <= 0 )
{
fprintf(stderr, "write: failed in writing to file :%s\n", file.c_str());
return 1;
}
write_log("sk completed writing data to file \n");
file.clear();
close(fd);
}

write_log("sk writing done sucess \n");
return 0;
}
You have several duplicated lines. Response is defined twice.

I would suggest that you test pointers (with assert at least) before you use them.

Is the order of soap_destroy -> soap_end -> soap_done correct?

I would suggest to try this code without thread first.
without thread this works fine. I have used new gsoap library. Please find below logs and code

I am getting core with gsoap 2.84 library and different soap_init error with gsoap 2.851 for same code.
Please advise.

ERROR with gsoap 2.84

Segmentation fault in soap_free_pht(soap*) at line 6676 in file "" ($t2)
could not read "stdsoap2_ssl_cpp.cpp"
(/tmp/dbx) where
soap_free_pht(soap*)(soap = 0x3004e430), line 6676 in "stdsoap2_ssl_cpp.cpp"
soap_free_temp(soap = 0x3004e430), line 8207 in "stdsoap2_ssl_cpp.cpp"
soap_begin(soap = 0x3004e430), line 8928 in "stdsoap2_ssl_cpp.cpp"
DOCUMENTUMPOCCLIDocumentumToolPortBindingProxy.DocumentumToolPortBindingProxy::sample_USCOREDownloadTxnImages(const char*,const char*,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,ns1__sample_USCOREDownloadTxnImagesResponse&)(this = 0x3004e430, endpoint = "http://xx.xx.xxx.xx:PPPP/DocumentumPoc?wsdl", soap_action = "", DOC_USCOREID = &(...), _param_2 = &(...)), line 169 in "DOCUMENTUMPOCCLIDocumentumToolPortBindingProxy.cpp"
GetImageDetailsFrmServer(void*)(soap = 0x2ff054a0), line 126 in "DocumentumPoc.cpp"

==============================================================
ERROR with gsoap 2.851
Error: soap struct state not initialized with soap_init

GetImageDetailsFrmServer(void *):130 Test log failed to retrieve data
thread completion: 258
==================================================================================

Here is my main program
int main(int count,char *val[])
{
char szDocID[50] = "";
pthread_t thread_id;
int ret = 0;
char system_path[MAX_PATH_LEN] = "";

if(count <= 1) {
printf("Documentum Binary usage: ./Documentum -d <Doc ID of the file to download the image(s)>\n or\n ./Documentum -u <filename1> <filename2> ... of the files to be uploaded\n");
return 0;
}

int success = 0, i = 0;
int actual_count = count-2;
char files[actual_count][50] ;
memset(files, '\0', actual_count*50);

if (strcmp (val[1],"-d") == 0)
{
printf("downloading..\n");
struct soap soapie;
soap_init(&soapie);
struct soap *tsoap;
tsoap = soap_copy(&soapie);
strcpy(szDocID,val[2]);
success = pthread_create(&thread_id, NULL, GetImageDetailsFrmServer, (void *)&tsoap);
if(success != 0)
{
printf("error: pthread_create failed: %d\n", success);
return 1;
}

printf("\n After pthread create \n");
pthread_join(thread_id, NULL);
printf ("thread completion: %d\n", thread_id);

}
else
printf("Provide either -d arguments\n");


return 0;
}



int GetImageDetailsFrmServer(void *soap)
{
char ServiceEp[MAX_PATH_LEN] = "";
char to_string_value[16] ;
printf("%s:%d Test log\n",__FUNCTION__,__LINE__);
DocumentumToolPortBindingProxy MyReq((struct soap &)soap);
printf("%s:%d Test log\n",__FUNCTION__,__LINE__);
int fd = 0;
ns1__sample_USCOREDownloadTxnImagesResponse Response;
std::string doc_id("");

sprintf((char *)ServiceEp, "%s", getenv("TPAMServiceEndPoint"));
if (strcmp(ServiceEp,"")== 0)
{
printf("%s:%d TPAM Service End point not set in OPER_ENVIR.ksh!\n",__FUNCTION__,__LINE__);
exit(-1);
}

char buf[8] = "2";

printf("%s:%d Test log\n",__FUNCTION__,__LINE__);
int Res = MyReq.sample_USCOREDownloadTxnImages(ServiceEp,NULL,buf,Response); //ServiceEp
if (Res != SOAP_OK )
{
soap_print_fault(&MyReq, stderr);
printf("\n%s:%d Test log failed to retrieve data\n",__FUNCTION__,__LINE__);
MyReq.destroy();

return 1;
}
printf("%s:%d Test log\n",__FUNCTION__,__LINE__);

doc_id = *Response.ResultDocumentObject->docID;

for (int i = 0; i < Response.ResultDocumentObject->size; i++) {
sprintf(to_string_value,"_%d",i);
string file = doc_id + to_string_value + ".TIF";
fd = open (file.c_str(),O_WRONLY|O_CREAT,0640);
if (fd == -1 )
{
fprintf(stderr, "Unable to open file %s\n", file.c_str());
MyReq.destroy();

return 1;
}
if(write(fd,(char*)Response.ResultDocumentObject->fileList[i].__ptr, Response.ResultDocumentObject->fileList[i].__size) <= 0 )
{
fprintf(stderr, "write: failed in writing to file :%s\n", file.c_str());
MyReq.destroy();

return 1;
}
file.clear();
close(fd);
}
MyReq.destroy();
return 0;
}
============================================================
I haven't done much with this library, but it seems that it is a problem that soap_init(...) and/or soap_copy(...) is done within another thread.
Topic archived. No new replies allowed.