nvptx abort implementation

Tom de Vries Tom_deVries@mentor.com
Wed May 2 17:37:00 GMT 2018


Hi,

I.

atm, abort for nvptx is implemented here ( 
newlib/libc/machine/nvptx/abort.c ) as:
...
void __attribute__((noreturn))
abort (void)
{
   for (;;)
     __builtin_trap ();
}
...

The __builtin_trap function is considered noreturn by gcc, so early in 
the compiler the loop is removed, even at -O0. So, this is equivalent to 
the shorter:
...
void __attribute__((noreturn))
abort (void)
{
   __builtin_trap ();
}
...


II.

Then, the nvptx port of gcc implements __builtin_trap using the 'trap' 
ptx insn.

The trap insn is documented in the ptx documentation as:
...
Abort execution and generate an interrupt to the host CPU.
...

After consulting with nvidia when running into unexpected behaviour we 
found out that in fact the ptx compilers (ptxas and the JIT in the 
drivers) do not consider trap a noreturn insn, and that a trap handler 
may return, and advised us to add an 'exit' after the trap. I've asked 
them to improve the ptx documentation (the abort is somewhat 
misleading), but sofar no luck there.

So, in fact nvptx __builtin_trap can return, which is a gcc bug, that I 
still need to file and fix.


III.

As for newlib, the ptx currently generated is:
...
.visible .func abort
{
   trap;
}
...

Based on the possibly-returning property of trap, we could expect 
execution of random code after the trap. But, as it happens, the 
translation from ptx to SASS adds an implicit 'ret' after the trap:
...
.text.abort:
         /*0008*/                   BPT.TRAP 0x1;
         /*0010*/                   RET;
...

So once we return from the abort we run into one more trap and an exit:
...
call abort;
trap; // (noreturn)
exit; // (noreturn)
...
which would then effectively abort.


IV.

I'd prefer a robust abort implementation that:
- does not depend on the __builtin_trap gcc bug being fixed, and
- does not depend on the ptx to SASS translation inserting a ret
   at the end of the function (given that there's nothing in the ptx
   documentation to suggest that this is guaranteed behaviour)
- does not depend on the noreturn calls being trailed by trap and exit

So, I'm thinking of:
...
void __attribute__((noreturn))
abort (void)
{
   asm ("trap; exit;" ::: "memory");
   while (1)
     ;
}
...

The while-true is there to prevent the warning "‘noreturn’ function does 
return".

I'll prepare a patch for this and test it.

Thanks,
- Tom



More information about the Newlib mailing list