Re: Invalid Address specified to RtlFreeHeap( 00870000, 008A1E90 ) on using FreeInternalIdList
Sure, post the whole function or send it to me privately if you like. I'll take a look. What compiler are you using (VS 6, .NET 2003, etc.), which C Run-time are you linking with (e.g. static vs dll, release vs debug), and which version of the Remedy API are you linking with? It's probably best to link to the release mode multi-threaded DLL and use Visual Studio 6 if possible, as that's probably what the AR API libraries were built with. (I've also used Visual Studio .NET 2003, and while it has a different run-time, it seems to be okay using the release mode multi-threaded DLL option). Dan From: Action Request System discussion list(ARSList) on behalf of Angus Comber Sent: Mon 7/17/2006 4:24 PM To: arslist@ARSLIST.ORG Subject: Re: Invalid Address specified to RtlFreeHeap( 0087, 008A1E90 ) on using FreeInternalIdList I agree with your points below. But this is just test code - agree not much error checking going on. It is just used against a new form I created. I am only checking against the Submitter field (ID 2) and the Assigned To field (ID 4). ARGetEntry returns zero - ie ok. Length of field values is 4 - ie 2 and 4! Made a string buffer of size 100 to copy the field values. But same error. Compiled and testing on Windows platform. (Windows XP). Would it be helpful to show the whole function - it is fairly small. Angus - Original Message - From: Dan Hardy [EMAIL PROTECTED] Newsgroups: public.remedy.arsystem.general To: arslist@ARSLIST.ORG Sent: Monday, July 17, 2006 11:46 PM Subject: Re: Invalid Address specified to RtlFreeHeap( 0087, 008A1E90 ) on using FreeInternalIdList Which platform are you on? It could be caused by: 1) Different structure byte-alignment options at compile time (I've found the default setting works on Windows, on Linux you need a special -malign switch with gcc at least). I can look it up if you need it. 2) It doesn't look you are checking the return code from the API call, checking whether the returned value list has at least 2 items, that either of the values is of type AR_DATA_TYPE_CHAR, or that the pointer is not NULL. You also are copying the data using strcpy, without checking the length, rather than using strncpy or allocating a buffer of large enough size. This could cause corruption (buffer overflow) and easily explain the error, particularly if szField1 and szField2 are stack variables. 3) Different run-time library version between your code and the AR System library (you're calling malloc, it's calling free - could be mismatched) If you are on Windows, I put my money on #2 - sounds like stack corruption. I would point out that if you used the rtl library much of this would be done for you, and you wouldn't have to worry about allocating or freeing any memory, testing for null pointers, checking return codes for error conditions, etc. ;) Dan -Original Message- From: Action Request System discussion list(ARSList) [mailto:[EMAIL PROTECTED] On Behalf Of Angus Comber Sent: Monday, July 17, 2006 3:11 PM To: arslist@ARSLIST.ORG Subject: Invalid Address specified to RtlFreeHeap( 0087, 008A1E90 ) on using FreeInternalIdList Hello I am doing this with ARGetEntry: ARInternalIdList idlist; idlist.numItems = 2; // need two fields idlist.internalIdList = (ARInternalId *) malloc(sizeof(ARInternalId) * idlist.numItems); idlist.internalIdList[0] = fieldID1; // eg 2 - Submitter idlist.internalIdList[1] = fieldID2; // eg 4 - Assigned To ret=ARGetEntry(m_ARctrlstruct, szFormName, entry.entryList[i].entryId, idlist, fldval, m_StatusList); strcpy(szField1, fldval.fieldValueList[0].value.u.charVal); // copy field data strcpy(szField2, fldval.fieldValueList[1].value.u.charVal); Then I get Invalid address specified to RtlFreeHeap when I call: FreeARInternalIdList(idlist, FALSE); What am I doing wrong? Angus ___ UNSUBSCRIBE or access ARSlist Archives at http://www.wwrug.org http://www.wwrug.org/ ___ UNSUBSCRIBE or access ARSlist Archives at http://www.wwrug.org http://www.wwrug.org/ ___ UNSUBSCRIBE or access ARSlist Archives at http://www.wwrug.org http://www.wwrug.org/ ___ UNSUBSCRIBE or access ARSlist Archives at http://www.wwrug.org
Re: Invalid Address specified to RtlFreeHeap( 00870000, 008A1E90 ) on using FreeInternalIdList
Thanks for your help. I am using Visual C++ version 6. Not interested in getting into the MS .NET nonsense. Ah just changed to link to the release mode multi-threaded DLL - and now don't get problem. What is going on here to cause the crash? Anyway, for what it's worth here is the function below function here: // Eg szFormName = [in] MyNewForm // Eg szSearchQual = [in] 'MyNewField' = 07768385144 OR 'Field2' = 07768385144 OR 'Field3' = 07768385144 // Eg szFieldID1 - [out] string from field1 // Eg szFieldID2 - [out] string from field2 // Eg fieldID1 - [in] fieldid to get data // Eg fieldID2 - [in] fieldid to get data long CRemedy::Find2Fields(char* szFormName, char* szSearchQual, char* szFieldID1, char* szFieldID2, long fieldID1, long fieldID2) { ARQualifierStruct qualstruct; AREntryListList entry; unsigned int matches = 0; ARInternalIdList idlist; ARFieldValueList fldval; // Loads specified qualification string int ret = ARLoadARQualifierStruct(m_ARctrlstruct, szFormName, NULL, szSearchQual, qualstruct, m_StatusList); if(ret == 0) { // retrieves list of forms on server - we specify form we are interested in here ret = ARGetListEntry(m_ARctrlstruct, szFormName, qualstruct, NULL, NULL, NULL, AR_NO_MAX_LIST_RETRIEVE, entry, matches, m_StatusList); if(ret == 0) { // printf(matches: %d\n, matches); if(matches 0) { for(int i=0; i (int)matches; i++) { // printf(Entry: %s\n, entry.entryList[i].entryId.entryIdList[0]); idlist.numItems = 2; // need two fields idlist.internalIdList = (ARInternalId*)malloc(sizeof(ARInternalId) * idlist.numItems); idlist.internalIdList[0] = fieldID1; idlist.internalIdList[1] = fieldID2; ret=ARGetEntry(m_ARctrlstruct, szFormName, entry.entryList[i].entryId, idlist, fldval, m_StatusList); // can specify NULL for idlist to retrieve ALL fields if (ret == 0) { // fldval.fieldValueList-value.u.charVal is field1 data // fldval.fieldValueList[1].fieldId is fieldid of that field strncpy(szFieldID1, fldval.fieldValueList[0].value.u.charVal, 100); strncpy(szFieldID2, fldval.fieldValueList[1].value.u.charVal, 100); } else { if (m_StatusList.numItems 0) strcpy(m_strLastErrorMsg, m_StatusList.statusList-messageText); } } } // else // { // printf(no matches\n); // } } // else // { // printf(getlistentry failed\n); // } } // else // { // printf(load qual failed\n); // } // FALSE if declared as stack level variable, TRUE for alloc'd mem for struct FreeARQualifierStruct(qualstruct, FALSE); FreeAREntryListList(entry, FALSE); FreeARInternalIdList(idlist, FALSE); FreeARFieldValueList(fldval, FALSE); FreeARStatusList(m_StatusList, FALSE); // freeStruct - A flag indicating whether you need to free the top-level structure. If you // allocated memory for the top-level structure, specify 1 (TRUE) to free both // the structure and its contents. If you used a stack variable for the top-level // structure, specify 0 (FALSE) to free only the contents of the structure. if (matches 1) return -1; return 0; } - Original Message - From: Dan Hardy [EMAIL PROTECTED] Newsgroups: public.remedy.arsystem.general To: arslist@ARSLIST.ORG Sent: Tuesday, July 18, 2006 6:59 AM Subject: Re: Invalid Address specified to RtlFreeHeap( 0087, 008A1E90 ) on using FreeInternalIdList Sure, post the whole function or send it to me privately if you like. I'll take a look. What compiler are you using (VS 6, .NET 2003, etc.), which C Run-time are you linking with (e.g. static vs dll, release vs debug), and which version of the Remedy API are you linking with? It's probably best to link to the release mode multi-threaded DLL and use Visual Studio 6 if possible, as that's probably what the AR API libraries were built with. (I've also used Visual Studio .NET 2003, and while it has a different run-time, it seems to be okay using the release mode multi-threaded DLL option). Dan ___ UNSUBSCRIBE or access ARSlist Archives at http://www.wwrug.org
Re: Invalid Address specified to RtlFreeHeap( 00870000, 008A1E90 ) on using FreeInternalIdList
Title: Re: Invalid Address specified to RtlFreeHeap( 0087, 008A1E90 ) on using FreeInternalIdList ** I've seen problems in the past like this if you are malloc'ing memory with the debug version of the function, and freeing it with the release mode version. This is what is happening if you are using the debug multi-threaded DLL in your compiler options for your own code. The Remedy API was compiled using the release-mode multi-threaded DLL (msvcrt.dll vs msvcrtd.dll with VS 6.0), and the FreeARxxx functions are calling their code; therefore you have a debug malloc and a release free. That's very likely your cause. You can still compile your project in debug mode to debug, but switch the release mode C runtime (which you don't need to debug anyway). Besides that issues, I see two immediate issues in the below code: 1. The memory leak in the for loop. You need to free the ARInternalIdList each time - it's leaking it for every entry that matches except the last one. 2. This code will crash if there are no matching entries. In that case, it will call FreeARInternalIdList on an uninitialized structure, which will cause a memory exception (a free of a bogus address). You should almost always initialize your structures, e.g. ARInternalIdList idList = {0, NULL}. All three of these are several of the many reasons to move to a later technology, whether it's C++, COM, Java, or .NET. I know you're not interested in getting into VS .NET. Even with VS 6.0, you could use the RTL package to simplify the use of the library with proper objects. IMHO, "C" code like that below is too verbose, error prone, and difficult to maintainto be a productive development environment. (But really, I don't mean to start a religious discussion...my "proof" of this is the code comparison at http://rtl.sourceforge.net/doc). If I get the time, I'll "translate" the below code for you to show that it is probably 80% smaller and simpler. Dan From: Angus Comber [mailto:[EMAIL PROTECTED]Sent: Tue 7/18/2006 1:45 AMTo: arslist@ARSLIST.ORGCc: Dan HardySubject: Re: Invalid Address specified to RtlFreeHeap( 0087, 008A1E90 ) on using FreeInternalIdList Thanks for your help.I am using Visual C++ version 6. Not interested in getting into the MS .NETnonsense.Ah just changed to link to the release mode multi-threaded DLL - and nowdon't get problem. What is going on here to cause the crash?Anyway, for what it's worth here is the function belowfunction here:// Eg szFormName = [in] MyNewForm// Eg szSearchQual = [in] 'MyNewField' = "07768385144" OR 'Field2' ="07768385144" OR 'Field3' = "07768385144"// Eg szFieldID1 - [out] string from field1// Eg szFieldID2 - [out] string from field2// Eg fieldID1 - [in] fieldid to get data// Eg fieldID2 - [in] fieldid to get datalong CRemedy::Find2Fields(char* szFormName, char* szSearchQual, char*szFieldID1, char* szFieldID2,long fieldID1, long fieldID2){ARQualifierStruct qualstruct;AREntryListList entry;unsigned int matches = 0;ARInternalIdList idlist;ARFieldValueList fldval;// Loads specified qualification stringint ret = ARLoadARQualifierStruct(m_ARctrlstruct, szFormName, NULL,szSearchQual,qualstruct, m_StatusList);if(ret == 0){// retrieves list of forms on server - we specify form we are interested inhereret = ARGetListEntry(m_ARctrlstruct, szFormName, qualstruct, NULL, NULL,NULL,AR_NO_MAX_LIST_RETRIEVE, entry, matches, m_StatusList);if(ret == 0){// printf("matches: %d\n", matches);if(matches 0){for(int i=0; i (int)matches; i++){// printf("Entry: %s\n", entry.entryList[i].entryId.entryIdList[0]);idlist.numItems = 2; // need two fieldsidlist.internalIdList =(ARInternalId*)malloc(sizeof(ARInternalId) * idlist.numItems);idlist.internalIdList[0] = fieldID1;idlist.internalIdList[1] = fieldID2;ret=ARGetEntry(m_ARctrlstruct, szFormName, entry.entryList[i].entryId,idlist, fldval, m_StatusList);// can specify NULL for idlist to retrieve ALL fieldsif (ret == 0){// fldval.fieldValueList-value.u.charVal is field1 data// fldval.fieldValueList[1].fieldId is fieldid of that fieldstrncpy(szFieldID1, fldval.fieldValueList[0].value.u.charVal, 100);strncpy(szFieldID2, fldval.fieldValueList[1].value.u.charVal, 100);}else{if (m_StatusList.numItems 0)strcpy(m_strLastErrorMsg, m_StatusList.statusList-messageText);}}}// else// {// printf("no matches\n");// }}// else// {// printf("getlistentry failed\n");// }}// else// {// printf("load qual failed\n");// }// FALSE if declared as stack level variable, TRUE for alloc'd mem forstructFreeARQualifierStruct(qualstruct, FALSE);FreeAREntryListList(entry, FALSE);FreeARInternalIdList(idlist, FALSE);FreeARFieldValueList(fldval, FALSE);FreeARStatusList(m_StatusList, FALSE);// freeStruct - A flag indicating whether you need to free the top-levelstructure. If you// allocated memory for the top-level structure, specify 1 (TRUE) to freeboth// the structure and its co
Re: Invalid Address specified to RtlFreeHeap( 00870000, 008A1E90 ) on using FreeInternalIdList
Title: Re: Invalid Address specified to RtlFreeHeap( 0087, 008A1E90 ) on using FreeInternalIdList ** Angus, I simplified it for you using rtl...this does all the memory management and error handling for you, and is almost exactly the equivalent code. One other note: Your program would be faster if you are able to use GetListEntryWithField and ask for the two field values right there, instead of one API call per entry. This will work unless you need to access long character or diary fields. The updated code: #include "server.h" #include iostream long find2Fields(const std::string formName, const std::string szSearchQual, std::string szField1, std::string szField2,long fieldID1, long fieldID2){try {rtl::Server server("hardy-remedy", "Demo", ""); // replace with however you set up your server connection (a global, passed in, whatever)rtl::Qualifier qualifier;rtl::EntryListFieldValueList entries;rtl::IdList idList;rtl::FieldValueMap fieldValues;server.parseQualification(qualifier, szSearchQual, formName, "");unsigned int matches = 0;server.getListEntryWithFields(entries, formName, qualifier, idList, rtl::SortList(), 0, 0, matches);if (matches 0 entries.size() 0){rtl::EntryListFieldValueList::iterator iter = entries.begin();rtl::IdList fieldIdList;fieldIdList.push_back(fieldID1);fieldIdList.push_back(fieldID2);for (; iter != entries.end(); iter++) {rtl::EntryListFieldValue entry = *iter;// get the entry with the two fieldsserver.getEntry(fieldValues, formName, entry.getEntryIdList(), fieldIdList);szField1 = fieldValues.get(fieldID1).toString();szField2 = fieldValues.get(fieldID2).toString();}}else{cout "no matches\n";}return (matches = 1) ? 0 : -1;} catch (rtl::Exception err) {std::cerr err.toString().c_str();return -1;}} Dan From: Angus Comber [mailto:[EMAIL PROTECTED]Sent: Tue 7/18/2006 1:45 AMTo: arslist@ARSLIST.ORGCc: Dan HardySubject: Re: Invalid Address specified to RtlFreeHeap( 0087, 008A1E90 ) on using FreeInternalIdList Thanks for your help.I am using Visual C++ version 6. Not interested in getting into the MS .NETnonsense.Ah just changed to link to the release mode multi-threaded DLL - and nowdon't get problem. What is going on here to cause the crash?Anyway, for what it's worth here is the function belowfunction here:// Eg szFormName = [in] MyNewForm// Eg szSearchQual = [in] 'MyNewField' = "07768385144" OR 'Field2' ="07768385144" OR 'Field3' = "07768385144"// Eg szFieldID1 - [out] string from field1// Eg szFieldID2 - [out] string from field2// Eg fieldID1 - [in] fieldid to get data// Eg fieldID2 - [in] fieldid to get datalong CRemedy::Find2Fields(char* szFormName, char* szSearchQual, char*szFieldID1, char* szFieldID2,long fieldID1, long fieldID2){ARQualifierStruct qualstruct;AREntryListList entry;unsigned int matches = 0;ARInternalIdList idlist;ARFieldValueList fldval;// Loads specified qualification stringint ret = ARLoadARQualifierStruct(m_ARctrlstruct, szFormName, NULL,szSearchQual,qualstruct, m_StatusList);if(ret == 0){// retrieves list of forms on server - we specify form we are interested inhereret = ARGetListEntry(m_ARctrlstruct, szFormName, qualstruct, NULL, NULL,NULL,AR_NO_MAX_LIST_RETRIEVE, entry, matches, m_StatusList);if(ret == 0){// printf("matches: %d\n", matches);if(matches 0){for(int i=0; i (int)matches; i++){// printf("Entry: %s\n", entry.entryList[i].entryId.entryIdList[0]);idlist.numItems = 2; // need two fieldsidlist.internalIdList =(ARInternalId*)malloc(sizeof(ARInternalId) * idlist.numItems);idlist.internalIdList[0] = fieldID1;idlist.internalIdList[1] = fieldID2;ret=ARGetEntry(m_ARctrlstruct, szFormName, entry.entryList[i].entryId,idlist, fldval, m_StatusList);// can specify NULL for idlist to retrieve ALL fieldsif (ret == 0){// fldval.fieldValueList-value.u.charVal is field1 data// fldval.fieldValueList[1].fieldId is fieldid of that fieldstrncpy(szFieldID1, fldval.fieldValueList[0].value.u.charVal, 100);strncpy(szFieldID2, fldval.fieldValueList[1].value.u.charVal, 100);}else{if (m_StatusList.numItems 0)strcpy(m_strLastErrorMsg, m_StatusList.statusList-messageText);}}}// else// {// printf("no matches\n");// }}// else// {// printf("getlistentry failed\n");// }}// else// {// printf("load qual failed\n");// }// FALSE if declared as stack level variable, TRUE for alloc'd mem forstructFreeARQualifierStruct(qualstruct, FALSE);FreeAREntryListList(entry, FALSE);FreeARInternalIdList(idlist, FALSE);FreeARFieldValueList(fldval, FALSE);FreeARStatusList(m_StatusList, FALSE);// freeStruct - A flag indicating whether you need to free the top-levelstructure. If you// allocated memory for the top-level structure, specify 1 (TRUE) to freeboth// the structure and its contents. If you used a stack variable for thetop-level// structure, specify 0 (FALSE) to free only the contents of the structure.if (matches 1)return -1;return 0;}-
Invalid Address specified to RtlFreeHeap( 00870000, 008A1E90 ) on using FreeInternalIdList
Hello I am doing this with ARGetEntry: ARInternalIdList idlist; idlist.numItems = 2; // need two fields idlist.internalIdList = (ARInternalId *) malloc(sizeof(ARInternalId) * idlist.numItems); idlist.internalIdList[0] = fieldID1; // eg 2 - Submitter idlist.internalIdList[1] = fieldID2; // eg 4 - Assigned To ret=ARGetEntry(m_ARctrlstruct, szFormName, entry.entryList[i].entryId, idlist, fldval, m_StatusList); strcpy(szField1, fldval.fieldValueList[0].value.u.charVal); // copy field data strcpy(szField2, fldval.fieldValueList[1].value.u.charVal); Then I get Invalid address specified to RtlFreeHeap when I call: FreeARInternalIdList(idlist, FALSE); What am I doing wrong? Angus ___ UNSUBSCRIBE or access ARSlist Archives at http://www.wwrug.org
Re: Invalid Address specified to RtlFreeHeap( 00870000, 008A1E90 ) on using FreeInternalIdList
Which platform are you on? It could be caused by: 1) Different structure byte-alignment options at compile time (I've found the default setting works on Windows, on Linux you need a special -malign switch with gcc at least). I can look it up if you need it. 2) It doesn't look you are checking the return code from the API call, checking whether the returned value list has at least 2 items, that either of the values is of type AR_DATA_TYPE_CHAR, or that the pointer is not NULL. You also are copying the data using strcpy, without checking the length, rather than using strncpy or allocating a buffer of large enough size. This could cause corruption (buffer overflow) and easily explain the error, particularly if szField1 and szField2 are stack variables. 3) Different run-time library version between your code and the AR System library (you're calling malloc, it's calling free - could be mismatched) If you are on Windows, I put my money on #2 - sounds like stack corruption. I would point out that if you used the rtl library much of this would be done for you, and you wouldn't have to worry about allocating or freeing any memory, testing for null pointers, checking return codes for error conditions, etc. ;) Dan -Original Message- From: Action Request System discussion list(ARSList) [mailto:[EMAIL PROTECTED] On Behalf Of Angus Comber Sent: Monday, July 17, 2006 3:11 PM To: arslist@ARSLIST.ORG Subject: Invalid Address specified to RtlFreeHeap( 0087, 008A1E90 ) on using FreeInternalIdList Hello I am doing this with ARGetEntry: ARInternalIdList idlist; idlist.numItems = 2; // need two fields idlist.internalIdList = (ARInternalId *) malloc(sizeof(ARInternalId) * idlist.numItems); idlist.internalIdList[0] = fieldID1; // eg 2 - Submitter idlist.internalIdList[1] = fieldID2; // eg 4 - Assigned To ret=ARGetEntry(m_ARctrlstruct, szFormName, entry.entryList[i].entryId, idlist, fldval, m_StatusList); strcpy(szField1, fldval.fieldValueList[0].value.u.charVal); // copy field data strcpy(szField2, fldval.fieldValueList[1].value.u.charVal); Then I get Invalid address specified to RtlFreeHeap when I call: FreeARInternalIdList(idlist, FALSE); What am I doing wrong? Angus ___ UNSUBSCRIBE or access ARSlist Archives at http://www.wwrug.org ___ UNSUBSCRIBE or access ARSlist Archives at http://www.wwrug.org