C++ delete operator undefined behavior
Ioi Lam
ioi.lam at oracle.com
Sat Feb 9 14:24:37 UTC 2019
On 2/9/19 4:36 AM, David Holmes wrote:
> Hi Ioi,
>
> On 9/02/2019 6:42 pm, Ioi Lam wrote:
>> I am getting a "ud2" instruction on the Mac for a 'delete'
>> expression. According to this page, it's clang flagging an undefined
>> behavior:
>>
>> https://stackoverflow.com/questions/21529308/why-does-clang-generate-ud2-opcode-on-osx
>>
>>
>> My code looks like this:
>>
>> class MetaspaceClosure {
>> class Ref : public ResourceObj {
>> ...
>> };
>>
>>
>> void push_impl(Ref* ref) {
>> if (_nest_level < MAX_NEST_LEVEL) {
>> do_push(ref);
>> delete ref;
>> } else {
>> ref->set_next(_pending_refs);
>> _pending_refs = ref;
>> }
>> }
>> };
>>
>> and clang generates this code
>>
>> libjvm.dylib`MetaspaceClosure::push_impl:
>> 0x10316db9c <+0>: pushq %rbp
>> 0x10316db9d <+1>: movq %rsp, %rbp
>> 0x10316dba0 <+4>: pushq %rbx
>> 0x10316dba1 <+5>: pushq %rax
>> 0x10316dba2 <+6>: movq %rsi, %rbx
>> 0x10316dba5 <+9>: cmpl $0x4, 0x10(%rdi)
>> 0x10316dba9 <+13>: jg 0x10316dbba
>> 0x10316dbab <+15>: movq %rbx, %rsi
>> 0x10316dbae <+18>: callq 0x10316dbce ; do_push()
>> 0x10316dbb3 <+23>: testq %rbx, %rbx
>> 0x10316dbb6 <+26>: je 0x10316dbc6
>> -> 0x10316dbb8 <+28>: ud2 <<<<<<<<<<<<<<<<<<<<<<< HERE
>> 0x10316dbba <+30>: movq 0x8(%rdi), %rax
>> 0x10316dbbe <+34>: movq %rax, 0x20(%rbx)
>> 0x10316dbc2 <+38>: movq %rbx, 0x8(%rdi)
>> 0x10316dbc6 <+42>: addq $0x8, %rsp
>> 0x10316dbca <+46>: popq %rbx
>> 0x10316dbcb <+47>: popq %rbp
>> 0x10316dbcc <+48>: retq
>> 0x10316dbcd <+49>: nop
>>
>> Shouldn't the 'delete' expression be translated to
>> ResourceObj::operator delete()?
>
> Are Ref's allocated on the C_heap? That's the only kind of resourceObj
> you can delete:
>
> void ResourceObj::operator delete(void* p) {
> assert(((ResourceObj *)p)->allocated_on_C_heap(),
> "delete only allowed for C_HEAP objects");
> DEBUG_ONLY(((ResourceObj *)p)->_allocation_t[0] =
> (uintptr_t)badHeapOopVal;)
> FreeHeap(p);
> }
>
I allocate them using
Ref *r = new (C_HEAP, mtInternal)Ref(....);
However, whether I do that or not isn't something that clang can deduce
statically to mark my 'delete' as having undefined behavior.
Thanks
- Ioi
> David
> -----
>
>> And I couldn't find any warning messages given by clang ....
>>
>> I rewrote the Ref class to inherit from CHeapObj<mtInternal> instead,
>> and it magically worked.
>>
>> However, but there's other use of 'delete' on ResourceObj (such as
>> ResourceHashtable) that seems to work just fine. Am I missing something?
>>
>> Thanks
>>
>> - Ioi
>>
>>
>>
More information about the hotspot-dev
mailing list