Jump to page: 1 2
Thread overview
Destruction Derby
Jun 09, 2004
Arcane Jill
Jun 09, 2004
J Anderson
Jun 09, 2004
Arcane Jill
Jun 09, 2004
Arcane Jill
Jun 09, 2004
Ivan Senji
Jun 09, 2004
Ilya Minkov
Jun 09, 2004
hellcatv
Jun 09, 2004
Arcane Jill
Jun 09, 2004
Ivan Senji
Jun 09, 2004
Andy Friesen
Jun 09, 2004
Ben Hinkle
Jun 09, 2004
Arcane Jill
Jun 14, 2004
Kevin Bealer
Jun 14, 2004
Kevin Bealer
Jun 09, 2004
Walter
Jun 09, 2004
Arcane Jill
Jun 09, 2004
Arcane Jill
Jun 09, 2004
Walter
June 09, 2004
Destruction - Definitive test results.

Faced with uncertainty, I did what any scientist would do. I did an experiment. Here's the source code:

//======== BEGIN =========
>   import std.c.stdio;
>   import std.c.stdlib;
>   import std.gc;
> 
>   FILE * f;
> 
>   class A
>   {
>       new(uint n)
>       {
>           f = fopen("C:\\gctest.txt","wt");
>           fprintf(f,"Allocator called\n");
>           return malloc(n);
>       }
> 
>       this()
>       {
>           fprintf(f,"Constructor called\n");
>       }
> 
>       ~this()
>       {
>           fprintf(f,"Destructor called\n");
>       }
> 
>       delete(void* p)
>       {
>           fprintf(f,"Deallocator called\n");
>           fclose(f);
>           free(p);
>       }
> 
>       int t;
>   }
> 
>   int main()
>   {
>       A a = new A();
>       a = null;
>       fullCollect();
>       return 0;
>   }
//========= END ==========

And here's the contents of the file after the program is run:

//======= BEGIN ========
Allocator called
Constructor called
//======== END =========

Conclusions:
(1) The destructor was not called.
(2) The class deallocator was not called.

Observe that the garbage collector WAS EXPLICITLY INVOKED, and that the variable 'a' was not reachable at the time the gc was run. This "destruction" is not merely lazy, it seems to be actually on vacation.

Now, there are two possibilities. Either
(a) This is correct behavior
(b) This is a bug in the compiler

If it's (a) I will need to think very hard to try to find a workaround. If I can't find one I will have to abandon my D project and write the thing in C++. If it's (b) then it's critical to me that the bug be fixed asap, because, again, this has to work, or D becomes useless for my purposes.



June 09, 2004
Arcane Jill wrote:

>If it's (a) I will need to think very hard to try to find a workaround. If I
>can't find one I will have to abandon my D project and write the thing in C++.
>If it's (b) then it's critical to me that the bug be fixed asap, because, again,
>this has to work, or D becomes useless for my purposes.
>  
>

Are you saying that the only reason you are using D is because of the gc?  If you use C++ you won't get automatic deconstruction either, you have to call delete (in D and C++) to get that.


-- 
-Anderson: http://badmama.com.au/~anderson/
June 09, 2004
In article <ca6us1$27g7$1@digitaldaemon.com>, J Anderson says...
>
>If you use C++ you won't get automatic deconstruction either, you have to call delete (in D and C++) to get that.

Not true.

>    void f()  // C++
>    {
>        SecurePassword p;   // constructed on the stack
>
>        /* do stuff with p which auto makes illegal in D */
>
>    }
>    // Destructor of p WILL be called, even in the event of an exception

Jill


June 09, 2004
In article <ca6us1$27g7$1@digitaldaemon.com>, J Anderson says...

>Are you saying that the only reason you are using D is because of the gc?

No. I'm using D because D is brilliant. I beleive I've said that a few times already. Please don't read into my words that which I have not said.

Destructors which refuse to execute are merely a recently discovered problem which I'm currently trying either to solve or work around.

Jill


June 09, 2004
"Arcane Jill" <Arcane_member@pathlink.com> wrote in message news:ca6rl9$22p9$1@digitaldaemon.com...
> Destruction - Definitive test results.
>
> Faced with uncertainty, I did what any scientist would do. I did an
experiment.
> Here's the source code:
>
> //======== BEGIN =========
> >   import std.c.stdio;
> >   import std.c.stdlib;
> >   import std.gc;
> >
> >   FILE * f;
> >
> >   class A
> >   {
> >       new(uint n)
> >       {
> >           f = fopen("C:\\gctest.txt","wt");
> >           fprintf(f,"Allocator called\n");
> >           return malloc(n);
> >       }
> >
> >       this()
> >       {
> >           fprintf(f,"Constructor called\n");
> >       }
> >
> >       ~this()
> >       {
> >           fprintf(f,"Destructor called\n");
> >       }
> >
> >       delete(void* p)
> >       {
> >           fprintf(f,"Deallocator called\n");
> >           fclose(f);
> >           free(p);
> >       }
> >
> >       int t;
> >   }
> >
> >   int main()
> >   {
> >       A a = new A();
> >       a = null;
> >       fullCollect();
> >       return 0;
> >   }
> //========= END ==========
>
> And here's the contents of the file after the program is run:
>
> //======= BEGIN ========
> Allocator called
> Constructor called
> //======== END =========
>
> Conclusions:
> (1) The destructor was not called.
> (2) The class deallocator was not called.
>
> Observe that the garbage collector WAS EXPLICITLY INVOKED, and that the
variable
> 'a' was not reachable at the time the gc was run. This "destruction" is
not
> merely lazy, it seems to be actually on vacation.

Maybe i am missing something but is it out of the question to use delete a; ?

> Now, there are two possibilities. Either
> (a) This is correct behavior
> (b) This is a bug in the compiler
>
> If it's (a) I will need to think very hard to try to find a workaround. If
I
> can't find one I will have to abandon my D project and write the thing in
C++.
> If it's (b) then it's critical to me that the bug be fixed asap, because,
again,
> this has to work, or D becomes useless for my purposes.
>
>
>


June 09, 2004
what if you explicitly call delete a; before setting it to null? In article <ca6rl9$22p9$1@digitaldaemon.com>, Arcane Jill says...
>
>Destruction - Definitive test results.
>
>Faced with uncertainty, I did what any scientist would do. I did an experiment. Here's the source code:
>
>//======== BEGIN =========
>>   import std.c.stdio;
>>   import std.c.stdlib;
>>   import std.gc;
>> 
>>   FILE * f;
>> 
>>   class A
>>   {
>>       new(uint n)
>>       {
>>           f = fopen("C:\\gctest.txt","wt");
>>           fprintf(f,"Allocator called\n");
>>           return malloc(n);
>>       }
>> 
>>       this()
>>       {
>>           fprintf(f,"Constructor called\n");
>>       }
>> 
>>       ~this()
>>       {
>>           fprintf(f,"Destructor called\n");
>>       }
>> 
>>       delete(void* p)
>>       {
>>           fprintf(f,"Deallocator called\n");
>>           fclose(f);
>>           free(p);
>>       }
>> 
>>       int t;
>>   }
>> 
>>   int main()
>>   {
>>       A a = new A();
>>       a = null;
>>       fullCollect();
>>       return 0;
>>   }
>//========= END ==========
>
>And here's the contents of the file after the program is run:
>
>//======= BEGIN ========
>Allocator called
>Constructor called
>//======== END =========
>
>Conclusions:
>(1) The destructor was not called.
>(2) The class deallocator was not called.
>
>Observe that the garbage collector WAS EXPLICITLY INVOKED, and that the variable 'a' was not reachable at the time the gc was run. This "destruction" is not merely lazy, it seems to be actually on vacation.
>
>Now, there are two possibilities. Either
>(a) This is correct behavior
>(b) This is a bug in the compiler
>
>If it's (a) I will need to think very hard to try to find a workaround. If I can't find one I will have to abandon my D project and write the thing in C++. If it's (b) then it's critical to me that the bug be fixed asap, because, again, this has to work, or D becomes useless for my purposes.
>
>
>


June 09, 2004
Try this:

>  int main()
>  {
>      {
>          auto A a = new A();
>          // use a here
>      }
>      // a's destructor should be called by this point
>      fullCollect();
>      return 0;
>  }

I haven't tested this firsthand, but it should have the effect of finalizing a when its enclosing scope terminates. (even if an exception is thrown)

 -- andy
June 09, 2004
Ivan Senji schrieb:

> Maybe i am missing something but is it out of the question to use
> delete a; ?

It is a question of *guarantees*. If a language with automatic memory management doesn't guarantee that destructors get called, it has to become a problem if more or less critical resources want to be managed in an advanced manner. And as shown, auto doesn't always help either.

-eye
June 09, 2004
In article <ca78n4$2mq2$1@digitaldaemon.com>, hellcatv@hotmail.com says...
>
>what if you explicitly call delete a; before setting it to null?

You are not the only person who has suggested this, however please, please understand that in the field in which I am working, this is simply not an option. Yes OF COURSE it is possible to explicitly call delete() - it's not like I hadn't thought of that. It's also possible to call a specially written function called wipeThisSensitiveDataNow().

But that would be missing the point.

A class which manages sensitive data *MUST* be capable of managing that resource completely, of preventing access to it except through authorized methods, and of securely erasing that sensitive data, REGARDLESS of what calls a user of that class does or does not make.

I could write pages and pages on this, on why it is important. But ... I'd rather that you trusted me that I know what I'm doing. This is my area of expertise. (Well, that and three decades of experience writing system software). Computer security is fraught with dangers. There are holes everywhere you look. One - single - omission ... could render sensitive data such as passwords, encryption keys, etc., open to an attacker. (Well, to an attacker who knows as much as I, anyway). And it could be YOUR data that is being protected by SOMEONE ELSE'S application built using MY toolkit. And THEY might not have called delete() (or even read the manual).

It's not that there's anything wrong with calling delete(). It's that I cannot rely on callers of my API doing that. And I have to guard against the possibility that they may not.

Fortunately, I am going to succeed, come what may. Even if I have to construct things on the stack (so that they can be routinely erased just by declaring a large array from time to time), I will find a way.

But all of this is irrelevant, and a side-issue. I can demonstrate, in a simple, repeatable experiment, that a destructor is not always called. So either this is correct behavior (in which case, fine, I'll figure out a way round it), or it's a bug (in which case, it is critical to anyone doing resource management that it be fixed). That's all.

I do recognise that you were trying to help though, and I do appreciate that. Arcane Jill


June 09, 2004
"Arcane Jill" <Arcane_member@pathlink.com> wrote in message news:ca7hnm$3ed$1@digitaldaemon.com...
> In article <ca78n4$2mq2$1@digitaldaemon.com>, hellcatv@hotmail.com says...
> >
> >what if you explicitly call delete a; before setting it to null?
>
> You are not the only person who has suggested this, however please, please understand that in the field in which I am working, this is simply not an option. Yes OF COURSE it is possible to explicitly call delete() - it's
not like
> I hadn't thought of that. It's also possible to call a specially written function called wipeThisSensitiveDataNow().
>
> But that would be missing the point.
>
> A class which manages sensitive data *MUST* be capable of managing that
resource
> completely, of preventing access to it except through authorized methods,
and of
> securely erasing that sensitive data, REGARDLESS of what calls a user of
that
> class does or does not make.
>
> I could write pages and pages on this, on why it is important. But ... I'd rather that you trusted me that I know what I'm doing. This is my area of expertise. (Well, that and three decades of experience writing system
software).
> Computer security is fraught with dangers. There are holes everywhere you
look.
> One - single - omission ... could render sensitive data such as passwords, encryption keys, etc., open to an attacker. (Well, to an attacker who
knows as
> much as I, anyway). And it could be YOUR data that is being protected by
SOMEONE
> ELSE'S application built using MY toolkit. And THEY might not have called
> delete() (or even read the manual).
>
> It's not that there's anything wrong with calling delete(). It's that I
cannot
> rely on callers of my API doing that. And I have to guard against the possibility that they may not.
>
> Fortunately, I am going to succeed, come what may. Even if I have to
construct
> things on the stack (so that they can be routinely erased just by
declaring a
> large array from time to time), I will find a way.
>
> But all of this is irrelevant, and a side-issue. I can demonstrate, in a
simple,
> repeatable experiment, that a destructor is not always called. So either
this is
> correct behavior (in which case, fine, I'll figure out a way round it), or
it's
> a bug (in which case, it is critical to anyone doing resource management
that it
> be fixed). That's all.
>
> I do recognise that you were trying to help though, and I do appreciate
that.
> Arcane Jill

Thanks for a good explanation :) I mada a mistake of thinking only about
your
code were you can make sure that you call delete, but i wasn't thinking
about
the user code, and now i see the problem.





« First   ‹ Prev
1 2