2005/5/9

     
 

core_memcheck.cpp

artefaktur
// -*- mode:C++; tab-width:2; c-basic-offset:2; indent-tabs-mode:nil -*- 
//
// Copyright (C) 2000-2005 by Roger Rene Kommer / artefaktur, Kassel, Germany.
// 
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public License (LGPL).
// 
// 
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the 
// License ACDK-FreeLicense document enclosed in the distribution
// for more for more details.
// This file is part of the Artefaktur Component Development Kit:
//                         ACDK
// 
// Please refer to
// - http://www.acdk.de
// - http://www.artefaktur.com
// - http://acdk.sourceforge.net
// for more information.
// 
// $Header: /cvsroot/acdk/acdk/acdk_core/src/acdk/lang/sys/core_memcheck.cpp,v 1.11 2005/03/07 13:47:28 kommer Exp $

#include <acdk.h>
#include "ObjectHeap.h"

#include "core_memcheck.h"
#include <acdk/lang/ref/NotifyObjectEvent.h>

namespace acdk {
namespace lang {
namespace sys {




class ListObjects
: extends ::acdk::lang::Object
, implements ::acdk::lang::ref::NotifyObjectEventListener
{
  virtual void notifyBeforeConstruction(acdk::lang::Object* obj) {}
  virtual bool notifyBeforeDestruction(acdk::lang::Object* obj) { return true; }
  virtual void notifyWhileDestruction(acdk::lang::Object* obj) {}
  virtual bool listHeaps(IN(::acdk::lang::sys::RHeapFrame) theheap) { return false; }
  virtual bool listedAllocated(IN(::acdk::lang::sys::RHeapFrame) theheap, void* obj, ::acdk::lang::sys::AllocatedType type, int size) 
  {
    switch (type)
    {
    case UnspecifiedMem: 
      sys::coreout << "Unspec Mem[" << size  << "]: " << obj << sys::eofl;
      break;
    case RawMem : 
      sys::coreout << "RawMem[" << size  << "]: " << obj << sys::eofl;
      break;
    case ObjectMem : 
    {
      RString s = ((acdk::lang::Object*)obj)->toString()->convert(CCAscii);
      const char* c = s->c_str();
      if (c == 0)
        c = "";
      sys::coreout << "ObjectMem[" << size  << "]: " << obj << ": "  << ((acdk::lang::Object*)obj)->getClass()->toString()->c_str() << ": " << c << sys::eofl;
      break;
    }
    case InternalMem :
      sys::coreout << "InternalMem[" << size  << "]: " << obj << sys::eofl;
      break;
    case ObjectRefArrayMem:
      sys::coreout << "ObjectRefArrayMem[" << size  << "]: " << obj << sys::eofl;
      break;
    case DumpBufferMem:
    {
      char* buffer = ::new char[size + 1];
      memcpy(buffer, obj, size);
      buffer[size] = 0;
      sys::coreout << "DumpBufferMem[" << size  << "]: " << buffer << sys::eofl;
      ::delete[] buffer;
      break;
    }
    case NoGcMem:
      sys::coreout << "NoGcMem[" << size  << "]: " << obj << sys::eofl;
      break;
    default : 
      sys::coreout << "<error> Mem[" << size  << "]: " << obj << sys::eofl;
      break;
    }
    return true;
  }
};


core_memcheck::core_memcheck(const char* name, bool newFrame, bool useNativeDebug)
: _name(name)
, _useNativeDebug(useNativeDebug)
, _useNewFrame(newFrame)
{
#if defined(_MSC_VER) && defined(_DEBUG)
  _CrtMemCheckpoint(&_checkpoint);
#endif
/FONT>
  if (_useNewFrame == true)
    ObjectHeap::pushFrame();
}
core_memcheck::~core_memcheck()
{
  if (_useNativeDebug == true)
    reportNativeDiff();
  reportHeapDiff();
  if (_useNewFrame == true)
    ObjectHeap::popFrame();
}

void 
core_memcheck::reportHeapDiff()
{
  ListObjects listo;
  acdk::lang::sys::RHeapFrame hf = acdk::lang::sys::ObjectHeap::topHeapFrame();
  if (_useNewFrame == true)
    ObjectHeap::pushFrame();
  hf->listObjects(&listo, 0);
  if (_useNewFrame == true)
    ObjectHeap::popFrame();
}
 


void 
core_memcheck::reportNativeDiff()
{
#if defined(_MSC_VER) && defined(_DEBUG)
  _CrtMemState checkpoint;
  _CrtMemCheckpoint(&checkpoint);
  _CrtMemState diff;
  _CrtMemDifference(&diff, &_checkpoint, &checkpoint);
  if (diff.lSizes[0] == 0 && diff.lSizes[1] == 0  && diff.lSizes[2] == 0  &&
      diff.lSizes[3] == 0  && diff.lSizes[4] == 0)
    return;
  _RPT1( _CRT_WARN, "\n\n%s:\n>>>>>>>>>>>>>>>>>>>>>>>>\n", _name);
  _CrtMemDumpAllObjectsSince(&_checkpoint);
  _RPT1( _CRT_WARN, "<<<<<<<<<<<<<<<<<<<<<<<<<<\n%s\n\n", _name);
#endif //defined(_MSC_VER)
}


} // namespace sys 
} // namespace lang 
} // namespace acdk