Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 21 Jul 2003 14:35:58 -0400
From:      Xiaowei Yang <yxw@cordelia.lcs.mit.edu>
To:        Brooks Davis <brooks@one-eyed-alien.net>
Cc:        freebsd-ports@freebsd.org
Subject:   Re: NJAMD
Message-ID:  <pzvvftvralt.wl@cordelia.lcs.mit.edu>
In-Reply-To: <pzv65m0t117.wl@cordelia.lcs.mit.edu>
References:  <pzvbrvtt7un.wl@cordelia.lcs.mit.edu> <20030717173305.GA449@Odin.AC.HMC.Edu> <pzv65m0t117.wl@cordelia.lcs.mit.edu>

next in thread | previous in thread | raw e-mail | index | archive | help
--Multipart_Mon_Jul_21_14:35:58_2003-1
Content-Type: text/plain; charset=US-ASCII

A few days ago, I posted a message asking whether NJAMD is ported to
FreeBSD. I was told there was no need for porting because the NOTES
file from the source distribution claims NJAMD runs under
FreeBSD. However, I tested NJAMD on FreeBSD machines and found some
problems.

For a simple program C++ I wrote, NJAMD reported memory leak while
there isnot. I did the test both on FreeBSD 4.7 and 5.1, using gcc
versions 2.95, 3.2, 3.3. I will attach the program at the end of the
message. NJAMD on a redhat 8.0 reports the right results.

Can someone recommend me a malloc debugger that works under FreeBsd? I
like NJAMD because I do not need to link the library during
compilation. Is there any similar tool under FreeBsd? I'd appreciate
your feedback!

Attached is my test program, followed by results reported from RedHat
and FreeBSD.


--Multipart_Mon_Jul_21_14:35:58_2003-1
Content-Type: application/octet-stream
Content-Disposition: attachment; filename="test-refcnt.C"
Content-Transfer-Encoding: 7bit

#include <cstdio>

class ConnectivityContent {
public:
  ConnectivityContent() : refcnt_(1), val(0) {}
  ConnectivityContent(int v) : refcnt_(1), val(v) {}
  ~ConnectivityContent() {
    printf("auto destructor is called\n");
  }

  void incr_refcnt() {
    refcnt_++;
  }

  void dec_refcnt() {
    refcnt_--;
    if (refcnt_ == 0) {
      printf("freeing content\n");
      delete this;
    }
  }

  unsigned refcnt() { return refcnt_; }

protected:
  unsigned refcnt_;
  int val;
};

class ConnectivityHeader {
public:
  ConnectivityHeader() : tippid_(0), nbrid_(0), seqno_(0), age_(0),
			 checksum_(0), reverse_(0) {}

  ConnectivityHeader(int tippid, int nbrid,  int seqno, int age) :
    reverse_(0)
  {
    tippid_ = tippid;
    nbrid_ = nbrid; 
    seqno_ = seqno;
    age_ = age;
  }

  int& age() { return age_; }
  int& tippid() { return tippid_; }
  int& nbrid() { return nbrid_; } // should be nbr asn?
  int& seqno() { return seqno_; }
  int& reverse() { return reverse_; }
  int& checksum() { return checksum_; }
  int compare(ConnectivityHeader& aheader);
  static const int MAXAGEDIFF = 300;
  static const int MAXAGE = 600;

protected:
  int tippid_;
  int seqno_;
  int nbrid_;
  int age_;
  int checksum_; 
  int reverse_;
};

class ConnectivityDesc {
public:
  ConnectivityDesc()  {}
  ConnectivityDesc(ConnectivityContent* c) {
    content_ = c;
  }
  ConnectivityDesc(const ConnectivityDesc& d) {
    header_ = d.header_;
    content_ = d.content_;
    content_->incr_refcnt();
  }
  ConnectivityDesc& operator= (const ConnectivityDesc& d) {
    header_ = d.header_;
    content_ = d.content_;
    content_->incr_refcnt();
  }

  ~ConnectivityDesc() {
    if (content_->refcnt() >  0) {
      content_->dec_refcnt();
    }
  }

  ConnectivityHeader& header() { return header_; }
  
  
  int& checksum() { return header_.checksum(); }
  int& age() { return header_.age(); }
  void set_reverse() { header_.reverse() = 1; }
  ConnectivityContent* content() { return content_; }

protected:
  ConnectivityHeader header_;
  // content_ is shared among all nodes that receive a copy of this
  // description.
  ConnectivityContent* content_;
};

int main(int argc, char* argv[])
{
  ConnectivityContent* c1 = new ConnectivityContent(1);
  ConnectivityContent* c2 = new ConnectivityContent(2);

  ConnectivityDesc* d1 = new ConnectivityDesc(c1);
  ConnectivityDesc* d2 = new ConnectivityDesc(c2);

  d1->age() = 1;
  d2->age() = 2;
  
  printf("refcnt c1 is %d\n", c1->refcnt());
  printf("refcnt c2 is %d\n", c2->refcnt());

  delete d2;

  printf("refcnt c1 is %d\n", c1->refcnt());
  printf("refcnt c2 is %d\n", c2->refcnt());

  d2 = d1;
  // *d2 = *d1;

  printf("refcnt c1 is %d\n", c1->refcnt());
  printf("refcnt c2 is %d\n", c2->refcnt());

  printf("age d2 is %d\n", d2->age());

  // delete d1;
  
  // delete d2;
  delete d1;
  
  printf("refcnt c1 is %d\n", c1->refcnt());
  printf("refcnt c2 is %d\n", c2->refcnt());

}  
  

--Multipart_Mon_Jul_21_14:35:58_2003-1
Content-Type: text/plain; charset=US-ASCII



********************Results reported under  RedHat 8.0********************
refcnt c1 is 1
refcnt c2 is 1
freeing content
auto destructor is called
age d2 is 1
freeing content
auto destructor is called

NJAMD totals:

        Allocation totals:              4 total, 0 leaked
        Leaked User Memory:             0 bytes
        Peak User Memory:               72 bytes
        NJAMD Overhead at peak:         15.930 kB
        Peak NJAMD Overhead:            15.930 kB
        Average NJAMD Overhead:         3.982 kB per alloc
        Address space used:             32.000 kB
        NJAMD Overhead at exit:         0 bytes
*************************************************************************

********************Results reported under FreeBSD********************
[v tmp]$ ./refcnt
refcnt c1 is 1
refcnt c2 is 1
freeing content
auto destructor is called
age d2 is 1
freeing content
auto destructor is called

0x28233000-0x28236000: Aligned len 4096
   Allocation callstack:
        called from 0x8048856
        called from 0x8048585
        called from 0x1
   Not Freed
**********************************************************************
--Multipart_Mon_Jul_21_14:35:58_2003-1--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?pzvvftvralt.wl>