Brian Dessent | 2 Feb 2006 13:26
Favicon

[patch] fix spurious SIGSEGV faults under Cygwin


Recently Cygwin has changed the way that it internally checks arguments for bad
pointers.  Where before it used IsBad{Read,Write}Ptr() from the win32 API, now
it installs its own temporary SEH fault handler.  However, gdb is not aware of
this and so it leads to the program stopping on a SIGSEGV on perfectly
legitimate code -- when not run under the debugger, Cygwin's fault handler
catches the attempt and returns the appropriate error.  Here is a minimal
example:

$ cat ss.cc
#include <string>

int main()
{
  std::string foo;

  return 0;
}

$ g++ -g ss.cc -o ss

$ gdb --quiet ./ss
(gdb) r
Starting program: /tmp/false_sigsegv/ss.exe 

Program received signal SIGSEGV, Segmentation fault.
0x610af8b8 in pthread_key_create (key=0x482c08, destructor=0) at
/usr/src/sourceware/winsup/cygwin/thread.cc:129
129       if ((*object)->magic != magic)
(gdb) c
(Continue reading)

Brian Dessent | 2 Feb 2006 17:00
Favicon

Re: [patch] fix spurious SIGSEGV faults under Cygwin

Brian Dessent wrote:

>  #define _CYGWIN_SIGNAL_STRING "cYgSiGw00f"
> +#define _CYGWIN_FAULT_IGNORE_STRING "cYgfAuLtIg"
> +#define _CYGWIN_FAULT_NOIGNORE_STRING "cYgNofAuLtIg"

Sigh, this breaks strace under Cygwin, I should have tested more.  Sorry
about that.  Apparently strace expects anything starting with the 'cYg'
prefix to be followed by a hex number.  I thought that since
_CYGWIN_SIGNAL_STRING already existed and didn't follow that format it
was safe to add more, but that's not the case.

So, should I pick another prefix that's not 'cYg'?  Or instead use
something like "cYg0 ..." since strace seems to just ignore the string
if its value is 0?  Or something else?

Brian

Christopher Faylor | 2 Feb 2006 18:05
Favicon

Re: [patch] fix spurious SIGSEGV faults under Cygwin

On Thu, Feb 02, 2006 at 08:00:01AM -0800, Brian Dessent wrote:
>Brian Dessent wrote:
>
>>  #define _CYGWIN_SIGNAL_STRING "cYgSiGw00f"
>> +#define _CYGWIN_FAULT_IGNORE_STRING "cYgfAuLtIg"
>> +#define _CYGWIN_FAULT_NOIGNORE_STRING "cYgNofAuLtIg"
>
>Sigh, this breaks strace under Cygwin, I should have tested more.  Sorry
>about that.  Apparently strace expects anything starting with the 'cYg'
>prefix to be followed by a hex number.  I thought that since
>_CYGWIN_SIGNAL_STRING already existed and didn't follow that format it
>was safe to add more, but that's not the case.
>
>So, should I pick another prefix that's not 'cYg'?  Or instead use
>something like "cYg0 ..." since strace seems to just ignore the string
>if its value is 0?  Or something else?

Brian,
Thanks for the patch but I've been working on this too and, so far, I think
it is possible to have a very minimal way of dealing with this problem.  I
haven't had time to delve into it too deeply but I have been exploring this
problem on and off for a couple of weeks.  If the situation at work calms
down a little I may be able to finish up what I've been working on.

OTOH, if what I have is really not working then I'll take a look at what
you've done.

Again, thanks for the patch.  I probably should have sent a heads up that
I was working on this.

(Continue reading)

Brian Dessent | 2 Feb 2006 18:21
Favicon

Re: [patch] fix spurious SIGSEGV faults under Cygwin

Christopher Faylor wrote:

> Thanks for the patch but I've been working on this too and, so far, I think
> it is possible to have a very minimal way of dealing with this problem.  I
> haven't had time to delve into it too deeply but I have been exploring this
> problem on and off for a couple of weeks.  If the situation at work calms
> down a little I may be able to finish up what I've been working on.
> 
> OTOH, if what I have is really not working then I'll take a look at what
> you've done.

Okay, no rush.  FWIW after noticing that strace was broken I tested a
version that used

 #define _CYGWIN_SIGNAL_STRING "cYgSiGw00f"
+#define _CYGWIN_FAULT_IGNORE_STRING "cYg0 faultig"
+#define _CYGWIN_FAULT_NOIGNORE_STRING "cYg0 nofaultig"

...which seems to fix the problem since the strtold() just picks up 0
after 'cYg' and strace ignores the rest.

The main problem I see with this approach is the extra call to
IsDebuggerPresent() every time a 'myfault' is created/destroyed, which
potentially could be a lot.  I'm presuming this is a relatively cheap
call so it wasn't something I worried too much about.  But then I didn't
actually try to measure it.

If it turns out that it's expensive, I was thinking that the inferior
could maintain this information in some variable, and just communicate
its location to gdb once at startup, then gdb could simply read that
(Continue reading)

Dave Korn | 2 Feb 2006 18:30
Favicon

RE: [patch] fix spurious SIGSEGV faults under Cygwin

On 02 February 2006 17:21, Brian Dessent wrote:

> The main problem I see with this approach is the extra call to
> IsDebuggerPresent() every time a 'myfault' is created/destroyed, which
> potentially could be a lot.  I'm presuming this is a relatively cheap
> call so it wasn't something I worried too much about.  But then I didn't
> actually try to measure it.   
> 
> If it turns out that it's expensive, I was thinking that the inferior
> could maintain this information in some variable, and just communicate
> its location to gdb once at startup, then gdb could simply read that
> variable in the process' memory before deciding whether to handle the
> fault.

  ?????!

  I'm having a conceptual difficulty here: Under what circumstances would you expect there *not* to be a
debugger attached to the
inferior to which the debugger is attached?  That's a bit zen, isn't it?

  Or IOW if a debugger is going to read a variable from its inferior that says if there's a debugger attached,
well... it might as
well be #defined to 1 in the gdb source code, mightn't it?

    cheers,
      DaveK
--

-- 
Can't think of a witty .sigline today....

(Continue reading)

Daniel Jacobowitz | 2 Feb 2006 18:38

Re: [patch] fix spurious SIGSEGV faults under Cygwin

On Thu, Feb 02, 2006 at 05:30:23PM -0000, Dave Korn wrote:
>   ?????!
> 
>   I'm having a conceptual difficulty here: Under what circumstances
> would you expect there *not* to be a debugger attached to the
> inferior to which the debugger is attached?  That's a bit zen, isn't
> it?

You missed that half the patch was for Cygwin - you even sent your
reply to cygwin-patches.

--

-- 
Daniel Jacobowitz
CodeSourcery

Brian Dessent | 2 Feb 2006 18:41
Favicon

Re: [patch] fix spurious SIGSEGV faults under Cygwin

Dave Korn wrote:

>   I'm having a conceptual difficulty here: Under what circumstances would you expect there *not* to be a
debugger attached to the
> inferior to which the debugger is attached?  That's a bit zen, isn't it?

The code in question here runs many times in the normal course of any
Cygwin program -- debugger or no.  The idea behind guarding the call to
OutputDebugString() with "if (being_debugged())" was that the call to
IsDebuggerPresent() was cheaper than the call to OutputDebugString(),
and that a well-behaived, non-debug build of a binary should not
needlessly send tons and tons of nonsense to OutputDebugString unless
it's actually being debugged and there is something there to interpret
the nonsense.

Brian

Dave Korn | 2 Feb 2006 18:43
Favicon

RE: [patch] fix spurious SIGSEGV faults under Cygwin

On 02 February 2006 17:38, Daniel Jacobowitz wrote:

> On Thu, Feb 02, 2006 at 05:30:23PM -0000, Dave Korn wrote:
>>   ?????!
>> 
>>   I'm having a conceptual difficulty here: Under what circumstances
>> would you expect there *not* to be a debugger attached to the inferior
>> to which the debugger is attached?  That's a bit zen, isn't it?
> 
> You missed that half the patch was for Cygwin - you even sent your reply
> to cygwin-patches. 

  Nope, I didn't miss that bit.  I can see the point in the cygwin side of the patch, for when there _isn't_ a
debugger attached,
and the cygwin library has to know whether the exception will be handled by a debugger or whether it has to
wrap the access in a
SEH.

  What I can't see is any point in gdb reading a variable from the inferior that tells gdb if there is a debugger
attached to the
inferior, because I can't see how gdb could read that variable except by attaching to the inferior, at which
point the value in the
variable should always be 'true', shouldn't it? 

    cheers,
      DaveK
--

-- 
Can't think of a witty .sigline today....

(Continue reading)

'Daniel Jacobowitz' | 2 Feb 2006 18:46

Re: [patch] fix spurious SIGSEGV faults under Cygwin

On Thu, Feb 02, 2006 at 05:43:51PM -0000, Dave Korn wrote:
>   What I can't see is any point in gdb reading a variable from the
> inferior that tells gdb if there is a debugger attached to the
> inferior, because I can't see how gdb could read that variable except
> by attaching to the inferior, at which point the value in the
> variable should always be 'true', shouldn't it?

He wrote:

> If it turns out that it's expensive, I was thinking that the inferior
> could maintain this information in some variable, and just communicate
> its location to gdb once at startup, then gdb could simply read that
> variable in the process' memory before deciding whether to handle the
> fault.

"this information" does not refer to "if there is a debugger attached".

--

-- 
Daniel Jacobowitz
CodeSourcery

Dave Korn | 2 Feb 2006 18:47
Favicon

RE: [patch] fix spurious SIGSEGV faults under Cygwin

On 02 February 2006 17:42, Brian Dessent wrote:

> Dave Korn wrote:
> 
>>   I'm having a conceptual difficulty here: Under what circumstances
>> would you expect there *not* to be a debugger attached to the inferior
>> to which the debugger is attached?  That's a bit zen, isn't it? 
> 
> The code in question here runs many times in the normal course of any
> Cygwin program -- debugger or no.  The idea behind guarding the call to 
> OutputDebugString() with "if (being_debugged())" was that the call to
> IsDebuggerPresent() was cheaper than the call to OutputDebugString(), and
> that a well-behaived, non-debug build of a binary should not needlessly
> send tons and tons of nonsense to OutputDebugString unless it's actually
> being debugged and there is something there to interpret the nonsense.   

  Um, that's two people now who thought I was referring to the cygwin side of the patch.

  No, this is the bit of your post that I was replying to:

"then gdb could simply read that variable in the process' memory before deciding whether to handle the
fault. "

  Is it the case that IsDebuggerPresent doesn't detect when gdb is attached?

    cheers,
      DaveK
--

-- 
Can't think of a witty .sigline today....

(Continue reading)


Gmane