www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 5517] New: SEGV: assert(false) in release mode

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5517

           Summary: SEGV: assert(false) in release mode
           Product: D
           Version: D1 & D2
          Platform: x86
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: ibuclaw ubuntu.com



void main() {
    assert(0);
}


When compiled in release mode, the instructions outputted by DMD cause a
segfault and exit code 139 (on Linux). I expected an abort and exit code 134.


$ dmd abort.d -release
$ ./abort 
Segmentation fault (core dumped)
$ echo $?
139


Disassembly of section .text._Dmain:

00000000 <_Dmain>:
void main() {
   0:    55                       push   %ebp
   1:    8b ec                    mov    %esp,%ebp
   3:    f4                       hlt    


Regards

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 02 2011
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5517


Don <clugdbug yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |clugdbug yahoo.com.au
          Component|DMD                         |druntime



The generated code is correct. Looks like a druntime bug to me. My guess is
that it's segfaulting while processing the HLT. Reassigning to druntime.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 02 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5517




Some further detail: 0xF4, the HLT opcode, is a privileged instruction; it
doesn't actually get executed. Instead, a Privileged Instruction hardware
exception is raised. I would expect Linux to turn this into SIGILL. So I would
expect an exit code of 132, if nothing is done to process it. There is no way
it should give a SEGV.

On Windows, druntime checks the offending instruction, and if it is HLT, it is
identified as a runtime assert(0).

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 03 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5517





 Some further detail: 0xF4, the HLT opcode, is a privileged instruction; it
 doesn't actually get executed. Instead, a Privileged Instruction hardware
 exception is raised. I would expect Linux to turn this into SIGILL. So I would
 expect an exit code of 132, if nothing is done to process it. There is no way
 it should give a SEGV.
If I was going off what I recall, I would have said that when a program receives the hlt instruction; it just stops executing instructions until there is an interrupt (in other words it just floats off in an undefined space). But I've looked it up, and HLT invokes SIGSEGV signal afterall...
 On Windows, druntime checks the offending instruction, and if it is HLT, it is
 identified as a runtime assert(0).
So on Windows, the runtime has a bespoke signal handler? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 05 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5517






 Some further detail: 0xF4, the HLT opcode, is a privileged instruction; it
 doesn't actually get executed. Instead, a Privileged Instruction hardware
 exception is raised. I would expect Linux to turn this into SIGILL. So I would
 expect an exit code of 132, if nothing is done to process it. There is no way
 it should give a SEGV.
If I was going off what I recall, I would have said that when a program receives the hlt instruction; it just stops executing instructions until there is an interrupt (in other words it just floats off in an undefined space).
That's what it does in ring 0 (ie, inside the kernel). But outside the kernel, it's a privileged instruction, which generates a hardware 'illegal instruction' interrupt.
 But I've looked it up, and HLT invokes SIGSEGV signal afterall...
Wow. Then Linux is just wrong. It should definitely be SIGILL. There's no memory access violation.
 On Windows, druntime checks the offending instruction, and if it is HLT, it is
 identified as a runtime assert(0).
So on Windows, the runtime has a bespoke signal handler?
Everything you'd call a signal on Linux, is just a system exception on Windows. D's exception handling uses the exact same mechanism. On all platforms, main is surrounded by a catch(...) which displays error messages from any uncaught exceptions. On Windows, this includes hardware faults as well as D-generated exceptions. The impression I get from the little I know of Unix signal handling, it seems to be one of the few things that Unix got horribly wrong. Windows structured exception handling is brilliant (albeit almost completely undocumented!) I am extremely impressed with it. For example, there's no restrictions on what you can do inside an exception handler. So there's probably more challenges for the *nix implementation of a lot of this stuff. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 05 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5517







 Some further detail: 0xF4, the HLT opcode, is a privileged instruction; it
 doesn't actually get executed. Instead, a Privileged Instruction hardware
 exception is raised. I would expect Linux to turn this into SIGILL. So I would
 expect an exit code of 132, if nothing is done to process it. There is no way
 it should give a SEGV.
If I was going off what I recall, I would have said that when a program receives the hlt instruction; it just stops executing instructions until there is an interrupt (in other words it just floats off in an undefined space).
That's what it does in ring 0 (ie, inside the kernel). But outside the kernel, it's a privileged instruction, which generates a hardware 'illegal instruction' interrupt.
 But I've looked it up, and HLT invokes SIGSEGV signal afterall...
Wow. Then Linux is just wrong. It should definitely be SIGILL. There's no memory access violation.
Well, signals are != exceptions. :)
 On Windows, druntime checks the offending instruction, and if it is HLT, it is
 identified as a runtime assert(0).
So on Windows, the runtime has a bespoke signal handler?
Everything you'd call a signal on Linux, is just a system exception on Windows. D's exception handling uses the exact same mechanism. On all platforms, main is surrounded by a catch(...) which displays error messages from any uncaught exceptions. On Windows, this includes hardware faults as well as D-generated exceptions. The impression I get from the little I know of Unix signal handling, it seems to be one of the few things that Unix got horribly wrong. Windows structured exception handling is brilliant (albeit almost completely undocumented!) I am extremely impressed with it. For example, there's no restrictions on what you can do inside an exception handler. So there's probably more challenges for the *nix implementation of a lot of this stuff.
There are 2 alternatives I can think of instead of using 'hlt' 1) Throw an exception (goes against release mode). 2) Raise an alternate interrupt. Like 'hlt', these are single byte opcodes. - int 0x3; #BP will invoke SIGTRAP signal handler. - ud2; #UD will invoke SIGILL signal handler. Regards -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 06 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5517








 Some further detail: 0xF4, the HLT opcode, is a privileged instruction; it
 doesn't actually get executed. Instead, a Privileged Instruction hardware
 exception is raised. I would expect Linux to turn this into SIGILL. So I would
 expect an exit code of 132, if nothing is done to process it. There is no way
 it should give a SEGV.
If I was going off what I recall, I would have said that when a program receives the hlt instruction; it just stops executing instructions until there is an interrupt (in other words it just floats off in an undefined space).
That's what it does in ring 0 (ie, inside the kernel). But outside the kernel, it's a privileged instruction, which generates a hardware 'illegal instruction' interrupt.
 But I've looked it up, and HLT invokes SIGSEGV signal afterall...
Wow. Then Linux is just wrong. It should definitely be SIGILL. There's no memory access violation.
Well, signals are != exceptions. :)
Even if you have that opinion, HLT is not a segfault. If Linux does the stupidity of treating privileged instruction violations as segfaults (are you CERTAIN it does? It's really hard to believe), then we shouldn't try to cover up that stupidity by pretend that SIGSEGV only ever means a segfault. Does it really report a segfault on this code? void main() { asm { hlt; } }
 There are 2 alternatives I can think of instead of using 'hlt'
 
 1) Throw an exception (goes against release mode).
 
 2) Raise an alternate interrupt. Like 'hlt', these are single byte opcodes.
 
 - int 0x3;  #BP will invoke SIGTRAP signal handler.
 - ud2;      #UD will invoke SIGILL signal handler.
 
 Regards
The first one won't work -- it defeats the ENTIRE PURPOSE of the feature. The second one's really, really wrong, and I can't see that it would even be an improvement. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 06 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5517


Jonathan M Davis <jmdavisProg gmx.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jmdavisProg gmx.com



PST ---
Well, if I run tho short program that Don provides there on my Linux box, it
definitely prints out "Segmentation fault" on the command line. So, whatever
signals end up being sent, that's how bash reports it.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 06 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5517




Some notes:

- sigaction can be used to catch signals
- signals caught have a packed struct with some simple information attached.
 - si_signo: Signal number (ie: SIGSEGV = 11).
 - si_errno: Errno value (unused on Linux).
 - si_code: Signal code to indicate why this signal was sent.

- The two possible signal codes related to SIGSEGV signals are:
 - SEGV_MAPERR: address not mapped to object
 - SEGV_ACCERR: invalid permissions for mapped object

- General purpose signal codes tell how the signal was raised:
 - SI_USER:    kill, sigsend or raise
 - SI_KERNEL:  The kernel
 - SI_QUEUE:   sigqueue
 - SI_TIMER:   timer expired
 - SI_MESGQ:   mesq state changed
 - SI_ASYNCIO: AIO completed
 - SI_SIGIO:   queued SIGIO

- HLT is emitted from the kernel (SI_KERNEL).


Here is a quick sample program:

import core.stdc.stdio;
import core.sys.posix.unistd;
import core.sys.posix.signal;

extern(C) void signal_handler(int signum, siginfo_t* info, void* ptr)
{
    if (info.si_signo == SIGSEGV && info.si_code == SI_KERNEL)
    {
        fprintf(stderr, "assert(0) or SEGV sent by kernel\n");
        _exit(signum);
    }
}

void main()
{
    sigaction_t action;
    action.sa_flags = SA_SIGINFO | SA_RESETHAND;
    action.sa_sigaction = &signal_handler;
    sigaction(SIGSEGV, &action, null);
    assert(0);
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 09 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5517


Walter Bright <bugzilla digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |bugzilla digitalmars.com
         Resolution|                            |INVALID



15:19:50 PST ---
Quoth the spec:

"The expression assert(0) is a special case; it signifies that it is
unreachable code. Either AssertError is thrown at runtime if it is reachable,
or the execution is halted (on the x86 processor, a HLT instruction can be used
to halt execution). The optimization and code generation phases of compilation
may assume that it is unreachable code."

It's working as designed.

dlang.org/expression.html#AssertExpression

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 28 2012
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5517


Alexander Tankeev <atankeev gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |atankeev gmail.com



PST ---
*** Issue 9134 has been marked as a duplicate of this issue. ***

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 01 2013