T.R | Title | User | Personal Name | Date | Lines |
---|
2455.1 | Need more info to reproduce this | RECV::VLATAS | WARNING: Do not swallow the battery door | Wed Mar 19 1997 07:20 | 13 |
|
I tried to reproduce this (using quickstart), but wasn't able to.
I watched the client process with the Performance monitor and the task
manager and the memory usage stayed flat as it looped through a few
thousand invokes (Purify also verified that no memory was leaked
after rundown).
Some questions:
1) What service pack level is installed on the NT 4.0 machine?
2) Which language bindings are you using?
3) Was the object an out argument, or was it the return value?
Tony
|
2455.2 | Some anwswers | UTROP1::OLERUD_G | | Wed Mar 19 1997 07:48 | 16 |
| Tony,
>> 1) What service pack level is installed on the NT 4.0 machine?
We are using service pack 1.
>> 2) Which language bindings are you using?
We are using C++ bindings
>> 3) Was the object an out argument, or was it the return value?
The object reference was returned as a return value.
Cheers
Gunnar
|
2455.3 | No luck yet, can you post the IDL | SEND::VLATAS | WARNING: Do not swallow the battery door | Wed Mar 19 1997 09:14 | 6 |
|
I still haven't been able to reproduce this. Could you post the IDL
that you used for the Quickstart reproducer.
thanks
Tony
|
2455.4 | here it is - nothing special | LEMAN::DONALDSON | Froggisattva! Froggisattva! | Fri Mar 21 1997 08:13 | 53 |
| Tony,
thanks for the attention and sorry for the slow turnaround.
Gunnar and I are working on site with the customer and it's
pretty difficult to keep in touch. Today I'm back at my
Digital desk (821-5032) and so of course it's difficult to
try things in the customer environment!
The IDL below shows the problem. However, I have to say that
there is nothing special about it. It's just what we've
reduced things to. At first we suspected something in the
way we were doing things (we have a large implementation by
now and lots of things are happening). We also have servers
with no memory leaks.
However, we then generated a quickstart client and server,
modified them to loop lots of times (loop in the client
and comment out exit_mainloop in the server). Then we
monitor with the task monitor that comes with NT4.
We reliably leak about 2k. That's if I Exchange->startSession
and then Session->close (see idl). If all I do is
Exchange->startSession then I leak a little bit less.
(Of course I had to modify the quickstart code a little to
get the Session->close on the Session returned by
Exchange->startSession).
As Gunnar said earlier we *dont* see this on VMS. And if
I could figure a simple way to monitor memory on W95 then
I'd check things there.
We can arrange to send you some code if you want but I
assure you its nothing special.
John D.
IDL: ------------------------------------------------------
module TSA
{
interface Session
{
void close();
};
interface Exchange
{
Session startSession( in string name);
};
};
|
2455.5 | Found 2 client leaks, 1 server leak | SEND::VLATAS | WARNING: Do not swallow the battery door | Tue Mar 25 1997 09:20 | 67 |
| Hi John,
Sorry for the delay, I just got back around to trying your IDL.
>> The IDL below shows the problem. However, I have to say that
>> there is nothing special about it.
Your IDL did show the leaks (My IDL used "Object" yours used
"Session", this was an important difference. I'm suprised that
the leaks only showed up in V2.7-11 and only on NT for you.
The leaks are pretty generic and I would expect would happen
everywhere. I also found a leak in the server.
I will be entering PTRs on these separately and will post the
PTR numbers when I enter them.
Two of the leaks were the result of generated code creating a
CORBA::Object_ptr, then narrowing it to the result Session, and
never releasing the original CORBA::Object_ptr.
Looks like there are a few leaks in the client:
1) The overloaded routine for extracting the object from the
marshalbuffer isn't releasing the tmp_obj_ptr.
Workaround A:
Change your IDL to return an Object, and have your client
narrow the Object to Session.
Workaround B: (Requires editing generated code)
Leave "Session" as the return type and edit the generated
routine in the typecode module:
OBB::MarshalBuf &operator>>(OBB::MarshalBuf &mb,
TSA::Session_ptr &_obj)
Add in the following after the _narrow call:
{
CORBA::Environment tmp_ev;
CORBA::release(tmp_obj_ptr, tmp_ev);
}
2) The Quickstart code for TSAExchangeStartSession allocates a
string that it never frees.
Workaround:
Edit generated client call routime TSAExchangestartsession
Add in the following after the call to
ExchangeObj->startsession():
CORBA::string_free(name);
For the leak in the Server:
1) The Quickstart code for ExchaneImpl::ExchangeImpl_startsession wasn't
releasing the temp_object after it narrowed it.
Workaround:
Add in the following after the _narrow call:
CORBA::release(temp_object, ev);
thanks
Tony
|
2455.6 | Forgot to mention another server side workaround.. | SEND::VLATAS | WARNING: Do not swallow the battery door | Tue Mar 25 1997 09:23 | 5 |
|
Also note that if you change your IDL to use "Object" the server
side leak will go away as well...
Tony
|
2455.7 | PTR numbers | SEND::VLATAS | WARNING: Do not swallow the battery door | Wed Mar 26 1997 09:44 | 7 |
| The PTR numbers for tracking those leaks are:
16-3-252
16-3-253
16-3-254
Tony
|
2455.8 | TypeCode fix program | UTROP1::OLERUD_G | | Thu Mar 27 1997 05:05 | 166 |
| This is now the fourth fix program I've written to fix OBB generated
code. I'm becoming a real expert in doing this.
Well, I've written a type code fix program that can be used to remove
the memory leak problem described in this note.
Gunnar
---------------------------------------------------------------------
/*
*
* TypeCodeFix - a program to fixup the generated TypeCode file from
ObjectBroker
*
* This program uses STL and has been written in Visual C++ 4.2.
*
* Description:
* This program reads in a generated type code file and adds a
release
* statement of a temporary object in all routines of type:
*
* OBB::MarshalBuf &operator>>(OBB::MarshalBuf &mb,
<module>::<interface>_ptr &obj)
*
* The search criteria used is: "::_narrow(tmp_obj_ptr);"
* which seems appropriate in this case.
*
* Authors: Olerud, 27 March 1997
*
* History:
* 27 March 1997 Gunnar Olerud, First version
*
*/
#ifdef WIN32
#pragma warning (disable: 4786) // identifier was truncated to
'255' characters
#endif
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <iterator>
#define MAX_LINE_SIZE 1024
typedef vector <string, allocator<string> > LineVector;
// Forward declarations
bool ReadFile (string filename, LineVector& inLines);
bool creOutputFile(string fileName, LineVector& outLines);
bool fixupRelease(LineVector& inLines, LineVector& outLines);
// Here it comes! The main program.
int
main(int argc, char *argv[])
{
LineVector inLines;
LineVector outLines;
if (argc < 2)
{
cout << "TypeCodeFix: Not enough parameters, syntax:" <<
endl;
cout << "TypeCodeFix <TypeCode file>" << endl;
return 1;
}
// read the type code file into a vector
if (!ReadFile (argv[1], inLines))
{
return 1;
}
if (!fixupRelease(inLines, outLines))
{
cout << "TypeCodeFix: No changes made" << endl;
return 0;
}
// output the default vector to the new IML file
creOutputFile(argv[1], outLines);
return 0;
}
bool
ReadFile (string fileName, LineVector& lines)
{
char single_line[MAX_LINE_SIZE];
ios_base::openmode mode = ios_base::in;
ifstream infile (fileName.c_str(), mode);
if (!infile.is_open())
{
cout << "TypeCodeFix: Can't open file '" << fileName << "'"
<< endl;
return false;
}
cout << "Reading from file " << fileName << endl;
while (infile.getline (single_line, sizeof(single_line)))
{
lines.push_back(single_line);
}
infile.close ();
return true;
}
bool
creOutputFile(string fileName, LineVector& lines)
{
ofstream fileout (fileName.c_str());
if (!fileout.is_open())
{
cout << "TypeCodeFix: Can't create file '" << fileName <<
"'" << endl;
return false;
}
cout << "Writing to file " << fileName << endl;
ostream_iterator<string, char, struct char_traits<char> >
out(fileout, "\n");
copy(lines.begin(), lines.end(), out);
fileout.close();
return true;
} // End of creOutputFile(string fileName, LineVector& lines)
bool
fixupRelease(LineVector& inLines, LineVector& outLines)
{
int position;
bool isChanged = false;
string searchKey = "::_narrow(tmp_obj_ptr);";
LineVector addLines;
addLines.push_back ("\t{");
addLines.push_back ("\t\tCORBA::Environment tmp_ev;");
addLines.push_back ("\t\tCORBA::release(tmp_obj_ptr, tmp_ev);");
addLines.push_back ("\t}");
LineVector::iterator lineIT;
for (lineIT = inLines.begin(); lineIT != inLines.end(); lineIT++)
{
outLines.push_back(*lineIT);
if ((position = (*lineIT).find(searchKey)) > 0)
{
//the narrow found. Add the release statement if
not already there
lineIT++;
if (!equal (addLines.begin(), addLines.end(),
lineIT))
{
copy (addLines.begin(), addLines.end(),
back_inserter(outLines));
isChanged = true;
}
}
}
return isChanged;
} // end of fixupRelease(LineVector& lines)
|
2455.9 | Correct version of TypeCodeFix program | UTROP1::OLERUD_G | | Thu Mar 27 1997 06:49 | 163 |
| Woops!!! I was too quick to enter the code in .7. Hopefully this
version works better.
Gunnar
----------------------------------------------------------------
/*
*
* TypeCodeFix - a program to fixup the generated TypeCode file from
ObjectBroker
*
* This program uses STL and has been written in Visual C++ 4.2.
*
* Description:
* This program reads in a generated type code file and adds a
release
* statement of a temporary object in all routines of type:
*
* OBB::MarshalBuf &operator>>(OBB::MarshalBuf &mb,
<module>::<interface>_ptr &obj)
*
* The search criteria used is: "::_narrow(tmp_obj_ptr);"
* which seems appropriate in this case.
*
* Authors: Olerud, 27 March 1997
*
* History:
* 27 March 1997 Gunnar Olerud, First version
*
*/
#ifdef WIN32
#pragma warning (disable: 4786) // identifier was truncated to
'255' characters
#endif
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <iterator>
#define MAX_LINE_SIZE 1024
typedef vector <string, allocator<string> > LineVector;
// Forward declarations
bool ReadFile (string filename, LineVector& inLines);
bool creOutputFile(string fileName, LineVector& outLines);
bool fixupRelease(LineVector& inLines, LineVector& outLines);
// Here it comes! The main program.
int
main(int argc, char *argv[])
{
LineVector inLines;
LineVector outLines;
if (argc < 2)
{
cout << "TypeCodeFix: Not enough parameters, syntax:" <<
endl;
cout << "TypeCodeFix <TypeCode file>" << endl;
return 1;
}
// read the type code file into a vector
if (!ReadFile (argv[1], inLines))
{
return 1;
}
if (!fixupRelease(inLines, outLines))
{
cout << "TypeCodeFix: No changes made" << endl;
return 0;
}
// output the default vector to the new IML file
creOutputFile(argv[1], outLines);
return 0;
}
bool
ReadFile (string fileName, LineVector& lines)
{
char single_line[MAX_LINE_SIZE];
ios_base::openmode mode = ios_base::in;
ifstream infile (fileName.c_str(), mode);
if (!infile.is_open())
{
cout << "TypeCodeFix: Can't open file '" << fileName << "'"
<< endl;
return false;
}
cout << "Reading from file " << fileName << endl;
while (infile.getline (single_line, sizeof(single_line)))
{
lines.push_back(single_line);
}
infile.close ();
return true;
}
bool
creOutputFile(string fileName, LineVector& lines)
{
ofstream fileout (fileName.c_str());
if (!fileout.is_open())
{
cout << "TypeCodeFix: Can't create file '" << fileName <<
"'" << endl;
return false;
}
cout << "Writing to file " << fileName << endl;
ostream_iterator<string, char, struct char_traits<char> >
out(fileout, "\n");
copy(lines.begin(), lines.end(), out);
fileout.close();
return true;
} // End of creOutputFile(string fileName, LineVector& lines)
bool
fixupRelease(LineVector& inLines, LineVector& outLines)
{
int position;
bool isChanged = false;
string searchKey = "::_narrow(tmp_obj_ptr);";
LineVector addLines;
addLines.push_back ("\t{");
addLines.push_back ("\t\tCORBA::Environment tmp_ev;");
addLines.push_back ("\t\tCORBA::release(tmp_obj_ptr, tmp_ev);");
addLines.push_back ("\t}");
LineVector::iterator lineIT;
for (lineIT = inLines.begin(); lineIT != inLines.end(); lineIT++)
{
outLines.push_back(*lineIT);
if ((position = (*lineIT).find(searchKey)) > 0)
{
//the narrow found. Add the release statement if
not already there
if (!equal (addLines.begin(), addLines.end(),
lineIT+1))
{
copy (addLines.begin(), addLines.end(),
back_inserter(outLines));
isChanged = true;
}
}
}
return isChanged;
} // end of fixupRelease(LineVector& lines)
|