Since the files are FILE *
, we could do something like this:
In a headerfile that gets included everywhere:
#define fopen(x, y) debug_fopen(x, y, __FILE__, __LINE__)
#define fclose(x) debug_fclose(x)
in "debugfile.cpp" (must obviously NOT use the above #define
's)
struct FileInfo
{
FileInfo(const char *nm, const char fl, int ln) :
name(nm), file(fl), line(ln) {}
std::string name;
const char *file;
int line;
};
std::map<FILE*, FileInfo> filemap;
FILE *debug_fopen(const char *fname, const char *mode, const char *file, int line)
{
FILE *f = fopen(fname, mode);
if (f)
{
FileInfo inf(fname, file, line);
filemap[f] = inf;
}
}
int debug_fclose(FILE *f)
{
int res = fclose(f);
filemap.erase(f);
return res;
}
// Called at some points.
void debug_list_openfiles()
{
for( i : filemap )
{
cerr << "File" << (void *) i.first << " opened as " << i.second.name
<< " at " << i.second.file << ":" << i.second.line << endl;
}
}
(I haven't compiled this code, and it's meant to show the concept, it may have minor bugs, but I think the concept would hold - as long as your code, and not some third party library is leaking)