public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* Re: GDB internal error in pc_in_thread_step_range
       [not found] ` <100001f1b27aa7d90902a75d5db37710@polymtl.ca>
@ 2018-11-18 16:37   ` Eli Zaretskii
  2018-11-30 13:42     ` Eli Zaretskii
  2018-12-16  3:58     ` Simon Marchi
  0 siblings, 2 replies; 25+ messages in thread
From: Eli Zaretskii @ 2018-11-18 16:37 UTC (permalink / raw)
  To: Simon Marchi; +Cc: gdb-patches

> Date: Mon, 20 Aug 2018 11:08:27 -0400
> From: Simon Marchi <simon.marchi@polymtl.ca>
> Cc: gdb@sourceware.org

A reminder: this is about an internal GDB error that happens on MinGW
whenever I step out of the 'main' function.

> >   Temporary breakpoint 1, main () at hello.c:8
> >   8         printf("hello, world!");
> >   (gdb) n
> >   hello, world!9    return 0;
> >   (gdb)
> >   10      }
> >   (gdb)
> >   0x0040126d in __register_frame_info ()
> >   (gdb)
> >   Single stepping until exit from function __register_frame_info,
> >   which has no line number information.
> >   infrun.c:2728: internal-error: void resume_1(gdb_signal): Assertion
> > `pc_in_thread_step_range (pc, tp)' failed.
> >   A problem internal to GDB has been detected,
> >   further debugging may prove unreliable.
> >   Quit this debugging session? (y or n)
> > 
> > Is it a known problem?
> 
> Not that I know of.

I finally got to debugging this.  It happens because:

  2723          gdb_assert (pc_in_thread_step_range (pc, tp));
  (top-gdb) p tp->control
  $22 = {step_resume_breakpoint = 0x0, exception_resume_breakpoint = 0x0,
    single_step_breakpoints = 0x0, step_range_start = 0x0,
    step_range_end = 0x1, step_start_function = 0x0, may_range_step = 1,
    step_frame_id = {stack_addr = 0x28ff70, code_addr = 0x0,
      special_addr = 0x0, stack_status = FID_STACK_VALID, code_addr_p = 1,
      special_addr_p = 0, artificial_depth = 0}, step_stack_frame_id = {
      stack_addr = 0x28ff70, code_addr = 0x0, special_addr = 0x0,
      stack_status = FID_STACK_VALID, code_addr_p = 1, special_addr_p = 0,
      artificial_depth = 0}, trap_expected = 0, proceed_to_finish = 0,
    in_infcall = 0, step_over_calls = STEP_OVER_ALL, stop_step = 0,
    stop_bpstat = 0x0, stepping_command = 1}

The step_range_start is zero and step_range_end is 1, which of course
will not match any value of PC.

What happens here is that step_1 first zeroes out these members, and
then fills them by calling find_pc_line_pc_range, called from
prepare_one_step.  But when I step out of the main program into the
library epilogue code, there's no line information, and
prepare_one_step calls find_pc_partial_function, which also doesn't
find any addresses.  So we fill these members with zero and 1:

  if (address)
    {
      if (pc_in_unmapped_range (pc, section))
	*address = overlay_unmapped_address (cache_pc_function_low, section);
      else
	*address = cache_pc_function_low;
    }

  if (name)
    *name = cache_pc_function_name;

  if (endaddr)
    {
      if (pc_in_unmapped_range (pc, section))
	{
	  /* Because the high address is actually beyond the end of
	     the function (and therefore possibly beyond the end of
	     the overlay), we must actually convert (high - 1) and
	     then add one to that.  */

	  *endaddr = 1 + overlay_unmapped_address (cache_pc_function_high - 1,
						   section);
	}
      else
	*endaddr = cache_pc_function_high;
    }

The cached values are zero and 1, correspondingly.

Any suggestions for how to fix this?  One way would be to avoid
triggering the assertion of the addresses are these two specific bogus
values.  Alternatively, perhaps the cached values in
find_pc_partial_function should be more useful, but in that case I'd
need guidance as to where and how are they supposed to be assigned, so
that I could look into why they don't in this case.

TIA

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: GDB internal error in pc_in_thread_step_range
  2018-11-18 16:37   ` GDB internal error in pc_in_thread_step_range Eli Zaretskii
@ 2018-11-30 13:42     ` Eli Zaretskii
  2018-12-07  7:22       ` Eli Zaretskii
  2018-12-16  3:58     ` Simon Marchi
  1 sibling, 1 reply; 25+ messages in thread
From: Eli Zaretskii @ 2018-11-30 13:42 UTC (permalink / raw)
  To: simon.marchi; +Cc: gdb-patches

Ping!

> Date: Sun, 18 Nov 2018 18:37:13 +0200
> From: Eli Zaretskii <eliz@gnu.org>
> CC: gdb-patches@sourceware.org
> 
> > Date: Mon, 20 Aug 2018 11:08:27 -0400
> > From: Simon Marchi <simon.marchi@polymtl.ca>
> > Cc: gdb@sourceware.org
> 
> A reminder: this is about an internal GDB error that happens on MinGW
> whenever I step out of the 'main' function.
> 
> > >   Temporary breakpoint 1, main () at hello.c:8
> > >   8         printf("hello, world!");
> > >   (gdb) n
> > >   hello, world!9    return 0;
> > >   (gdb)
> > >   10      }
> > >   (gdb)
> > >   0x0040126d in __register_frame_info ()
> > >   (gdb)
> > >   Single stepping until exit from function __register_frame_info,
> > >   which has no line number information.
> > >   infrun.c:2728: internal-error: void resume_1(gdb_signal): Assertion
> > > `pc_in_thread_step_range (pc, tp)' failed.
> > >   A problem internal to GDB has been detected,
> > >   further debugging may prove unreliable.
> > >   Quit this debugging session? (y or n)
> > > 
> > > Is it a known problem?
> > 
> > Not that I know of.
> 
> I finally got to debugging this.  It happens because:
> 
>   2723          gdb_assert (pc_in_thread_step_range (pc, tp));
>   (top-gdb) p tp->control
>   $22 = {step_resume_breakpoint = 0x0, exception_resume_breakpoint = 0x0,
>     single_step_breakpoints = 0x0, step_range_start = 0x0,
>     step_range_end = 0x1, step_start_function = 0x0, may_range_step = 1,
>     step_frame_id = {stack_addr = 0x28ff70, code_addr = 0x0,
>       special_addr = 0x0, stack_status = FID_STACK_VALID, code_addr_p = 1,
>       special_addr_p = 0, artificial_depth = 0}, step_stack_frame_id = {
>       stack_addr = 0x28ff70, code_addr = 0x0, special_addr = 0x0,
>       stack_status = FID_STACK_VALID, code_addr_p = 1, special_addr_p = 0,
>       artificial_depth = 0}, trap_expected = 0, proceed_to_finish = 0,
>     in_infcall = 0, step_over_calls = STEP_OVER_ALL, stop_step = 0,
>     stop_bpstat = 0x0, stepping_command = 1}
> 
> The step_range_start is zero and step_range_end is 1, which of course
> will not match any value of PC.
> 
> What happens here is that step_1 first zeroes out these members, and
> then fills them by calling find_pc_line_pc_range, called from
> prepare_one_step.  But when I step out of the main program into the
> library epilogue code, there's no line information, and
> prepare_one_step calls find_pc_partial_function, which also doesn't
> find any addresses.  So we fill these members with zero and 1:
> 
>   if (address)
>     {
>       if (pc_in_unmapped_range (pc, section))
> 	*address = overlay_unmapped_address (cache_pc_function_low, section);
>       else
> 	*address = cache_pc_function_low;
>     }
> 
>   if (name)
>     *name = cache_pc_function_name;
> 
>   if (endaddr)
>     {
>       if (pc_in_unmapped_range (pc, section))
> 	{
> 	  /* Because the high address is actually beyond the end of
> 	     the function (and therefore possibly beyond the end of
> 	     the overlay), we must actually convert (high - 1) and
> 	     then add one to that.  */
> 
> 	  *endaddr = 1 + overlay_unmapped_address (cache_pc_function_high - 1,
> 						   section);
> 	}
>       else
> 	*endaddr = cache_pc_function_high;
>     }
> 
> The cached values are zero and 1, correspondingly.
> 
> Any suggestions for how to fix this?  One way would be to avoid
> triggering the assertion of the addresses are these two specific bogus
> values.  Alternatively, perhaps the cached values in
> find_pc_partial_function should be more useful, but in that case I'd
> need guidance as to where and how are they supposed to be assigned, so
> that I could look into why they don't in this case.
> 
> TIA
> 

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: GDB internal error in pc_in_thread_step_range
  2018-11-30 13:42     ` Eli Zaretskii
@ 2018-12-07  7:22       ` Eli Zaretskii
  2018-12-15 12:07         ` Eli Zaretskii
  0 siblings, 1 reply; 25+ messages in thread
From: Eli Zaretskii @ 2018-12-07  7:22 UTC (permalink / raw)
  To: simon.marchi; +Cc: gdb-patches

Ping!  Ping!

I'd really like to fix this problem for the next GDB release.  Can
someone please review my findings and suggest a way of solving this?

Thanks.

> Date: Fri, 30 Nov 2018 15:42:27 +0200
> From: Eli Zaretskii <eliz@gnu.org>
> CC: gdb-patches@sourceware.org
> 
> Ping!
> 
> > Date: Sun, 18 Nov 2018 18:37:13 +0200
> > From: Eli Zaretskii <eliz@gnu.org>
> > CC: gdb-patches@sourceware.org
> > 
> > > Date: Mon, 20 Aug 2018 11:08:27 -0400
> > > From: Simon Marchi <simon.marchi@polymtl.ca>
> > > Cc: gdb@sourceware.org
> > 
> > A reminder: this is about an internal GDB error that happens on MinGW
> > whenever I step out of the 'main' function.
> > 
> > > >   Temporary breakpoint 1, main () at hello.c:8
> > > >   8         printf("hello, world!");
> > > >   (gdb) n
> > > >   hello, world!9    return 0;
> > > >   (gdb)
> > > >   10      }
> > > >   (gdb)
> > > >   0x0040126d in __register_frame_info ()
> > > >   (gdb)
> > > >   Single stepping until exit from function __register_frame_info,
> > > >   which has no line number information.
> > > >   infrun.c:2728: internal-error: void resume_1(gdb_signal): Assertion
> > > > `pc_in_thread_step_range (pc, tp)' failed.
> > > >   A problem internal to GDB has been detected,
> > > >   further debugging may prove unreliable.
> > > >   Quit this debugging session? (y or n)
> > > > 
> > > > Is it a known problem?
> > > 
> > > Not that I know of.
> > 
> > I finally got to debugging this.  It happens because:
> > 
> >   2723          gdb_assert (pc_in_thread_step_range (pc, tp));
> >   (top-gdb) p tp->control
> >   $22 = {step_resume_breakpoint = 0x0, exception_resume_breakpoint = 0x0,
> >     single_step_breakpoints = 0x0, step_range_start = 0x0,
> >     step_range_end = 0x1, step_start_function = 0x0, may_range_step = 1,
> >     step_frame_id = {stack_addr = 0x28ff70, code_addr = 0x0,
> >       special_addr = 0x0, stack_status = FID_STACK_VALID, code_addr_p = 1,
> >       special_addr_p = 0, artificial_depth = 0}, step_stack_frame_id = {
> >       stack_addr = 0x28ff70, code_addr = 0x0, special_addr = 0x0,
> >       stack_status = FID_STACK_VALID, code_addr_p = 1, special_addr_p = 0,
> >       artificial_depth = 0}, trap_expected = 0, proceed_to_finish = 0,
> >     in_infcall = 0, step_over_calls = STEP_OVER_ALL, stop_step = 0,
> >     stop_bpstat = 0x0, stepping_command = 1}
> > 
> > The step_range_start is zero and step_range_end is 1, which of course
> > will not match any value of PC.
> > 
> > What happens here is that step_1 first zeroes out these members, and
> > then fills them by calling find_pc_line_pc_range, called from
> > prepare_one_step.  But when I step out of the main program into the
> > library epilogue code, there's no line information, and
> > prepare_one_step calls find_pc_partial_function, which also doesn't
> > find any addresses.  So we fill these members with zero and 1:
> > 
> >   if (address)
> >     {
> >       if (pc_in_unmapped_range (pc, section))
> > 	*address = overlay_unmapped_address (cache_pc_function_low, section);
> >       else
> > 	*address = cache_pc_function_low;
> >     }
> > 
> >   if (name)
> >     *name = cache_pc_function_name;
> > 
> >   if (endaddr)
> >     {
> >       if (pc_in_unmapped_range (pc, section))
> > 	{
> > 	  /* Because the high address is actually beyond the end of
> > 	     the function (and therefore possibly beyond the end of
> > 	     the overlay), we must actually convert (high - 1) and
> > 	     then add one to that.  */
> > 
> > 	  *endaddr = 1 + overlay_unmapped_address (cache_pc_function_high - 1,
> > 						   section);
> > 	}
> >       else
> > 	*endaddr = cache_pc_function_high;
> >     }
> > 
> > The cached values are zero and 1, correspondingly.
> > 
> > Any suggestions for how to fix this?  One way would be to avoid
> > triggering the assertion of the addresses are these two specific bogus
> > values.  Alternatively, perhaps the cached values in
> > find_pc_partial_function should be more useful, but in that case I'd
> > need guidance as to where and how are they supposed to be assigned, so
> > that I could look into why they don't in this case.
> > 
> > TIA
> > 
> 

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: GDB internal error in pc_in_thread_step_range
  2018-12-07  7:22       ` Eli Zaretskii
@ 2018-12-15 12:07         ` Eli Zaretskii
  0 siblings, 0 replies; 25+ messages in thread
From: Eli Zaretskii @ 2018-12-15 12:07 UTC (permalink / raw)
  To: simon.marchi; +Cc: gdb-patches

Ping!  Ping!  Ping!

I'd really like to fix this problem for the next GDB release.  Can
someone please review my findings and suggest a way of solving this?

Thanks.

> Date: Fri, 07 Dec 2018 09:21:58 +0200
> From: Eli Zaretskii <eliz@gnu.org>
> CC: gdb-patches@sourceware.org
> 
> Ping!  Ping!
> 
> I'd really like to fix this problem for the next GDB release.  Can
> someone please review my findings and suggest a way of solving this?
> 
> Thanks.
> 
> > Date: Fri, 30 Nov 2018 15:42:27 +0200
> > From: Eli Zaretskii <eliz@gnu.org>
> > CC: gdb-patches@sourceware.org
> > 
> > Ping!
> > 
> > > Date: Sun, 18 Nov 2018 18:37:13 +0200
> > > From: Eli Zaretskii <eliz@gnu.org>
> > > CC: gdb-patches@sourceware.org
> > > 
> > > > Date: Mon, 20 Aug 2018 11:08:27 -0400
> > > > From: Simon Marchi <simon.marchi@polymtl.ca>
> > > > Cc: gdb@sourceware.org
> > > 
> > > A reminder: this is about an internal GDB error that happens on MinGW
> > > whenever I step out of the 'main' function.
> > > 
> > > > >   Temporary breakpoint 1, main () at hello.c:8
> > > > >   8         printf("hello, world!");
> > > > >   (gdb) n
> > > > >   hello, world!9    return 0;
> > > > >   (gdb)
> > > > >   10      }
> > > > >   (gdb)
> > > > >   0x0040126d in __register_frame_info ()
> > > > >   (gdb)
> > > > >   Single stepping until exit from function __register_frame_info,
> > > > >   which has no line number information.
> > > > >   infrun.c:2728: internal-error: void resume_1(gdb_signal): Assertion
> > > > > `pc_in_thread_step_range (pc, tp)' failed.
> > > > >   A problem internal to GDB has been detected,
> > > > >   further debugging may prove unreliable.
> > > > >   Quit this debugging session? (y or n)
> > > > > 
> > > > > Is it a known problem?
> > > > 
> > > > Not that I know of.
> > > 
> > > I finally got to debugging this.  It happens because:
> > > 
> > >   2723          gdb_assert (pc_in_thread_step_range (pc, tp));
> > >   (top-gdb) p tp->control
> > >   $22 = {step_resume_breakpoint = 0x0, exception_resume_breakpoint = 0x0,
> > >     single_step_breakpoints = 0x0, step_range_start = 0x0,
> > >     step_range_end = 0x1, step_start_function = 0x0, may_range_step = 1,
> > >     step_frame_id = {stack_addr = 0x28ff70, code_addr = 0x0,
> > >       special_addr = 0x0, stack_status = FID_STACK_VALID, code_addr_p = 1,
> > >       special_addr_p = 0, artificial_depth = 0}, step_stack_frame_id = {
> > >       stack_addr = 0x28ff70, code_addr = 0x0, special_addr = 0x0,
> > >       stack_status = FID_STACK_VALID, code_addr_p = 1, special_addr_p = 0,
> > >       artificial_depth = 0}, trap_expected = 0, proceed_to_finish = 0,
> > >     in_infcall = 0, step_over_calls = STEP_OVER_ALL, stop_step = 0,
> > >     stop_bpstat = 0x0, stepping_command = 1}
> > > 
> > > The step_range_start is zero and step_range_end is 1, which of course
> > > will not match any value of PC.
> > > 
> > > What happens here is that step_1 first zeroes out these members, and
> > > then fills them by calling find_pc_line_pc_range, called from
> > > prepare_one_step.  But when I step out of the main program into the
> > > library epilogue code, there's no line information, and
> > > prepare_one_step calls find_pc_partial_function, which also doesn't
> > > find any addresses.  So we fill these members with zero and 1:
> > > 
> > >   if (address)
> > >     {
> > >       if (pc_in_unmapped_range (pc, section))
> > > 	*address = overlay_unmapped_address (cache_pc_function_low, section);
> > >       else
> > > 	*address = cache_pc_function_low;
> > >     }
> > > 
> > >   if (name)
> > >     *name = cache_pc_function_name;
> > > 
> > >   if (endaddr)
> > >     {
> > >       if (pc_in_unmapped_range (pc, section))
> > > 	{
> > > 	  /* Because the high address is actually beyond the end of
> > > 	     the function (and therefore possibly beyond the end of
> > > 	     the overlay), we must actually convert (high - 1) and
> > > 	     then add one to that.  */
> > > 
> > > 	  *endaddr = 1 + overlay_unmapped_address (cache_pc_function_high - 1,
> > > 						   section);
> > > 	}
> > >       else
> > > 	*endaddr = cache_pc_function_high;
> > >     }
> > > 
> > > The cached values are zero and 1, correspondingly.
> > > 
> > > Any suggestions for how to fix this?  One way would be to avoid
> > > triggering the assertion of the addresses are these two specific bogus
> > > values.  Alternatively, perhaps the cached values in
> > > find_pc_partial_function should be more useful, but in that case I'd
> > > need guidance as to where and how are they supposed to be assigned, so
> > > that I could look into why they don't in this case.
> > > 
> > > TIA
> > > 
> > 
> 

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: GDB internal error in pc_in_thread_step_range
  2018-11-18 16:37   ` GDB internal error in pc_in_thread_step_range Eli Zaretskii
  2018-11-30 13:42     ` Eli Zaretskii
@ 2018-12-16  3:58     ` Simon Marchi
  2018-12-16 15:40       ` Eli Zaretskii
  1 sibling, 1 reply; 25+ messages in thread
From: Simon Marchi @ 2018-12-16  3:58 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches

Hi Eli,

Sorry for the wait.  I don't really have an good answer for you, but I thought I'd
reply anyway, maybe this will help generate ideas.

On 2018-11-18 11:37 a.m., Eli Zaretskii wrote:
>> Date: Mon, 20 Aug 2018 11:08:27 -0400
>> From: Simon Marchi <simon.marchi@polymtl.ca>
>> Cc: gdb@sourceware.org
> 
> A reminder: this is about an internal GDB error that happens on MinGW
> whenever I step out of the 'main' function.
> 
>>>   Temporary breakpoint 1, main () at hello.c:8
>>>   8         printf("hello, world!");
>>>   (gdb) n
>>>   hello, world!9    return 0;
>>>   (gdb)
>>>   10      }
>>>   (gdb)
>>>   0x0040126d in __register_frame_info ()
>>>   (gdb)
>>>   Single stepping until exit from function __register_frame_info,
>>>   which has no line number information.
>>>   infrun.c:2728: internal-error: void resume_1(gdb_signal): Assertion
>>> `pc_in_thread_step_range (pc, tp)' failed.
>>>   A problem internal to GDB has been detected,
>>>   further debugging may prove unreliable.
>>>   Quit this debugging session? (y or n)
>>>
>>> Is it a known problem?
>>
>> Not that I know of.
> 
> I finally got to debugging this.  It happens because:
> 
>   2723          gdb_assert (pc_in_thread_step_range (pc, tp));
>   (top-gdb) p tp->control
>   $22 = {step_resume_breakpoint = 0x0, exception_resume_breakpoint = 0x0,
>     single_step_breakpoints = 0x0, step_range_start = 0x0,
>     step_range_end = 0x1, step_start_function = 0x0, may_range_step = 1,
>     step_frame_id = {stack_addr = 0x28ff70, code_addr = 0x0,
>       special_addr = 0x0, stack_status = FID_STACK_VALID, code_addr_p = 1,
>       special_addr_p = 0, artificial_depth = 0}, step_stack_frame_id = {
>       stack_addr = 0x28ff70, code_addr = 0x0, special_addr = 0x0,
>       stack_status = FID_STACK_VALID, code_addr_p = 1, special_addr_p = 0,
>       artificial_depth = 0}, trap_expected = 0, proceed_to_finish = 0,
>     in_infcall = 0, step_over_calls = STEP_OVER_ALL, stop_step = 0,
>     stop_bpstat = 0x0, stepping_command = 1}
> 
> The step_range_start is zero and step_range_end is 1, which of course
> will not match any value of PC.
> 
> What happens here is that step_1 first zeroes out these members, and
> then fills them by calling find_pc_line_pc_range, called from
> prepare_one_step.  But when I step out of the main program into the
> library epilogue code, there's no line information, and
> prepare_one_step calls find_pc_partial_function, which also doesn't
> find any addresses.  So we fill these members with zero and 1:
> 
>   if (address)
>     {
>       if (pc_in_unmapped_range (pc, section))
> 	*address = overlay_unmapped_address (cache_pc_function_low, section);
>       else
> 	*address = cache_pc_function_low;
>     }
> 
>   if (name)
>     *name = cache_pc_function_name;
> 
>   if (endaddr)
>     {
>       if (pc_in_unmapped_range (pc, section))
> 	{
> 	  /* Because the high address is actually beyond the end of
> 	     the function (and therefore possibly beyond the end of
> 	     the overlay), we must actually convert (high - 1) and
> 	     then add one to that.  */
> 
> 	  *endaddr = 1 + overlay_unmapped_address (cache_pc_function_high - 1,
> 						   section);
> 	}
>       else
> 	*endaddr = cache_pc_function_high;
>     }
> 
> The cached values are zero and 1, correspondingly.

Do you mean that cache_pc_function_low is 0 and cache_pc_function_high is 1?
Do these values even make sense?  They are supposed to hold a range of program
addresses, so 0 and 1 seem bogus.  Maybe this is the result of something going
wrong before?  It would be interesting to understand how they end up with these
values.

If find_pc_partial_function is unable to determine a proper symbol and some proper
bounds, it should return 0.  So if it returns 1 but returns some wrong data,
something is fishy.

Simon

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: GDB internal error in pc_in_thread_step_range
  2018-12-16  3:58     ` Simon Marchi
@ 2018-12-16 15:40       ` Eli Zaretskii
  2018-12-16 17:06         ` Simon Marchi
  0 siblings, 1 reply; 25+ messages in thread
From: Eli Zaretskii @ 2018-12-16 15:40 UTC (permalink / raw)
  To: Simon Marchi; +Cc: gdb-patches

> Cc: gdb-patches@sourceware.org
> From: Simon Marchi <simon.marchi@polymtl.ca>
> Date: Sat, 15 Dec 2018 22:57:57 -0500
> 
> Hi Eli,
> 
> Sorry for the wait.  I don't really have an good answer for you, but I thought I'd
> reply anyway, maybe this will help generate ideas.

Thanks for replying.

> >   if (address)
> >     {
> >       if (pc_in_unmapped_range (pc, section))
> > 	*address = overlay_unmapped_address (cache_pc_function_low, section);
> >       else
> > 	*address = cache_pc_function_low;
> >     }
> > 
> >   if (name)
> >     *name = cache_pc_function_name;
> > 
> >   if (endaddr)
> >     {
> >       if (pc_in_unmapped_range (pc, section))
> > 	{
> > 	  /* Because the high address is actually beyond the end of
> > 	     the function (and therefore possibly beyond the end of
> > 	     the overlay), we must actually convert (high - 1) and
> > 	     then add one to that.  */
> > 
> > 	  *endaddr = 1 + overlay_unmapped_address (cache_pc_function_high - 1,
> > 						   section);
> > 	}
> >       else
> > 	*endaddr = cache_pc_function_high;
> >     }
> > 
> > The cached values are zero and 1, correspondingly.
> 
> Do you mean that cache_pc_function_low is 0 and cache_pc_function_high is 1?

Yes.

> Do these values even make sense?

What else can we expect from a code at PC for which there's absolutely
no symbolic information?  So yes, I think it's reasonable, but I'm far
from being an expert on these parts of GDB.

> They are supposed to hold a range of program addresses, so 0 and 1
> seem bogus.  Maybe this is the result of something going wrong
> before?  It would be interesting to understand how they end up with
> these values.

They are assigned here:

  cache_pc_function_low = BMSYMBOL_VALUE_ADDRESS (msymbol);
  cache_pc_function_name = MSYMBOL_LINKAGE_NAME (msymbol.minsym);
  cache_pc_function_section = section;
  cache_pc_function_high = minimal_symbol_upper_bound (msymbol);
  cache_pc_function_block = nullptr;

This is part of find_pc_partial_function.  I verified that
minimal_symbol_upper_bound returns 1 in this case, and that this value
of 1 is assigned here:

  obj_section = MSYMBOL_OBJ_SECTION (minsym.objfile, minsym.minsym);
  if (MSYMBOL_LINKAGE_NAME (msymbol + i) != NULL
      && (MSYMBOL_VALUE_ADDRESS (minsym.objfile, msymbol + i)
	  < obj_section_endaddr (obj_section)))
    result = MSYMBOL_VALUE_ADDRESS (minsym.objfile, msymbol + i); <<<<<<
  else

Once again, I'm not an expert on this stuff, but just thinking about
the situation, what else could GDB return in this case?

> If find_pc_partial_function is unable to determine a proper symbol and some proper
> bounds, it should return 0.  So if it returns 1 but returns some wrong data,
> something is fishy.

If it returns zero, we will emit an error message:

	      if (find_pc_partial_function (pc, &name,
					    &tp->control.step_range_start,
					    &tp->control.step_range_end) == 0)
		error (_("Cannot find bounds of current function"));

So I'm not sure this is a good idea.  Instead, I propose the following
change:

--- gdb/infrun.c~0	2018-07-04 18:41:59.000000000 +0300
+++ gdb/infrun.c	2018-12-16 11:02:24.103425700 +0200
@@ -2713,7 +2713,13 @@ resume_1 (enum gdb_signal sig)
       displaced_step_dump_bytes (gdb_stdlog, buf, sizeof (buf));
     }
 
-  if (tp->control.may_range_step)
+  if (tp->control.may_range_step
+      /* If .step_range_start == 0 and .step_range_end == 1, we don't
+	 really know the step range, so don't check in that case.
+	 (This is known to happen on MinGW when stepping the program
+	 epilogue code after 'main' returns.)  */
+      && !(tp->control.step_range_start == 0x0
+	   && tp->control.step_range_end == 0x1))
     {
       /* If we're resuming a thread with the PC out of the step
 	 range, then we're doing some nested/finer run control


Thanks.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: GDB internal error in pc_in_thread_step_range
  2018-12-16 15:40       ` Eli Zaretskii
@ 2018-12-16 17:06         ` Simon Marchi
  2018-12-16 17:22           ` Eli Zaretskii
  0 siblings, 1 reply; 25+ messages in thread
From: Simon Marchi @ 2018-12-16 17:06 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches

On 2018-12-16 10:40 a.m., Eli Zaretskii wrote:
> What else can we expect from a code at PC for which there's absolutely
> no symbolic information?  So yes, I think it's reasonable, but I'm far
> from being an expert on these parts of GDB.

I can't see any mention or even clue that these values would have a special
meaning, it looks to me like they are returned by mistake more than on purpose.

>> They are supposed to hold a range of program addresses, so 0 and 1
>> seem bogus.  Maybe this is the result of something going wrong
>> before?  It would be interesting to understand how they end up with
>> these values.
> 
> They are assigned here:
> 
>   cache_pc_function_low = BMSYMBOL_VALUE_ADDRESS (msymbol);
>   cache_pc_function_name = MSYMBOL_LINKAGE_NAME (msymbol.minsym);
>   cache_pc_function_section = section;
>   cache_pc_function_high = minimal_symbol_upper_bound (msymbol);
>   cache_pc_function_block = nullptr;
> 
> This is part of find_pc_partial_function.  I verified that
> minimal_symbol_upper_bound returns 1 in this case, and that this value
> of 1 is assigned here:
> 
>   obj_section = MSYMBOL_OBJ_SECTION (minsym.objfile, minsym.minsym);
>   if (MSYMBOL_LINKAGE_NAME (msymbol + i) != NULL
>       && (MSYMBOL_VALUE_ADDRESS (minsym.objfile, msymbol + i)
> 	  < obj_section_endaddr (obj_section)))
>     result = MSYMBOL_VALUE_ADDRESS (minsym.objfile, msymbol + i); <<<<<<
>   else
> 
> Once again, I'm not an expert on this stuff, but just thinking about
> the situation, what else could GDB return in this case?

This means that BMSYMBOL_VALUE_ADDRESS (msymbol) returned 0?  What is that symbol?
How come by looking up a symbol for PC (what is PC's value, btw) we found this symbol?

>> If find_pc_partial_function is unable to determine a proper symbol and some proper
>> bounds, it should return 0.  So if it returns 1 but returns some wrong data,
>> something is fishy.
> 
> If it returns zero, we will emit an error message:
> 
> 	      if (find_pc_partial_function (pc, &name,
> 					    &tp->control.step_range_start,
> 					    &tp->control.step_range_end) == 0)
> 		error (_("Cannot find bounds of current function"));
> 
> So I'm not sure this is a good idea.

That sounds like a reasonable thing to happen if the user tries to use "step" and
we are not able to compute the function bounds.  The question is, are we really
unable to compute the function bounds, or are able, we are just messing it up.

The goal of find_pc_partial_function's ADDRESS and ENDADDR out parameters is to give
the range of the function PC is in.  If find_pc_partial_function returns "success" but
[ADDRESS,ENDADDR[ does not enclose PC, that really sounds like a bug to me, and this is
where I'd dig.

Instead, I propose the following
> change:
> 
> --- gdb/infrun.c~0	2018-07-04 18:41:59.000000000 +0300
> +++ gdb/infrun.c	2018-12-16 11:02:24.103425700 +0200
> @@ -2713,7 +2713,13 @@ resume_1 (enum gdb_signal sig)
>        displaced_step_dump_bytes (gdb_stdlog, buf, sizeof (buf));
>      }
>  
> -  if (tp->control.may_range_step)
> +  if (tp->control.may_range_step
> +      /* If .step_range_start == 0 and .step_range_end == 1, we don't
> +	 really know the step range, so don't check in that case.
> +	 (This is known to happen on MinGW when stepping the program
> +	 epilogue code after 'main' returns.)  */
> +      && !(tp->control.step_range_start == 0x0
> +	   && tp->control.step_range_end == 0x1))
>      {
>        /* If we're resuming a thread with the PC out of the step
>  	 range, then we're doing some nested/finer run control

This is treating 0 and 1 as special values, which I don't think they are.

Simon

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: GDB internal error in pc_in_thread_step_range
  2018-12-16 17:06         ` Simon Marchi
@ 2018-12-16 17:22           ` Eli Zaretskii
  2018-12-16 18:06             ` Simon Marchi
  0 siblings, 1 reply; 25+ messages in thread
From: Eli Zaretskii @ 2018-12-16 17:22 UTC (permalink / raw)
  To: Simon Marchi; +Cc: gdb-patches

> Cc: gdb-patches@sourceware.org
> From: Simon Marchi <simon.marchi@polymtl.ca>
> Date: Sun, 16 Dec 2018 12:06:07 -0500
> 
> I can't see any mention or even clue that these values would have a special
> meaning, it looks to me like they are returned by mistake more than on purpose.

If the start address is zero and the length is zero, this is what we
will get, right?

> >   cache_pc_function_low = BMSYMBOL_VALUE_ADDRESS (msymbol);
> >   cache_pc_function_name = MSYMBOL_LINKAGE_NAME (msymbol.minsym);
> >   cache_pc_function_section = section;
> >   cache_pc_function_high = minimal_symbol_upper_bound (msymbol);
> >   cache_pc_function_block = nullptr;
> > 
> > This is part of find_pc_partial_function.  I verified that
> > minimal_symbol_upper_bound returns 1 in this case, and that this value
> > of 1 is assigned here:
> > 
> >   obj_section = MSYMBOL_OBJ_SECTION (minsym.objfile, minsym.minsym);
> >   if (MSYMBOL_LINKAGE_NAME (msymbol + i) != NULL
> >       && (MSYMBOL_VALUE_ADDRESS (minsym.objfile, msymbol + i)
> > 	  < obj_section_endaddr (obj_section)))
> >     result = MSYMBOL_VALUE_ADDRESS (minsym.objfile, msymbol + i); <<<<<<
> >   else
> > 
> > Once again, I'm not an expert on this stuff, but just thinking about
> > the situation, what else could GDB return in this case?
> 
> This means that BMSYMBOL_VALUE_ADDRESS (msymbol) returned 0?  What is that symbol?

Please help me understand what field of which struct do I need to show
to answer that question.  IOW, when you ask "what is that symbol",
what kind of answer do you expect me to provide?

> How come by looking up a symbol for PC (what is PC's value, btw) we found this symbol?

It comes from this loop, just before the above-mentioned snippet from
minimal_symbol_upper_bound:

  msymbol = minsym.minsym;
  section = MSYMBOL_SECTION (msymbol);
  for (i = 1; MSYMBOL_LINKAGE_NAME (msymbol + i) != NULL; i++)
    {
      if ((MSYMBOL_VALUE_RAW_ADDRESS (msymbol + i)
	   != MSYMBOL_VALUE_RAW_ADDRESS (msymbol))
	  && MSYMBOL_SECTION (msymbol + i) == section)
	break;
    }

> > --- gdb/infrun.c~0	2018-07-04 18:41:59.000000000 +0300
> > +++ gdb/infrun.c	2018-12-16 11:02:24.103425700 +0200
> > @@ -2713,7 +2713,13 @@ resume_1 (enum gdb_signal sig)
> >        displaced_step_dump_bytes (gdb_stdlog, buf, sizeof (buf));
> >      }
> >  
> > -  if (tp->control.may_range_step)
> > +  if (tp->control.may_range_step
> > +      /* If .step_range_start == 0 and .step_range_end == 1, we don't
> > +	 really know the step range, so don't check in that case.
> > +	 (This is known to happen on MinGW when stepping the program
> > +	 epilogue code after 'main' returns.)  */
> > +      && !(tp->control.step_range_start == 0x0
> > +	   && tp->control.step_range_end == 0x1))
> >      {
> >        /* If we're resuming a thread with the PC out of the step
> >  	 range, then we're doing some nested/finer run control
> 
> This is treating 0 and 1 as special values, which I don't think they are.

It definitely looked to me as if they were special.  But I will try to
answer your other questions, maybe I was wrong.

Thanks.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: GDB internal error in pc_in_thread_step_range
  2018-12-16 17:22           ` Eli Zaretskii
@ 2018-12-16 18:06             ` Simon Marchi
  2018-12-19 15:50               ` Eli Zaretskii
  0 siblings, 1 reply; 25+ messages in thread
From: Simon Marchi @ 2018-12-16 18:06 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches

On 2018-12-16 12:22 p.m., Eli Zaretskii wrote:
>> Cc: gdb-patches@sourceware.org
>> From: Simon Marchi <simon.marchi@polymtl.ca>
>> Date: Sun, 16 Dec 2018 12:06:07 -0500
>>
>> I can't see any mention or even clue that these values would have a special
>> meaning, it looks to me like they are returned by mistake more than on purpose.
> 
> If the start address is zero and the length is zero, this is what we
> will get, right?

Technically, I think this is what we would get if address was 0 and length 1.  If
address was 0 and length 0 (en empty range?), *ENDADDR would also be 0.

>>>   cache_pc_function_low = BMSYMBOL_VALUE_ADDRESS (msymbol);
>>>   cache_pc_function_name = MSYMBOL_LINKAGE_NAME (msymbol.minsym);
>>>   cache_pc_function_section = section;
>>>   cache_pc_function_high = minimal_symbol_upper_bound (msymbol);
>>>   cache_pc_function_block = nullptr;
>>>
>>> This is part of find_pc_partial_function.  I verified that
>>> minimal_symbol_upper_bound returns 1 in this case, and that this value
>>> of 1 is assigned here:
>>>
>>>   obj_section = MSYMBOL_OBJ_SECTION (minsym.objfile, minsym.minsym);
>>>   if (MSYMBOL_LINKAGE_NAME (msymbol + i) != NULL
>>>       && (MSYMBOL_VALUE_ADDRESS (minsym.objfile, msymbol + i)
>>> 	  < obj_section_endaddr (obj_section)))
>>>     result = MSYMBOL_VALUE_ADDRESS (minsym.objfile, msymbol + i); <<<<<<
>>>   else
>>>
>>> Once again, I'm not an expert on this stuff, but just thinking about
>>> the situation, what else could GDB return in this case?
>>
>> This means that BMSYMBOL_VALUE_ADDRESS (msymbol) returned 0?  What is that symbol?
> 
> Please help me understand what field of which struct do I need to show
> to answer that question.  IOW, when you ask "what is that symbol",
> what kind of answer do you expect me to provide?

In particular, I am looking for why we identified the symbol represented by MSYMBOL
as the function containing PC.  What is this symbol's name?  That would be printed
with MSYMBOL_LINKAGE_NAME(msymbol.minsym), I think.  Or if you expand,
"msymbol.minsym.mginfo.name".

What is its address (should be msymbol.minsym.mginfo.value.address)?

> 
>> How come by looking up a symbol for PC (what is PC's value, btw) we found this symbol?
> 
> It comes from this loop, just before the above-mentioned snippet from
> minimal_symbol_upper_bound:
> 
>   msymbol = minsym.minsym;
>   section = MSYMBOL_SECTION (msymbol);
>   for (i = 1; MSYMBOL_LINKAGE_NAME (msymbol + i) != NULL; i++)
>     {
>       if ((MSYMBOL_VALUE_RAW_ADDRESS (msymbol + i)
> 	   != MSYMBOL_VALUE_RAW_ADDRESS (msymbol))
> 	  && MSYMBOL_SECTION (msymbol + i) == section)
> 	break;
>     }

Actually, I think I would investigate this line in find_pc_partial_function:

  msymbol = lookup_minimal_symbol_by_pc_section (mapped_pc, section);

This is where we ask the question "which is the closest minimal symbol that is <= than PC".
I would then try to see if the returned msymbol makes sense.  If you can give its name and
address, it would be a good start.  If we find it doesn't make sense, I'd start looking at
why lookup_minimal_symbol_by_pc_section returned that.

I am not familiar with PE/Windows executables, but I would try to compare what I see there
with the output of "objdump -t" and "objdump -d" to see if the minimal symbols in GDB
correspond to something there.

>>> --- gdb/infrun.c~0	2018-07-04 18:41:59.000000000 +0300
>>> +++ gdb/infrun.c	2018-12-16 11:02:24.103425700 +0200
>>> @@ -2713,7 +2713,13 @@ resume_1 (enum gdb_signal sig)
>>>        displaced_step_dump_bytes (gdb_stdlog, buf, sizeof (buf));
>>>      }
>>>  
>>> -  if (tp->control.may_range_step)
>>> +  if (tp->control.may_range_step
>>> +      /* If .step_range_start == 0 and .step_range_end == 1, we don't
>>> +	 really know the step range, so don't check in that case.
>>> +	 (This is known to happen on MinGW when stepping the program
>>> +	 epilogue code after 'main' returns.)  */
>>> +      && !(tp->control.step_range_start == 0x0
>>> +	   && tp->control.step_range_end == 0x1))
>>>      {
>>>        /* If we're resuming a thread with the PC out of the step
>>>  	 range, then we're doing some nested/finer run control
>>
>> This is treating 0 and 1 as special values, which I don't think they are.
> 
> It definitely looked to me as if they were special.  But I will try to
> answer your other questions, maybe I was wrong.

I think that for "absence of range", a 0/0 value would make more sense.  But that isn't
how find_pc_partial_function is documented to work:

   If it succeeds, it sets *NAME, *ADDRESS, and *ENDADDR to real
   information and returns 1.  If it fails, it sets *NAME, *ADDRESS
   and *ENDADDR to zero and returns 0.

find_pc_partial_function returns 1 in our case, and the information it returns in
*ADDRESS and *ENDADDR doesn't seem "real", as the comment says.

Also, if you read to complete comment of find_pc_partial_function (in symtab.h), it
reinforces the idea that the *ADDRESS <= PC < *ENDADDR invariant should hold.

Simon

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: GDB internal error in pc_in_thread_step_range
  2018-12-16 18:06             ` Simon Marchi
@ 2018-12-19 15:50               ` Eli Zaretskii
  2018-12-20  0:16                 ` Simon Marchi
  0 siblings, 1 reply; 25+ messages in thread
From: Eli Zaretskii @ 2018-12-19 15:50 UTC (permalink / raw)
  To: Simon Marchi; +Cc: gdb-patches

> Cc: gdb-patches@sourceware.org
> From: Simon Marchi <simon.marchi@polymtl.ca>
> Date: Sun, 16 Dec 2018 13:06:27 -0500
> 
> >>>   cache_pc_function_low = BMSYMBOL_VALUE_ADDRESS (msymbol);
> >>>   cache_pc_function_name = MSYMBOL_LINKAGE_NAME (msymbol.minsym);
> >>>   cache_pc_function_section = section;
> >>>   cache_pc_function_high = minimal_symbol_upper_bound (msymbol);
> >>>   cache_pc_function_block = nullptr;
> >>>
> >>> This is part of find_pc_partial_function.  I verified that
> >>> minimal_symbol_upper_bound returns 1 in this case, and that this value
> >>> of 1 is assigned here:
> >>>
> >>>   obj_section = MSYMBOL_OBJ_SECTION (minsym.objfile, minsym.minsym);
> >>>   if (MSYMBOL_LINKAGE_NAME (msymbol + i) != NULL
> >>>       && (MSYMBOL_VALUE_ADDRESS (minsym.objfile, msymbol + i)
> >>> 	  < obj_section_endaddr (obj_section)))
> >>>     result = MSYMBOL_VALUE_ADDRESS (minsym.objfile, msymbol + i); <<<<<<
> >>>   else
> >>>
> >>> Once again, I'm not an expert on this stuff, but just thinking about
> >>> the situation, what else could GDB return in this case?
> >>
> >> This means that BMSYMBOL_VALUE_ADDRESS (msymbol) returned 0?  What is that symbol?

The symbol is the one shown by GDB:

   0x0040126d in __register_frame_info ()
   Single stepping until exit from function __register_frame_info,
   which has no line number information.

Here it is as shown in the debugging session:

  227       msymbol = lookup_minimal_symbol_by_pc_section (mapped_pc, section);
  (top-gdb)
  228       ALL_OBJFILES (objfile)
  (top-gdb) p msymbol
  $3 = {minsym = 0x10450d38, objfile = 0x10443b48}
  (top-gdb) p msymbol.minsym.mginfo.name
  $4 = 0x104485cd "__register_frame_info"
  (top-gdb) p msymbol.minsym.mginfo
  $5 = {name = 0x104485cd "__register_frame_info", value = {ivalue = 0,
      block = 0x0, bytes = 0x0, address = 0x0, common_block = 0x0,
      chain = 0x0}, language_specific = {obstack = 0x0, demangled_name = 0x0},
    language = language_auto, ada_mangled = 0, section = 0}

> In particular, I am looking for why we identified the symbol represented by MSYMBOL
> as the function containing PC.  What is this symbol's name?  That would be printed
> with MSYMBOL_LINKAGE_NAME(msymbol.minsym), I think.  Or if you expand,
> "msymbol.minsym.mginfo.name".
> 
> What is its address (should be msymbol.minsym.mginfo.value.address)?
> 
> > 
> >> How come by looking up a symbol for PC (what is PC's value, btw) we found this symbol?

That's because it's the symbol with the lowest address that satisfies
all the conditions in lookup_minimal_symbol_by_pc_section.  It goes
like this:

The loop which does a binary search through the minsyms finds the the
symbol immediately preceding the address of PC is this:

  (top-gdb) p newobj
  $28 = 26
  (top-gdb) p msymbol[newobj]
  $29 = {mginfo = {name = 0x10448845 "_image_base__", value = {
	ivalue = 4194304, block = 0x400000, bytes = 0x400000 "MZ\220",
	address = 0x400000, common_block = 0x400000, chain = 0x400000},
      language_specific = {obstack = 0x0, demangled_name = 0x0},
      language = language_auto, ada_mangled = 0, section = 0}, size = 0,
    filename = 0x0, type = mst_abs, created_by_gdb = 0, target_flag_1 = 0,
    target_flag_2 = 0, has_size = 0, hash_next = 0x0, demangled_hash_next = 0x0}

(our PC is 0x40126d).

Then this loop:

	      /* Skip various undesirable symbols.  */
	      while (hi >= 0)
		{

decrements 'hi' all the way down to 5, because all the preceding
symbols have the type mst_abs:

  (top-gdb) p hi
  $46 = 5
  (top-gdb) p msymbol[hi]
  $47 = {mginfo = {name = 0x1044858d "__register_frame_info", value = {
	ivalue = 0, block = 0x0, bytes = 0x0, address = 0x0,
	common_block = 0x0, chain = 0x0}, language_specific = {obstack = 0x0,
	demangled_name = 0x0}, language = language_auto, ada_mangled = 0,
      section = 0}, size = 0, filename = 0x0, type = mst_text,
    created_by_gdb = 0, target_flag_1 = 0, target_flag_2 = 0, has_size = 0,
    hash_next = 0x0, demangled_hash_next = 0x0}

Note that this symbol's address is zero.  This symbol is then
returned, and so cache_pc_function_low becomes zero.  Then we get to
this:

   cache_pc_function_high = minimal_symbol_upper_bound (msymbol);

minimal_symbol_upper_bound then looks at the following symbols trying
to find the one whose address is different from zero:

  for (i = 1; MSYMBOL_LINKAGE_NAME (msymbol + i) != NULL; i++)
    {
      if ((MSYMBOL_VALUE_RAW_ADDRESS (msymbol + i)
	   != MSYMBOL_VALUE_RAW_ADDRESS (msymbol))
	  && MSYMBOL_SECTION (msymbol + i) == section)
	break;
    }

It finds such a symbol in the 10th entry:

  (top-gdb) p msymbol[1]
  $76 = {mginfo = {name = 0x10448a55 "__set_app_type", value = {ivalue = 0,
	block = 0x0, bytes = 0x0, address = 0x0, common_block = 0x0,
	chain = 0x0}, language_specific = {obstack = 0x0,
	demangled_name = 0x0}, language = language_auto, ada_mangled = 0,
      section = 0}, size = 0, filename = 0x0, type = mst_abs,
    created_by_gdb = 0, target_flag_1 = 0, target_flag_2 = 0, has_size = 0,
    hash_next = 0x0, demangled_hash_next = 0x0}
  (top-gdb) p msymbol[2]
  $77 = {mginfo = {name = 0x104487ad "_dll__", value = {ivalue = 0,
	block = 0x0, bytes = 0x0, address = 0x0, common_block = 0x0,
	chain = 0x0}, language_specific = {obstack = 0x0,
	demangled_name = 0x0}, language = language_auto, ada_mangled = 0,
      section = 0}, size = 0, filename = 0x0, type = mst_abs,
    created_by_gdb = 0, target_flag_1 = 0, target_flag_2 = 0, has_size = 0,
    hash_next = 0x0, demangled_hash_next = 0x0}
  (top-gdb) p msymbol[3]
  $78 = {mginfo = {name = 0x104483cd "_dll_characteristics__", value = {
	ivalue = 0, block = 0x0, bytes = 0x0, address = 0x0,
	common_block = 0x0, chain = 0x0}, language_specific = {obstack = 0x0,
	demangled_name = 0x0}, language = language_auto, ada_mangled = 0,
      section = 0}, size = 0, filename = 0x0, type = mst_abs,
    created_by_gdb = 0, target_flag_1 = 0, target_flag_2 = 0, has_size = 0,
    hash_next = 0x0, demangled_hash_next = 0x0}
  (top-gdb) p msymbol[3]
  $79 = {mginfo = {name = 0x104483cd "_dll_characteristics__", value = {
	ivalue = 0, block = 0x0, bytes = 0x0, address = 0x0,
	common_block = 0x0, chain = 0x0}, language_specific = {obstack = 0x0,
	demangled_name = 0x0}, language = language_auto, ada_mangled = 0,
      section = 0}, size = 0, filename = 0x0, type = mst_abs,
    created_by_gdb = 0, target_flag_1 = 0, target_flag_2 = 0, has_size = 0,
    hash_next = 0x0, demangled_hash_next = 0x0}
  (top-gdb) p msymbol[4]
  $80 = {mginfo = {name = 0x1044868d "_fpreset", value = {ivalue = 0,
	block = 0x0, bytes = 0x0, address = 0x0, common_block = 0x0,
	chain = 0x0}, language_specific = {obstack = 0x0,
	demangled_name = 0x0}, language = language_auto, ada_mangled = 0,
      section = 0}, size = 0, filename = 0x0, type = mst_abs,
    created_by_gdb = 0, target_flag_1 = 0, target_flag_2 = 0, has_size = 0,
    hash_next = 0x0, demangled_hash_next = 0x0}
  (top-gdb) p msymbol[5]
  $81 = {mginfo = {name = 0x1044fead "_loader_flags__", value = {ivalue = 0,
	block = 0x0, bytes = 0x0, address = 0x0, common_block = 0x0,
	chain = 0x0}, language_specific = {obstack = 0x0,
	demangled_name = 0x0}, language = language_auto, ada_mangled = 0,
      section = 0}, size = 0, filename = 0x0, type = mst_abs,
    created_by_gdb = 0, target_flag_1 = 0, target_flag_2 = 0, has_size = 0,
    hash_next = 0x0, demangled_hash_next = 0x0}
  (top-gdb) p msymbol[6]
  $82 = {mginfo = {name = 0x1044ff9d "_minor_image_version__", value = {
	ivalue = 0, block = 0x0, bytes = 0x0, address = 0x0,
	common_block = 0x0, chain = 0x0}, language_specific = {obstack = 0x0,
	demangled_name = 0x0}, language = language_auto, ada_mangled = 0,
      section = 0}, size = 0, filename = 0x0, type = mst_abs,
    created_by_gdb = 0, target_flag_1 = 0, target_flag_2 = 0, has_size = 0,
    hash_next = 0x0, demangled_hash_next = 0x0}
  (top-gdb) p msymbol[7]
  $83 = {mginfo = {name = 0x104487cd "_minor_os_version__", value = {
	ivalue = 0, block = 0x0, bytes = 0x0, address = 0x0,
	common_block = 0x0, chain = 0x0}, language_specific = {obstack = 0x0,
	demangled_name = 0x0}, language = language_auto, ada_mangled = 0,
      section = 0}, size = 0, filename = 0x0, type = mst_abs,
    created_by_gdb = 0, target_flag_1 = 0, target_flag_2 = 0, has_size = 0,
    hash_next = 0x0, demangled_hash_next = 0x0}
  (top-gdb) p msymbol[8]
  $84 = {mginfo = {name = 0x1044ff65 "_minor_subsystem_version__", value = {
	ivalue = 0, block = 0x0, bytes = 0x0, address = 0x0,
	common_block = 0x0, chain = 0x0}, language_specific = {obstack = 0x0,
	demangled_name = 0x0}, language = language_auto, ada_mangled = 0,
      section = 0}, size = 0, filename = 0x0, type = mst_abs,
    created_by_gdb = 0, target_flag_1 = 0, target_flag_2 = 0, has_size = 0,
    hash_next = 0x0, demangled_hash_next = 0x0}
  (top-gdb) p msymbol[9]
  $85 = {mginfo = {name = 0x10448b35 "_rt_psrelocs_size", value = {ivalue = 0,
	block = 0x0, bytes = 0x0, address = 0x0, common_block = 0x0,
	chain = 0x0}, language_specific = {obstack = 0x0,
	demangled_name = 0x0}, language = language_auto, ada_mangled = 0,
      section = 0}, size = 0, filename = 0x0, type = mst_abs,
    created_by_gdb = 0, target_flag_1 = 0, target_flag_2 = 0, has_size = 0,
    hash_next = 0x0, demangled_hash_next = 0x0}
  (top-gdb) p msymbol[10]
  $86 = {mginfo = {name = 0x1044fe8d "_major_image_version__", value = {
	ivalue = 1, block = 0x1,
	bytes = 0x1 <error: Cannot access memory at address 0x1>,
	address = 0x1, common_block = 0x1, chain = 0x1}, language_specific = {
	obstack = 0x0, demangled_name = 0x0}, language = language_auto,
      ada_mangled = 0, section = 0}, size = 0, filename = 0x0, type = mst_abs,
    created_by_gdb = 0, target_flag_1 = 0, target_flag_2 = 0, has_size = 0,
    hash_next = 0x0, demangled_hash_next = 0x0}

And so cache_pc_function_high becomes 1.

> Actually, I think I would investigate this line in find_pc_partial_function:
> 
>   msymbol = lookup_minimal_symbol_by_pc_section (mapped_pc, section);
> 
> This is where we ask the question "which is the closest minimal symbol that is <= than PC".
> I would then try to see if the returned msymbol makes sense.  If you can give its name and
> address, it would be a good start.  If we find it doesn't make sense, I'd start looking at
> why lookup_minimal_symbol_by_pc_section returned that.

That's what I did.  The problem seems to be that the low value of PC
doesn't allow GDB to find a reasonable symbol; what it finds are
symbols with very low addresses, which don't look like symbols
relevant to the issue at hand.  I see the same symbols and addresses
in the output of "objdump -t" (I can show it if you want).

Where do we go from here?

Thanks.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: GDB internal error in pc_in_thread_step_range
  2018-12-19 15:50               ` Eli Zaretskii
@ 2018-12-20  0:16                 ` Simon Marchi
  2018-12-20 15:45                   ` Eli Zaretskii
  0 siblings, 1 reply; 25+ messages in thread
From: Simon Marchi @ 2018-12-20  0:16 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches

On 2018-12-19 10:50, Eli Zaretskii wrote:
> The symbol is the one shown by GDB:
> 
>    0x0040126d in __register_frame_info ()
>    Single stepping until exit from function __register_frame_info,
>    which has no line number information.
> 
> Here it is as shown in the debugging session:
> 
>   227       msymbol = lookup_minimal_symbol_by_pc_section (mapped_pc, 
> section);
>   (top-gdb)
>   228       ALL_OBJFILES (objfile)
>   (top-gdb) p msymbol
>   $3 = {minsym = 0x10450d38, objfile = 0x10443b48}
>   (top-gdb) p msymbol.minsym.mginfo.name
>   $4 = 0x104485cd "__register_frame_info"
>   (top-gdb) p msymbol.minsym.mginfo
>   $5 = {name = 0x104485cd "__register_frame_info", value = {ivalue = 0,
>       block = 0x0, bytes = 0x0, address = 0x0, common_block = 0x0,
>       chain = 0x0}, language_specific = {obstack = 0x0, demangled_name 
> = 0x0},
>     language = language_auto, ada_mangled = 0, section = 0}

Ok.  Well this is already strange.  Why is there an mst_text (code) 
symbol with a value of 0?  If your binary is anything like those I can 
produce with x86_64-w64-mingw32-gcc (and it looks similar, given the 
addresses you show), your "image base" is likely 0x400000, and "base of 
code" 0x1000 (0x401000 in absolute).  I found this information using 
"objdump -x", in the header somewhere.  I therefore expect all text 
symbols to be >= 0x401000.  I would start digging why this text symbol 
with a value of 0 exists.

It would be interesting to look at some other symbols in the msymbols 
vector.  Are the other mst_text symbols >= 0x401000?

When printing the symbols with "objdump -t", the addresses are also 
relative to 0x401000, but when they become minimal symbols in GDB, they 
are saved as the absolute address (e.g. a text symbol at 0x1c88 becomes 
0x401000).

Assuming this minimal symbol is wrong and assuming it wasn't there, then 
I guess the search would fail and we would fall in the "Cannot find 
bounds of current function" case of prepare_one_step?  That would be 
appropriate in this case.

>> In particular, I am looking for why we identified the symbol 
>> represented by MSYMBOL
>> as the function containing PC.  What is this symbol's name?  That 
>> would be printed
>> with MSYMBOL_LINKAGE_NAME(msymbol.minsym), I think.  Or if you expand,
>> "msymbol.minsym.mginfo.name".
>> 
>> What is its address (should be msymbol.minsym.mginfo.value.address)?
>> 
>> >
>> >> How come by looking up a symbol for PC (what is PC's value, btw) we found this symbol?
> 
> That's because it's the symbol with the lowest address that satisfies
> all the conditions in lookup_minimal_symbol_by_pc_section.  It goes
> like this:
> 
> The loop which does a binary search through the minsyms finds the the
> symbol immediately preceding the address of PC is this:
> 
>   (top-gdb) p newobj
>   $28 = 26
>   (top-gdb) p msymbol[newobj]
>   $29 = {mginfo = {name = 0x10448845 "_image_base__", value = {
> 	ivalue = 4194304, block = 0x400000, bytes = 0x400000 "MZ\220",
> 	address = 0x400000, common_block = 0x400000, chain = 0x400000},
>       language_specific = {obstack = 0x0, demangled_name = 0x0},
>       language = language_auto, ada_mangled = 0, section = 0}, size = 
> 0,
>     filename = 0x0, type = mst_abs, created_by_gdb = 0, target_flag_1 = 
> 0,
>     target_flag_2 = 0, has_size = 0, hash_next = 0x0, 
> demangled_hash_next = 0x0}
> 
> (our PC is 0x40126d).
> 
> Then this loop:
> 
> 	      /* Skip various undesirable symbols.  */
> 	      while (hi >= 0)
> 		{
> 
> decrements 'hi' all the way down to 5, because all the preceding
> symbols have the type mst_abs:
> 
>   (top-gdb) p hi
>   $46 = 5
>   (top-gdb) p msymbol[hi]
>   $47 = {mginfo = {name = 0x1044858d "__register_frame_info", value = {
> 	ivalue = 0, block = 0x0, bytes = 0x0, address = 0x0,
> 	common_block = 0x0, chain = 0x0}, language_specific = {obstack = 0x0,
> 	demangled_name = 0x0}, language = language_auto, ada_mangled = 0,
>       section = 0}, size = 0, filename = 0x0, type = mst_text,
>     created_by_gdb = 0, target_flag_1 = 0, target_flag_2 = 0, has_size 
> = 0,
>     hash_next = 0x0, demangled_hash_next = 0x0}
> 
> Note that this symbol's address is zero.  This symbol is then
> returned, and so cache_pc_function_low becomes zero.  Then we get to
> this:
> 
>    cache_pc_function_high = minimal_symbol_upper_bound (msymbol);
> 
> minimal_symbol_upper_bound then looks at the following symbols trying
> to find the one whose address is different from zero:
> 
>   for (i = 1; MSYMBOL_LINKAGE_NAME (msymbol + i) != NULL; i++)
>     {
>       if ((MSYMBOL_VALUE_RAW_ADDRESS (msymbol + i)
> 	   != MSYMBOL_VALUE_RAW_ADDRESS (msymbol))
> 	  && MSYMBOL_SECTION (msymbol + i) == section)
> 	break;
>     }
> 
> It finds such a symbol in the 10th entry:
> 
>   (top-gdb) p msymbol[1]
>   $76 = {mginfo = {name = 0x10448a55 "__set_app_type", value = {ivalue 
> = 0,
> 	block = 0x0, bytes = 0x0, address = 0x0, common_block = 0x0,
> 	chain = 0x0}, language_specific = {obstack = 0x0,
> 	demangled_name = 0x0}, language = language_auto, ada_mangled = 0,
>       section = 0}, size = 0, filename = 0x0, type = mst_abs,
>     created_by_gdb = 0, target_flag_1 = 0, target_flag_2 = 0, has_size 
> = 0,
>     hash_next = 0x0, demangled_hash_next = 0x0}
>   (top-gdb) p msymbol[2]
>   $77 = {mginfo = {name = 0x104487ad "_dll__", value = {ivalue = 0,
> 	block = 0x0, bytes = 0x0, address = 0x0, common_block = 0x0,
> 	chain = 0x0}, language_specific = {obstack = 0x0,
> 	demangled_name = 0x0}, language = language_auto, ada_mangled = 0,
>       section = 0}, size = 0, filename = 0x0, type = mst_abs,
>     created_by_gdb = 0, target_flag_1 = 0, target_flag_2 = 0, has_size 
> = 0,
>     hash_next = 0x0, demangled_hash_next = 0x0}
>   (top-gdb) p msymbol[3]
>   $78 = {mginfo = {name = 0x104483cd "_dll_characteristics__", value = 
> {
> 	ivalue = 0, block = 0x0, bytes = 0x0, address = 0x0,
> 	common_block = 0x0, chain = 0x0}, language_specific = {obstack = 0x0,
> 	demangled_name = 0x0}, language = language_auto, ada_mangled = 0,
>       section = 0}, size = 0, filename = 0x0, type = mst_abs,
>     created_by_gdb = 0, target_flag_1 = 0, target_flag_2 = 0, has_size 
> = 0,
>     hash_next = 0x0, demangled_hash_next = 0x0}
>   (top-gdb) p msymbol[3]
>   $79 = {mginfo = {name = 0x104483cd "_dll_characteristics__", value = 
> {
> 	ivalue = 0, block = 0x0, bytes = 0x0, address = 0x0,
> 	common_block = 0x0, chain = 0x0}, language_specific = {obstack = 0x0,
> 	demangled_name = 0x0}, language = language_auto, ada_mangled = 0,
>       section = 0}, size = 0, filename = 0x0, type = mst_abs,
>     created_by_gdb = 0, target_flag_1 = 0, target_flag_2 = 0, has_size 
> = 0,
>     hash_next = 0x0, demangled_hash_next = 0x0}
>   (top-gdb) p msymbol[4]
>   $80 = {mginfo = {name = 0x1044868d "_fpreset", value = {ivalue = 0,
> 	block = 0x0, bytes = 0x0, address = 0x0, common_block = 0x0,
> 	chain = 0x0}, language_specific = {obstack = 0x0,
> 	demangled_name = 0x0}, language = language_auto, ada_mangled = 0,
>       section = 0}, size = 0, filename = 0x0, type = mst_abs,
>     created_by_gdb = 0, target_flag_1 = 0, target_flag_2 = 0, has_size 
> = 0,
>     hash_next = 0x0, demangled_hash_next = 0x0}
>   (top-gdb) p msymbol[5]
>   $81 = {mginfo = {name = 0x1044fead "_loader_flags__", value = {ivalue 
> = 0,
> 	block = 0x0, bytes = 0x0, address = 0x0, common_block = 0x0,
> 	chain = 0x0}, language_specific = {obstack = 0x0,
> 	demangled_name = 0x0}, language = language_auto, ada_mangled = 0,
>       section = 0}, size = 0, filename = 0x0, type = mst_abs,
>     created_by_gdb = 0, target_flag_1 = 0, target_flag_2 = 0, has_size 
> = 0,
>     hash_next = 0x0, demangled_hash_next = 0x0}
>   (top-gdb) p msymbol[6]
>   $82 = {mginfo = {name = 0x1044ff9d "_minor_image_version__", value = 
> {
> 	ivalue = 0, block = 0x0, bytes = 0x0, address = 0x0,
> 	common_block = 0x0, chain = 0x0}, language_specific = {obstack = 0x0,
> 	demangled_name = 0x0}, language = language_auto, ada_mangled = 0,
>       section = 0}, size = 0, filename = 0x0, type = mst_abs,
>     created_by_gdb = 0, target_flag_1 = 0, target_flag_2 = 0, has_size 
> = 0,
>     hash_next = 0x0, demangled_hash_next = 0x0}
>   (top-gdb) p msymbol[7]
>   $83 = {mginfo = {name = 0x104487cd "_minor_os_version__", value = {
> 	ivalue = 0, block = 0x0, bytes = 0x0, address = 0x0,
> 	common_block = 0x0, chain = 0x0}, language_specific = {obstack = 0x0,
> 	demangled_name = 0x0}, language = language_auto, ada_mangled = 0,
>       section = 0}, size = 0, filename = 0x0, type = mst_abs,
>     created_by_gdb = 0, target_flag_1 = 0, target_flag_2 = 0, has_size 
> = 0,
>     hash_next = 0x0, demangled_hash_next = 0x0}
>   (top-gdb) p msymbol[8]
>   $84 = {mginfo = {name = 0x1044ff65 "_minor_subsystem_version__", 
> value = {
> 	ivalue = 0, block = 0x0, bytes = 0x0, address = 0x0,
> 	common_block = 0x0, chain = 0x0}, language_specific = {obstack = 0x0,
> 	demangled_name = 0x0}, language = language_auto, ada_mangled = 0,
>       section = 0}, size = 0, filename = 0x0, type = mst_abs,
>     created_by_gdb = 0, target_flag_1 = 0, target_flag_2 = 0, has_size 
> = 0,
>     hash_next = 0x0, demangled_hash_next = 0x0}
>   (top-gdb) p msymbol[9]
>   $85 = {mginfo = {name = 0x10448b35 "_rt_psrelocs_size", value = 
> {ivalue = 0,
> 	block = 0x0, bytes = 0x0, address = 0x0, common_block = 0x0,
> 	chain = 0x0}, language_specific = {obstack = 0x0,
> 	demangled_name = 0x0}, language = language_auto, ada_mangled = 0,
>       section = 0}, size = 0, filename = 0x0, type = mst_abs,
>     created_by_gdb = 0, target_flag_1 = 0, target_flag_2 = 0, has_size 
> = 0,
>     hash_next = 0x0, demangled_hash_next = 0x0}
>   (top-gdb) p msymbol[10]
>   $86 = {mginfo = {name = 0x1044fe8d "_major_image_version__", value = 
> {
> 	ivalue = 1, block = 0x1,
> 	bytes = 0x1 <error: Cannot access memory at address 0x1>,
> 	address = 0x1, common_block = 0x1, chain = 0x1}, language_specific = {
> 	obstack = 0x0, demangled_name = 0x0}, language = language_auto,
>       ada_mangled = 0, section = 0}, size = 0, filename = 0x0, type = 
> mst_abs,
>     created_by_gdb = 0, target_flag_1 = 0, target_flag_2 = 0, has_size 
> = 0,
>     hash_next = 0x0, demangled_hash_next = 0x0}
> 
> And so cache_pc_function_high becomes 1.

Ok, from what I understand, all these "mst_abs" symbols do not represent 
addresses.  They just represent numerical "values", like version 
numbers, alignment sizes, etc.  So it seems right to skip them when 
looking for the minimal symbol preceding pc.

It looks like minimal_symbol_upper_bound is buggy, in that it should not 
consider these mst_abs.  If we are looking for the end of a memory 
range, we should not consider those symbols that do not even represent 
memory addresses...

>> Actually, I think I would investigate this line in 
>> find_pc_partial_function:
>> 
>>   msymbol = lookup_minimal_symbol_by_pc_section (mapped_pc, section);
>> 
>> This is where we ask the question "which is the closest minimal symbol 
>> that is <= than PC".
>> I would then try to see if the returned msymbol makes sense.  If you 
>> can give its name and
>> address, it would be a good start.  If we find it doesn't make sense, 
>> I'd start looking at
>> why lookup_minimal_symbol_by_pc_section returned that.
> 
> That's what I did.  The problem seems to be that the low value of PC
> doesn't allow GDB to find a reasonable symbol; what it finds are
> symbols with very low addresses, which don't look like symbols
> relevant to the issue at hand.  I see the same symbols and addresses
> in the output of "objdump -t" (I can show it if you want).

If you could pastebin it, or send it as an attachment, I think it would 
be useful.  Consider sending the output of "objdump -x", which I think 
gives a superset of "objdump -t".

> Where do we go from here?

I would say

1. investigate if the text symbol at address 0 really has business being 
there.
2. investigate if there should be some text symbol that should really 
contain 0x0040126d, that for some reason does not end up in GDB's 
minimal symbol table.

Simon

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: GDB internal error in pc_in_thread_step_range
  2018-12-20  0:16                 ` Simon Marchi
@ 2018-12-20 15:45                   ` Eli Zaretskii
  2018-12-20 23:03                     ` Simon Marchi
  0 siblings, 1 reply; 25+ messages in thread
From: Eli Zaretskii @ 2018-12-20 15:45 UTC (permalink / raw)
  To: Simon Marchi; +Cc: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 8512 bytes --]

> Date: Wed, 19 Dec 2018 19:16:15 -0500
> From: Simon Marchi <simon.marchi@polymtl.ca>
> Cc: gdb-patches@sourceware.org
> 
> >   (top-gdb) p msymbol
> >   $3 = {minsym = 0x10450d38, objfile = 0x10443b48}
> >   (top-gdb) p msymbol.minsym.mginfo.name
> >   $4 = 0x104485cd "__register_frame_info"
> >   (top-gdb) p msymbol.minsym.mginfo
> >   $5 = {name = 0x104485cd "__register_frame_info", value = {ivalue = 0,
> >       block = 0x0, bytes = 0x0, address = 0x0, common_block = 0x0,
> >       chain = 0x0}, language_specific = {obstack = 0x0, demangled_name 
> > = 0x0},
> >     language = language_auto, ada_mangled = 0, section = 0}
> 
> Ok.  Well this is already strange.  Why is there an mst_text (code) 
> symbol with a value of 0?

Its address is zero because it's an unresolved symbol:

  d:\usr\eli>nm -A hello0.exe | fgrep " U "
  hello0.exe:         U ___deregister_frame_info
  hello0.exe:         U ___register_frame_info
  hello0.exe:         U __Jv_RegisterClasses

This symbol comes from a weak symbol defined in MinGW crtbegin.o:

  d:\usr\eli>nm -A lib/gcc/mingw32/6.3.0/crtbegin.o | fgrep _frame_info
  lib/gcc/mingw32/6.3.0/crtbegin.o:00000000 A .weak.___deregister_frame_info.___EH_FRAME_BEGIN__
  lib/gcc/mingw32/6.3.0/crtbegin.o:00000000 A .weak.___register_frame_info.___EH_FRAME_BEGIN__
  lib/gcc/mingw32/6.3.0/crtbegin.o:         w ___deregister_frame_info
  lib/gcc/mingw32/6.3.0/crtbegin.o:         w ___register_frame_info

> If your binary is anything like those I can 
> produce with x86_64-w64-mingw32-gcc (and it looks similar, given the 
> addresses you show), your "image base" is likely 0x400000, and "base of 
> code" 0x1000 (0x401000 in absolute).  I found this information using 
> "objdump -x", in the header somewhere.  I therefore expect all text 
> symbols to be >= 0x401000.  I would start digging why this text symbol 
> with a value of 0 exists.

See above.  But please note that I use mingw.org's MinGW, and my
executables are 32-bit, whereas you use MinGW64 and 64-bit
executables.  So some details might be different; in particular, I
don't think MinGW64 has this problematic symbol, because it's specific
to the DWARF2 exception unwinding implemented in libgcc, which 64-bit
Windows executables don't use.

> It would be interesting to look at some other symbols in the msymbols 
> vector.  Are the other mst_text symbols >= 0x401000?

There are 2 more unresolved mst_text symbols, see above; they all have
a zero address.  All the others are above 0x401000, indeed.

The lowest-address resolved minimal symbol whose type is mst_text is
this:

  (top-gdb) p msymbol[22]
  $112 = {mginfo = {name = 0x10447d95 "_mingw32_init_mainargs", value = {
	ivalue = 4199072, block = 0x4012a0 <_mingw32_init_mainargs>,
	bytes = 0x4012a0 <_mingw32_init_mainargs> "Æ\222?<\215D$,\307D$\004",
	address = 0x4012a0, common_block = 0x4012a0 <_mingw32_init_mainargs>,
	chain = 0x4012a0 <_mingw32_init_mainargs>}, language_specific = {
	obstack = 0x0, demangled_name = 0x0}, language = language_auto,
      ada_mangled = 0, section = 0}, size = 0, filename = 0x0, type = mst_text,
    created_by_gdb = 0, target_flag_1 = 0, target_flag_2 = 0, has_size = 0,
    hash_next = 0x0, demangled_hash_next = 0x0}

Interestingly, objdump shows this symbol in section 1:

  [  0](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x000002a0 __mingw32_init_mainargs

whereas the above minsym information shows section = 0.  Is this
expected?  If "real" symbols were to have section > 0, we could
perhaps reject the unresolved ones.

> Assuming this minimal symbol is wrong and assuming it wasn't there, then 
> I guess the search would fail and we would fall in the "Cannot find 
> bounds of current function" case of prepare_one_step?  That would be 
> appropriate in this case.

It's not wrong, but perhaps lookup_minimal_symbol_by_pc_section should
reject unresolved symbols for this purpose.  However, the question is
how?  One possibility is by their zero address.  (I don't see the weak
attribute, or any other indication of its being unresolved, in the
minimal symbol attributes.)

In any case, if we do call the "Cannot find bounds of current
function" error, that will throw to the command loop, which I think is
undesirable in this case.  We want GDB to step out of this code, not
to error out.

> Ok, from what I understand, all these "mst_abs" symbols do not represent 
> addresses.  They just represent numerical "values", like version 
> numbers, alignment sizes, etc.  So it seems right to skip them when 
> looking for the minimal symbol preceding pc.
> 
> It looks like minimal_symbol_upper_bound is buggy, in that it should not 
> consider these mst_abs.  If we are looking for the end of a memory 
> range, we should not consider those symbols that do not even represent 
> memory addresses...

Indeed, the following change is enough to avoid the internal error:

--- gdb/minsyms.c~0	2018-07-04 18:41:59.000000000 +0300
+++ gdb/minsyms.c	2018-12-20 08:06:11.516834500 +0200
@@ -1514,7 +1514,8 @@ minimal_symbol_upper_bound (struct bound
     {
       if ((MSYMBOL_VALUE_RAW_ADDRESS (msymbol + i)
 	   != MSYMBOL_VALUE_RAW_ADDRESS (msymbol))
-	  && MSYMBOL_SECTION (msymbol + i) == section)
+	  && MSYMBOL_SECTION (msymbol + i) == section
+	  && MSYMBOL_TYPE (msymbol + i) != mst_abs)
 	break;
     }
 
However, it still shows the incorrect function name from the
zero-address symbol:

  7       }
  (gdb) n
  0x00401288 in __register_frame_info ()
  (gdb) n
  Single stepping until exit from function __register_frame_info,
  which has no line number information.
  [Inferior 1 (process 10424) exited normally]

I think if we want to avoid showing __register_frame_info, we need
further changes in lookup_minimal_symbol_by_pc_section.  But I don't
see how this will help us, unless we also allow displaying the above
message for functions whose names we don't know, perhaps saying
something like

  Single stepping until exit from function <unknown>

> > That's what I did.  The problem seems to be that the low value of PC
> > doesn't allow GDB to find a reasonable symbol; what it finds are
> > symbols with very low addresses, which don't look like symbols
> > relevant to the issue at hand.  I see the same symbols and addresses
> > in the output of "objdump -t" (I can show it if you want).
> 
> If you could pastebin it, or send it as an attachment, I think it would 
> be useful.  Consider sending the output of "objdump -x", which I think 
> gives a superset of "objdump -t".

Attached.

> > Where do we go from here?
> 
> I would say
> 
> 1. investigate if the text symbol at address 0 really has business being 
> there.

Done.

> 2. investigate if there should be some text symbol that should really 
> contain 0x0040126d, that for some reason does not end up in GDB's 
> minimal symbol table.

The function in which the PC value of 0x401288 lives is
__mingw_CRTStartup, which ends like this:

  /* Call the main() function. If the user does not supply one
   * the one in the 'libmingw32.a' library will be linked in, and
   * that one calls WinMain().  See main.c in the 'lib' directory
   * for more details.
   */
  nRet = main (_argc, _argv, environ);

  /* Perform exit processing for the C library. This means flushing
   * output and calling atexit() registered functions.
   */
  _cexit ();

  ExitProcess (nRet);
}

This function is declared in the MinGW runtime sources as follows:

  static __MINGW_ATTRIB_NORETURN void __mingw_CRTStartup (void);

But its symbol is not in the symbol table.  Not sure why, perhaps
because it's a static function?  But the code is there, starting at
the address 0x4011b0.  The last part, after exiting 'main', which
corresponds to the above source snippet is this:

  (gdb) disassemble 0x401283,0x401294
  Dump of assembler code from 0x401283 to 0x401294:
     0x00401283 <__register_frame_info+4199043>:  call   0x401460 <main>
     0x00401288 <__register_frame_info+4199048>:  mov    %eax,%ebx
     0x0040128a <__register_frame_info+4199050>:  call   0x403a90 <_cexit>
     0x0040128f <__register_frame_info+4199055>:  mov    %ebx,(%esp)
     0x00401292 <__register_frame_info+4199058>:  call   0x403b28 <ExitProcess@4>

So when this problem happens, we are at the "mov %eax,%ebx"
instruction after exiting 'main', as I'd expect.


[-- Attachment #2: objdump_x.txt --]
[-- Type: text/plain, Size: 36151 bytes --]


hello0.exe:     file format pei-i386
hello0.exe
architecture: i386, flags 0x0000013a:
EXEC_P, HAS_DEBUG, HAS_SYMS, HAS_LOCALS, D_PAGED
start address 0x004012e0

Characteristics 0x107
	relocations stripped
	executable
	line numbers stripped
	32 bit words

Time/Date		Sun Nov 18 09:35:52 2018
Magic			010b	(PE32)
MajorLinkerVersion	2
MinorLinkerVersion	31
SizeOfCode		00002c00
SizeOfInitializedData	00004600
SizeOfUninitializedData	00000200
AddressOfEntryPoint	000012e0
BaseOfCode		00001000
BaseOfData		00004000
ImageBase		00400000
SectionAlignment	00001000
FileAlignment		00000200
MajorOSystemVersion	4
MinorOSystemVersion	0
MajorImageVersion	1
MinorImageVersion	0
MajorSubsystemVersion	4
MinorSubsystemVersion	0
Win32Version		00000000
SizeOfImage		00015000
SizeOfHeaders		00000400
CheckSum		00011add
Subsystem		00000003	(Windows CUI)
DllCharacteristics	00000000
SizeOfStackReserve	00200000
SizeOfStackCommit	00001000
SizeOfHeapReserve	00100000
SizeOfHeapCommit	00001000
LoaderFlags		00000000
NumberOfRvaAndSizes	00000010

The Data Directory
Entry 0 00000000 00000000 Export Directory [.edata (or where ever we found it)]
Entry 1 00008000 000005bc Import Directory [parts of .idata]
Entry 2 00000000 00000000 Resource Directory [.rsrc]
Entry 3 00000000 00000000 Exception Directory [.pdata]
Entry 4 00000000 00000000 Security Directory
Entry 5 00000000 00000000 Base Relocation Directory [.reloc]
Entry 6 00000000 00000000 Debug Directory
Entry 7 00000000 00000000 Description Directory
Entry 8 00000000 00000000 Special Directory
Entry 9 0000a004 00000018 Thread Storage Directory [.tls]
Entry a 00000000 00000000 Load Configuration Directory
Entry b 00000000 00000000 Bound Import Directory
Entry c 00008128 000000d8 Import Address Table Directory
Entry d 00000000 00000000 Delay Import Directory
Entry e 00000000 00000000 CLR Runtime Header
Entry f 00000000 00000000 Reserved

There is an import table in .idata at 0x408000

The Import Tables (interpreted .idata section contents)
 vma:            Hint    Time      Forward  DLL       First
                 Table   Stamp     Chain    Name      Thunk
 00008000	00008050 00000000 00000000 00008510 00008128

	DLL Name: KERNEL32.dll
	vma:  Hint/Ord Member-Name Bound-To
	8200	  208  DeleteCriticalSection
	8218	  237  EnterCriticalSection
	8230	  280  ExitProcess
	823e	  301  FindClose
	824a	  305  FindFirstFileA
	825c	  322  FindNextFileA
	826c	  353  FreeLibrary
	827a	  389  GetCommandLineA
	828c	  511  GetLastError
	829c	  530  GetModuleHandleA
	82b0	  578  GetProcAddress
	82c2	  735  InitializeCriticalSection
	82de	  815  LeaveCriticalSection
	82f6	  818  LoadLibraryA
	8306	 1141  SetUnhandledExceptionFilter
	8324	 1174  TlsGetValue
	8332	 1214  VirtualProtect
	8344	 1216  VirtualQuery

 00008014	0000809c 00000000 00000000 00008528 00008174

	DLL Name: msvcrt.dll
	vma:  Hint/Ord Member-Name Bound-To
	8354	   80  _strdup
	835e	   82  _stricoll

 00008028	000080a8 00000000 00000000 000085b0 00008180

	DLL Name: msvcrt.dll
	vma:  Hint/Ord Member-Name Bound-To
	836a	   89  __getmainargs
	837a	  120  __mb_cur_max
	838a	  132  __p__environ
	839a	  134  __p__fmode
	83a8	  154  __set_app_type
	83ba	  220  _cexit
	83c4	  286  _errno
	83ce	  325  _fpreset
	83da	  351  _fullpath
	83e6	  418  _iob
	83ee	  423  _isctype
	83fa	  690  _onexit
	8404	  699  _pctype
	840e	  754  _setmode
	841a	 1084  abort
	8422	 1092  atexit
	842c	 1099  calloc
	8436	 1132  free
	843e	 1143  fwrite
	8448	 1188  malloc
	8452	 1195  mbstowcs
	845e	 1200  memcpy
	8468	 1213  puts
	8470	 1221  realloc
	847a	 1228  setlocale
	8486	 1230  signal
	8490	 1243  strcoll
	849a	 1250  strlen
	84a4	 1278  tolower
	84ae	 1285  vfprintf
	84ba	 1326  wcstombs

 0000803c	00000000 00000000 00000000 00000000 00000000

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00002b74  00401000  00401000  00000400  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE, DATA
  1 .data         0000001c  00404000  00404000  00003000  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  2 .rdata        000002fc  00405000  00405000  00003200  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .eh_frame     0000099c  00406000  00406000  00003600  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .bss          00000070  00407000  00407000  00000000  2**2
                  ALLOC
  5 .idata        000005bc  00408000  00408000  00004000  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  6 .CRT          00000018  00409000  00409000  00004600  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  7 .tls          00000020  0040a000  0040a000  00004800  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  8 .debug_aranges 00000058  0040b000  0040b000  00004a00  2**3
                  CONTENTS, READONLY, DEBUGGING
  9 .debug_info   00001e7f  0040c000  0040c000  00004c00  2**0
                  CONTENTS, READONLY, DEBUGGING
 10 .debug_abbrev 000001be  0040e000  0040e000  00006c00  2**0
                  CONTENTS, READONLY, DEBUGGING
 11 .debug_line   000002b8  0040f000  0040f000  00006e00  2**0
                  CONTENTS, READONLY, DEBUGGING
 12 .debug_frame  00000038  00410000  00410000  00007200  2**2
                  CONTENTS, READONLY, DEBUGGING
 13 .debug_macro  00003f1d  00411000  00411000  00007400  2**0
                  CONTENTS, READONLY, DEBUGGING
SYMBOL TABLE:
[  0](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x000002a0 __mingw32_init_mainargs
[  1](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x000002e0 _mainCRTStartup
[  2](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000300 _WinMainCRTStartup
[  3](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000320 _atexit
[  4](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000330 __onexit
[  5](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .text
AUX scnlen 0x336 nreloc 42 nlnno 0
[  7](sec  5)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .bss
AUX scnlen 0x8 nreloc 0 nlnno 0
[  9](sec -2)(fl 0x00)(ty   0)(scl 103) (nx 1) 0x0000001e cygming-crtbegin.c
File 
[ 11](sec  5)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000008 _obj
[ 12](sec  2)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000000 _deregister_frame_fn
[ 13](sec  2)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000018 ___JCR_LIST__
[ 14](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 1) 0x00000340 ___gcc_register_frame
AUX tagndx 0 ttlsiz 0x0 lnnos 0 next 0
[ 16](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000430 ___gcc_deregister_frame
[ 17](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000340 .text
AUX scnlen 0x11e nreloc 28 nlnno 0
[ 19](sec  2)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .data
AUX scnlen 0x4 nreloc 0 nlnno 0
[ 21](sec  5)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000008 .bss
AUX scnlen 0x18 nreloc 0 nlnno 0
[ 23](sec  4)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x000000b8 .eh_frame
AUX scnlen 0x64 nreloc 2 nlnno 0
[ 25](sec  3)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .rdata
AUX scnlen 0x63 nreloc 0 nlnno 0
[ 27](sec  3)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x0000015c .rdata$zzz
AUX scnlen 0x11 nreloc 0 nlnno 0
[ 29](sec  2)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000018 .jcr
[ 30](sec -2)(fl 0x00)(ty   0)(scl 103) (nx 1) 0x0000006a hello.c
File 
[ 32](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 1) 0x00000460 _main
AUX tagndx 0 ttlsiz 0x0 lnnos 0 next 0
[ 34](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000460 .text
AUX scnlen 0x21 nreloc 3 nlnno 0
[ 36](sec  2)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000004 .data
AUX scnlen 0x0 nreloc 0 nlnno 0
[ 38](sec  5)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000020 .bss
AUX scnlen 0x0 nreloc 0 nlnno 0
[ 40](sec  3)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000064 .rdata
AUX scnlen 0x18 nreloc 0 nlnno 0
[ 42](sec 10)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .debug_info
AUX scnlen 0x180 nreloc 5 nlnno 0
[ 44](sec 11)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .debug_abbrev
AUX scnlen 0x8f nreloc 0 nlnno 0
[ 46](sec  9)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .debug_aranges
AUX scnlen 0x20 nreloc 2 nlnno 0
[ 48](sec 14)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .debug_macro
AUX scnlen 0x3f1d nreloc 1 nlnno 0
[ 50](sec 12)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .debug_line
AUX scnlen 0xf0 nreloc 1 nlnno 0
[ 52](sec  3)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000170 .rdata$zzz
AUX scnlen 0x23 nreloc 0 nlnno 0
[ 54](sec  4)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x0000011c .eh_frame
AUX scnlen 0x38 nreloc 1 nlnno 0
[ 56](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 1) 0x00000490 __setargv
AUX tagndx 0 ttlsiz 0x0 lnnos 0 next 0
[ 58](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000490 .text
AUX scnlen 0x39f nreloc 15 nlnno 0
[ 60](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 1) 0x00000830 ___cpu_features_init
AUX tagndx 0 ttlsiz 0x0 lnnos 0 next 0
[ 62](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000830 .text
AUX scnlen 0xdc nreloc 10 nlnno 0
[ 64](sec  5)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000024 .bss
AUX scnlen 0x4 nreloc 0 nlnno 0
[ 66](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 1) 0x00000910 ___do_global_dtors
AUX tagndx 0 ttlsiz 0x0 lnnos 0 next 0
[ 68](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000940 ___do_global_ctors
[ 69](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000990 ___main
[ 70](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000910 .text
AUX scnlen 0x9c nreloc 10 nlnno 0
[ 72](sec  2)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000010 .data
AUX scnlen 0x4 nreloc 1 nlnno 0
[ 74](sec  5)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000028 .bss
AUX scnlen 0x4 nreloc 0 nlnno 0
[ 76](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000a00 ___dyn_tls_init@12
[ 77](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000a90 ___tlregdtor
[ 78](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x000009b0 .text
AUX scnlen 0xe3 nreloc 7 nlnno 0
[ 80](sec  5)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x0000002c .bss
AUX scnlen 0x10 nreloc 0 nlnno 0
[ 82](sec  7)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000014 .CRT$XDZ
AUX scnlen 0x4 nreloc 0 nlnno 0
[ 84](sec  7)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000010 .CRT$XDA
AUX scnlen 0x4 nreloc 0 nlnno 0
[ 86](sec  7)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .CRT$XLA
AUX scnlen 0x4 nreloc 0 nlnno 0
[ 88](sec  8)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x0000001c .tls$ZZZ
AUX scnlen 0x1 nreloc 0 nlnno 0
[ 90](sec  8)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .tls$AAA
AUX scnlen 0x1 nreloc 0 nlnno 0
[ 92](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000b00 ____w64_mingwthr_add_key_dtor
[ 93](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000b90 ____w64_mingwthr_remove_key_dtor
[ 94](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000c30 ___mingw_TLScallback
[ 95](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000aa0 .text
AUX scnlen 0x227 nreloc 35 nlnno 0
[ 97](sec  5)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x0000003c .bss
AUX scnlen 0x20 nreloc 0 nlnno 0
[ 99](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000e10 __pei386_runtime_relocator
[100](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000cd0 .text
AUX scnlen 0x30b nreloc 33 nlnno 0
[102](sec  5)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x0000005c .bss
AUX scnlen 0x4 nreloc 0 nlnno 0
[104](sec  3)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000080 .rdata
AUX scnlen 0xaa nreloc 0 nlnno 0
[106](sec -2)(fl 0x00)(ty   0)(scl 103) (nx 1) 0x0000007c fake
File 
[108](sec 10)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000180 .debug_info
AUX scnlen 0xa7 nreloc 4 nlnno 0
[110](sec 11)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x0000008f .debug_abbrev
AUX scnlen 0x14 nreloc 0 nlnno 0
[112](sec 12)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x000000f0 .debug_line
AUX scnlen 0x71 nreloc 1 nlnno 0
[114](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000fe0 .text
AUX scnlen 0x2a nreloc 0 nlnno 0
[116](sec  2)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000014 .data
AUX scnlen 0x0 nreloc 0 nlnno 0
[118](sec  5)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000068 .bss
AUX scnlen 0x0 nreloc 0 nlnno 0
[120](sec  9)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000020 .debug_aranges
AUX scnlen 0x20 nreloc 2 nlnno 0
[122](sec 13)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .debug_frame
AUX scnlen 0x38 nreloc 2 nlnno 0
[124](sec -2)(fl 0x00)(ty   0)(scl 103) (nx 1) 0x0000010d libgcc2.c
File 
[126](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x0000100c .text
AUX scnlen 0x0 nreloc 0 nlnno 0
[128](sec  2)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000014 .data
AUX scnlen 0x0 nreloc 0 nlnno 0
[130](sec  5)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000068 .bss
AUX scnlen 0x0 nreloc 0 nlnno 0
[132](sec 10)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000227 .debug_info
AUX scnlen 0x1c58 nreloc 4 nlnno 0
[134](sec 11)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x000000a3 .debug_abbrev
AUX scnlen 0x11b nreloc 0 nlnno 0
[136](sec  9)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000040 .debug_aranges
AUX scnlen 0x18 nreloc 1 nlnno 0
[138](sec 12)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000161 .debug_line
AUX scnlen 0x157 nreloc 0 nlnno 0
[140](sec  3)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000284 .rdata$zzz
AUX scnlen 0x11 nreloc 0 nlnno 0
[142](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 1) 0x00001010 _fesetenv
AUX tagndx 0 ttlsiz 0x0 lnnos 0 next 0
[144](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00001010 .text
AUX scnlen 0x6c nreloc 5 nlnno 0
[146](sec  2)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000014 .data
AUX scnlen 0x4 nreloc 0 nlnno 0
[148](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00001fb0 ___mingw_glob
[149](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x000020a0 ___mingw_globfree
[150](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00001080 .text
AUX scnlen 0x107f nreloc 52 nlnno 0
[152](sec  3)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x0000012c .rdata
AUX scnlen 0x13 nreloc 0 nlnno 0
[154](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 1) 0x00002100 ___mingw_dirname
AUX tagndx 0 ttlsiz 0x0 lnnos 0 next 0
[156](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00002100 .text
AUX scnlen 0x3f4 nreloc 27 nlnno 0
[158](sec  5)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000068 .bss
AUX scnlen 0x4 nreloc 0 nlnno 0
[160](sec  3)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000140 .rdata
AUX scnlen 0x6 nreloc 0 nlnno 0
[162](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002680 ___mingw_opendir
[163](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002840 ___mingw_readdir
[164](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002890 ___mingw_closedir
[165](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x000028e0 ___mingw_rewinddir
[166](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002940 ___mingw_telldir
[167](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002970 ___mingw_seekdir
[168](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00002500 .text
AUX scnlen 0x4e1 nreloc 26 nlnno 0
[170](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x000001f8 .idata$5
[171](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x000004ba .idata$6
[172](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x000001f4 .idata$5
[173](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x000004ae .idata$6
[174](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x000001f0 .idata$5
[175](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x000004a4 .idata$6
[176](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x000001ec .idata$5
[177](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x0000049a .idata$6
[178](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x000001e8 .idata$5
[179](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000490 .idata$6
[180](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x000001e4 .idata$5
[181](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000486 .idata$6
[182](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x000001e0 .idata$5
[183](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x0000047a .idata$6
[184](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x000001dc .idata$5
[185](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000470 .idata$6
[186](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x000001d8 .idata$5
[187](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000468 .idata$6
[188](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x000001d4 .idata$5
[189](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x0000045e .idata$6
[190](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x000001d0 .idata$5
[191](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000452 .idata$6
[192](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x000001cc .idata$5
[193](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000448 .idata$6
[194](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x000001c8 .idata$5
[195](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x0000043e .idata$6
[196](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x000001c4 .idata$5
[197](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000436 .idata$6
[198](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x000001c0 .idata$5
[199](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x0000042c .idata$6
[200](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000422 .idata$6
[201](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x000001b8 .idata$5
[202](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x0000041a .idata$6
[203](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x000001b4 .idata$5
[204](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x0000040e .idata$6
[205](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000404 .idata$6
[206](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x000003fa .idata$6
[207](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x000001a8 .idata$5
[208](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x000003ee .idata$6
[209](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x000003e6 .idata$6
[210](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x000001a0 .idata$5
[211](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x000003da .idata$6
[212](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000198 .idata$5
[213](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x000003c4 .idata$6
[214](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000194 .idata$5
[215](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x000003ba .idata$6
[216](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x0000018c .idata$5
[217](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x0000039a .idata$6
[218](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000188 .idata$5
[219](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x0000038a .idata$6
[220](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x0000037a .idata$6
[221](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000180 .idata$5
[222](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x0000036a .idata$6
[223](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x000000a8 .idata$4
[224](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000180 .idata$5
[225](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x0000016c .idata$5
[226](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000344 .idata$6
[227](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000168 .idata$5
[228](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000332 .idata$6
[229](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000164 .idata$5
[230](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000324 .idata$6
[231](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000160 .idata$5
[232](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000306 .idata$6
[233](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x0000015c .idata$5
[234](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x000002f6 .idata$6
[235](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000158 .idata$5
[236](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x000002de .idata$6
[237](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000154 .idata$5
[238](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x000002c2 .idata$6
[239](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000150 .idata$5
[240](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x000002b0 .idata$6
[241](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x0000014c .idata$5
[242](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x0000029c .idata$6
[243](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000148 .idata$5
[244](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x0000028c .idata$6
[245](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000144 .idata$5
[246](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x0000027a .idata$6
[247](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000140 .idata$5
[248](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x0000026c .idata$6
[249](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x0000013c .idata$5
[250](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x0000025c .idata$6
[251](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000138 .idata$5
[252](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x0000024a .idata$6
[253](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000134 .idata$5
[254](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x0000023e .idata$6
[255](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000130 .idata$5
[256](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000230 .idata$6
[257](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x0000012c .idata$5
[258](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000218 .idata$6
[259](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000128 .idata$5
[260](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000200 .idata$6
[261](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000050 .idata$4
[262](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000128 .idata$5
[263](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000178 .idata$5
[264](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x0000035e .idata$6
[265](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000174 .idata$5
[266](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000354 .idata$6
[267](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x0000009c .idata$4
[268](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000174 .idata$5
[269](sec -2)(fl 0x00)(ty   0)(scl 103) (nx 1) 0x00000127 cygming-crtend.c
File 
[271](sec  4)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000960 ___FRAME_END__
[272](sec  2)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000018 ___JCR_END__
[273](sec  1)(fl 0x00)(ty  20)(scl   3) (nx 1) 0x00002b50 _register_frame_ctor
AUX tagndx 0 ttlsiz 0x0 lnnos 0 next 0
[275](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00002b50 .text
AUX scnlen 0x0 nreloc 0 nlnno 0
[277](sec  2)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000018 .data
AUX scnlen 0x0 nreloc 0 nlnno 0
[279](sec  5)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x0000006c .bss
AUX scnlen 0x0 nreloc 0 nlnno 0
[281](sec  4)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000960 .eh_frame
AUX scnlen 0x3c nreloc 1 nlnno 0
[283](sec  2)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000018 .jcr
AUX scnlen 0x4 nreloc 0 nlnno 0
[285](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00002b50 .text.startup
AUX scnlen 0x9 nreloc 1 nlnno 0
[287](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00002b64 .ctors.65535
AUX scnlen 0x4 nreloc 1 nlnno 0
[289](sec  3)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x000002e8 .rdata$zzz
AUX scnlen 0x11 nreloc 0 nlnno 0
[291](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x0000019c .idata$5
[292](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x000003ce .idata$6
[293](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000190 .idata$5
[294](sec  6)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x000003a8 .idata$6
[295](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000138 __imp__FindFirstFileA@8
[296](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002a90 __cexit
[297](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002ab8 _VirtualProtect@16
[298](sec  3)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x000002fc ___RUNTIME_PSEUDO_RELOC_LIST__
[299](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x000001a0 __imp___fullpath
[300](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002b18 _FindFirstFileA@8
[301](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x000001b4 __imp___setmode
[302](sec  2)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 __data_start__
[303](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002b08 _FreeLibrary@4
[304](sec  1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00002b6c ___DTOR_LIST__
[305](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002a58 _free
[306](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000168 __imp__VirtualProtect@16
[307](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x000001ac __imp___onexit
[308](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002a98 ___p__fmode
[309](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000148 __imp__GetLastError@0
[310](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002ac8 _SetUnhandledExceptionFilter@4
[311](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000016c __imp__VirtualQuery@12
[312](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000013c __imp__FindNextFileA@8
[313](sec  8)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 ___tls_start__
[314](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000164 __imp__TlsGetValue@4
[315](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x000005b0 __libmsvcrt_a_iname
[316](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000154 __imp__InitializeCriticalSection@4
[317](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002a88 __errno
[318](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002b38 _DeleteCriticalSection@4
[319](sec  3)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x000002fc __rt_psrelocs_start
[320](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x000001b8 __imp__abort
[321](sec  7)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000004 ___xl_c
[322](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 __dll_characteristics__
[323](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00001000 __size_of_stack_commit__
[324](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00200000 __size_of_stack_reserve__
[325](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000004 __major_subsystem_version__
[326](sec  7)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 ___crt_xl_start__
[327](sec  7)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 ___crt_xi_start__
[328](sec  7)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 ___crt_xi_end__
[329](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000178 __imp__stricoll
[330](sec  7)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000c ___xl_z
[331](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000184 __imp____mb_cur_max
[332](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002af8 _GetLastError@0
[333](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002a30 _puts
[334](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000188 __imp____p__environ
[335](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x000001b0 __imp___pctype
[336](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002ab0 _VirtualQuery@12
[337](sec  5)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000034 _mingw_initltsdrot_force
[338](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x000001a4 __imp___iob
[339](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002af0 _GetModuleHandleA@4
[340](sec  0)(fl 0x00)(ty  20)(scl   2) (nx 1) 0x00000000 ___register_frame_info
AUX tagndx 25 ttlsiz 0x1 lnnos 0 next 0
[342](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000528 __libmoldname_a_iname
[343](sec  5)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000006c _hmod_libgcc
[344](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 .weak.___register_frame_info.___EH_FRAME_BEGIN__
[345](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000174 __imp__strdup
[346](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x000001a8 __imp___isctype
[347](sec  5)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 __bss_start__
[348](sec  3)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x000002fc ___RUNTIME_PSEUDO_RELOC_LIST_END__
[349](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 __fpreset
[350](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00001000 __size_of_heap_commit__
[351](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000198 __imp___errno
[352](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002aa0 ___p__environ
[353](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000150 __imp__GetProcAddress@8
[354](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002ae8 _GetProcAddress@8
[355](sec  7)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000010 ___crt_xp_start__
[356](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x000001f8 __imp__wcstombs
[357](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002a10 _strcoll
[358](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002b00 _GetCommandLineA@0
[359](sec  7)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000010 ___crt_xp_end__
[360](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x000001e4 __imp__signal
[361](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 __dll__
[362](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x000001d8 __imp__puts
[363](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 __minor_os_version__
[364](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002a50 _fwrite
[365](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x000001bc __imp__atexit
[366](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x000001d0 __imp__mbstowcs
[367](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000028 __head_libmsvcrt_a
[368](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00400000 __image_base__
[369](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002a78 __isctype
[370](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00001000 __section_alignment__
[371](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002ad0 _LoadLibraryA@4
[372](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x000029f0 _wcstombs
[373](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000140 __imp__FreeLibrary@4
[374](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002a38 _memcpy
[375](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000200 __IAT_end__
[376](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000014 __head_libmoldname_a
[377](sec  3)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x000002fc __RUNTIME_PSEUDO_RELOC_LIST__
[378](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002a20 _setlocale
[379](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000018c __imp____p__fmode
[380](sec  5)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000004 __argc
[381](sec  8)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 __tls_start
[382](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002b28 _ExitProcess@4
[383](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x000001e8 __imp__strcoll
[384](sec  2)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000001c __data_end__
[385](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002aa8 ___getmainargs
[386](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002b20 _FindClose@4
[387](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002a00 _tolower
[388](sec  7)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 ___xl_a
[389](sec  7)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000008 ___xl_d
[390](sec  1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00002b60 __CTOR_LIST__
[391](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002a40 _mbstowcs
[392](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 ___set_app_type
[393](sec  5)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000064 __CRT_MT
[394](sec  5)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000070 __bss_end__
[395](sec  5)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000020 __CRT_fmode
[396](sec  7)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 ___crt_xc_end__
[397](sec  5)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000038 __tls_index
[398](sec  7)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 ___crt_xc_start__
[399](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002b48 _strdup
[400](sec  5)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 __argv
[401](sec  1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00002b60 ___CTOR_LIST__
[402](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002a60 _calloc
[403](sec  2)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000c __fmode
[404](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 __rt_psrelocs_size
[405](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x000001d4 __imp__memcpy
[406](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002b10 _FindNextFileA@8
[407](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000200 __file_alignment__
[408](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000158 __imp__LeaveCriticalSection@4
[409](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002a28 _realloc
[410](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x000001cc __imp__malloc
[411](sec  4)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x000000b8 ___EH_FRAME_BEGIN__
[412](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000004 __major_os_version__
[413](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x000001dc __imp__realloc
[414](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000128 __IAT_start__
[415](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002b40 _stricoll
[416](sec  8)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000001c __tls_end
[417](sec  8)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00001000 __end__
[418](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000014c __imp__GetModuleHandleA@4
[419](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002a18 _signal
[420](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002a48 _malloc
[421](sec  1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00002b6c __DTOR_LIST__
[422](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000019c __imp___fpreset
[423](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 .weak.___deregister_frame_info.___EH_FRAME_BEGIN__
[424](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002b30 _EnterCriticalSection@4
[425](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002a80 __fullpath
[426](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00100000 __size_of_heap_reserve__
[427](sec  7)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000010 ___crt_xt_start__
[428](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00400000 ___ImageBase
[429](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000003 __subsystem__
[430](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x000001ec __imp__strlen
[431](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 .weak.__Jv_RegisterClasses.___EH_FRAME_BEGIN__
[432](sec  2)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000008 __CRT_fenv
[433](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x000001c0 __imp__calloc
[434](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002a68 _abort
[435](sec  0)(fl 0x00)(ty  20)(scl   2) (nx 1) 0x00000000 __Jv_RegisterClasses
AUX tagndx 27 ttlsiz 0x1 lnnos 0 next 0
[437](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000180 __imp____getmainargs
[438](sec  8)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000020 ___tls_end__
[439](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000130 __imp__ExitProcess@4
[440](sec  5)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000002c _mingw_initltssuo_force
[441](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002ae0 _InitializeCriticalSection@4
[442](sec  5)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000024 ___cpu_features
[443](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x000001c4 __imp__free
[444](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000160 __imp__SetUnhandledExceptionFilter@4
[445](sec  0)(fl 0x00)(ty  20)(scl   2) (nx 1) 0x00000000 ___deregister_frame_info
AUX tagndx 26 ttlsiz 0x1 lnnos 0 next 0
[447](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000001 __major_image_version__
[448](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 __loader_flags__
[449](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x000001f0 __imp__tolower
[450](sec  2)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000004 __CRT_glob
[451](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002a70 __setmode
[452](sec  1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000fe0 ___chkstk_ms
[453](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 __head_libkernel32_a
[454](sec  3)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x000002fc __rt_psrelocs_end
[455](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000194 __imp___cexit
[456](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 __minor_subsystem_version__
[457](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000134 __imp__FindClose@4
[458](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 __minor_image_version__
[459](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x000001f4 __imp__vfprintf
[460](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002a08 _strlen
[461](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000190 __imp____set_app_type
[462](sec  5)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000030 _mingw_initltsdyn_force
[463](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002ac0 _TlsGetValue@4
[464](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000128 __imp__DeleteCriticalSection@4
[465](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00002ad8 _LeaveCriticalSection@4
[466](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000144 __imp__GetCommandLineA@0
[467](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000015c __imp__LoadLibraryA@4
[468](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x000001e0 __imp__setlocale
[469](sec  3)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x000002fc __RUNTIME_PSEUDO_RELOC_LIST_END__
[470](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000510 __libkernel32_a_iname
[471](sec  3)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000007c ___dyn_tls_init_callback
[472](sec  8)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000004 __tls_used
[473](sec  7)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000010 ___crt_xt_end__
[474](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x000029f8 _vfprintf
[475](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000012c __imp__EnterCriticalSection@4
[476](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x000001c8 __imp__fwrite



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: GDB internal error in pc_in_thread_step_range
  2018-12-20 15:45                   ` Eli Zaretskii
@ 2018-12-20 23:03                     ` Simon Marchi
  2018-12-22  8:44                       ` Eli Zaretskii
  0 siblings, 1 reply; 25+ messages in thread
From: Simon Marchi @ 2018-12-20 23:03 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches

On 2018-12-20 10:45, Eli Zaretskii wrote:
>> Date: Wed, 19 Dec 2018 19:16:15 -0500
>> From: Simon Marchi <simon.marchi@polymtl.ca>
>> Cc: gdb-patches@sourceware.org
>> 
>> >   (top-gdb) p msymbol
>> >   $3 = {minsym = 0x10450d38, objfile = 0x10443b48}
>> >   (top-gdb) p msymbol.minsym.mginfo.name
>> >   $4 = 0x104485cd "__register_frame_info"
>> >   (top-gdb) p msymbol.minsym.mginfo
>> >   $5 = {name = 0x104485cd "__register_frame_info", value = {ivalue = 0,
>> >       block = 0x0, bytes = 0x0, address = 0x0, common_block = 0x0,
>> >       chain = 0x0}, language_specific = {obstack = 0x0, demangled_name
>> > = 0x0},
>> >     language = language_auto, ada_mangled = 0, section = 0}
>> 
>> Ok.  Well this is already strange.  Why is there an mst_text (code)
>> symbol with a value of 0?
> 
> Its address is zero because it's an unresolved symbol:
> 
>   d:\usr\eli>nm -A hello0.exe | fgrep " U "
>   hello0.exe:         U ___deregister_frame_info
>   hello0.exe:         U ___register_frame_info
>   hello0.exe:         U __Jv_RegisterClasses

Huh, interesting.  I looked at elfread, and similar undefined symbols 
are skipped:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=blob;f=gdb/elfread.c;h=71e6fcca6ec62ec57f93f06d8a9913612be6f9e2;hb=HEAD#l270

> This symbol comes from a weak symbol defined in MinGW crtbegin.o:
> 
>   d:\usr\eli>nm -A lib/gcc/mingw32/6.3.0/crtbegin.o | fgrep _frame_info
>   lib/gcc/mingw32/6.3.0/crtbegin.o:00000000 A
> .weak.___deregister_frame_info.___EH_FRAME_BEGIN__
>   lib/gcc/mingw32/6.3.0/crtbegin.o:00000000 A
> .weak.___register_frame_info.___EH_FRAME_BEGIN__
>   lib/gcc/mingw32/6.3.0/crtbegin.o:         w ___deregister_frame_info
>   lib/gcc/mingw32/6.3.0/crtbegin.o:         w ___register_frame_info

Is crtbegin.o an object file you link with statically when compiling 
with mingw?  If so, why would you end up with an undefined reference in 
the final executable?  Or is it linked dynamically at runtime?

>> If your binary is anything like those I can
>> produce with x86_64-w64-mingw32-gcc (and it looks similar, given the
>> addresses you show), your "image base" is likely 0x400000, and "base 
>> of
>> code" 0x1000 (0x401000 in absolute).  I found this information using
>> "objdump -x", in the header somewhere.  I therefore expect all text
>> symbols to be >= 0x401000.  I would start digging why this text symbol
>> with a value of 0 exists.
> 
> See above.  But please note that I use mingw.org's MinGW, and my
> executables are 32-bit, whereas you use MinGW64 and 64-bit
> executables.  So some details might be different; in particular, I
> don't think MinGW64 has this problematic symbol, because it's specific
> to the DWARF2 exception unwinding implemented in libgcc, which 64-bit
> Windows executables don't use.

Indeed, they are similar but not identical.  The file you provided as 
attachment is very useful to see what's in your binary.

>> It would be interesting to look at some other symbols in the msymbols
>> vector.  Are the other mst_text symbols >= 0x401000?
> 
> There are 2 more unresolved mst_text symbols, see above; they all have
> a zero address.  All the others are above 0x401000, indeed.
> 
> The lowest-address resolved minimal symbol whose type is mst_text is
> this:
> 
>   (top-gdb) p msymbol[22]
>   $112 = {mginfo = {name = 0x10447d95 "_mingw32_init_mainargs", value = 
> {
> 	ivalue = 4199072, block = 0x4012a0 <_mingw32_init_mainargs>,
> 	bytes = 0x4012a0 <_mingw32_init_mainargs> "Æ\222?<\215D$,\307D$\004",
> 	address = 0x4012a0, common_block = 0x4012a0 <_mingw32_init_mainargs>,
> 	chain = 0x4012a0 <_mingw32_init_mainargs>}, language_specific = {
> 	obstack = 0x0, demangled_name = 0x0}, language = language_auto,
>       ada_mangled = 0, section = 0}, size = 0, filename = 0x0, type = 
> mst_text,
>     created_by_gdb = 0, target_flag_1 = 0, target_flag_2 = 0, has_size 
> = 0,
>     hash_next = 0x0, demangled_hash_next = 0x0}
> 
> Interestingly, objdump shows this symbol in section 1:
> 
>   [  0](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x000002a0
> __mingw32_init_mainargs
> 
> whereas the above minsym information shows section = 0.  Is this
> expected?  If "real" symbols were to have section > 0, we could
> perhaps reject the unresolved ones.

Indeed.  I think the objdump output is misleading.  The indices in the 
"Sections:" section are 0-based.  But the indices in the "SYMBOL TABLE:" 
section look 1-based, as described here:

https://docs.microsoft.com/en-us/windows/desktop/debug/pe-format#coff-symbol-table
https://docs.microsoft.com/en-us/windows/desktop/debug/pe-format#section-number-values

So it looks like we should indeed skip symbols with section == 0.  We 
may also want to skip symbols with section == -1 (IMAGE_SYM_ABSOLUTE), 
such as __major_subsystem_version__.  I don't if anything relies on some 
of those symbols though.

>> Assuming this minimal symbol is wrong and assuming it wasn't there, 
>> then
>> I guess the search would fail and we would fall in the "Cannot find
>> bounds of current function" case of prepare_one_step?  That would be
>> appropriate in this case.
> 
> It's not wrong, but perhaps lookup_minimal_symbol_by_pc_section should
> reject unresolved symbols for this purpose.  However, the question is
> how?  One possibility is by their zero address.  (I don't see the weak
> attribute, or any other indication of its being unresolved, in the
> minimal symbol attributes.)
> 
> In any case, if we do call the "Cannot find bounds of current
> function" error, that will throw to the command loop, which I think is
> undesirable in this case.  We want GDB to step out of this code, not
> to error out.

When we have no line information for the current PC and the user asks us 
to step, we fall back to "single step until out of the current 
function".  But if the minimal symbol information doesn't let us know 
the bounds of the current function, then we can't "single step until out 
of the current function", because we don't know where it starts/end.

In your binary, the lowest .text function symbol is  
__mingw32_init_mainargs at 0x000002a0 (0x4012a0 once relocated).  Your 
pc is 0x40126d (according to an earlier message, but reading lower I 
realize this may not be valid anymore), which is lower.  So there's just 
no minimal symbol for GDB to find.  In that case, it sounds right to 
error our and say "I can't step, I don't have enough information".  The 
user can still use stepi.

Side-question, are there some debug symbols in the binary that could 
describe this location?  Which debug format (DWARF or equivalent) is 
generated when you use -g with mingw?

>> Ok, from what I understand, all these "mst_abs" symbols do not 
>> represent
>> addresses.  They just represent numerical "values", like version
>> numbers, alignment sizes, etc.  So it seems right to skip them when
>> looking for the minimal symbol preceding pc.
>> 
>> It looks like minimal_symbol_upper_bound is buggy, in that it should 
>> not
>> consider these mst_abs.  If we are looking for the end of a memory
>> range, we should not consider those symbols that do not even represent
>> memory addresses...
> 
> Indeed, the following change is enough to avoid the internal error:
> 
> --- gdb/minsyms.c~0	2018-07-04 18:41:59.000000000 +0300
> +++ gdb/minsyms.c	2018-12-20 08:06:11.516834500 +0200
> @@ -1514,7 +1514,8 @@ minimal_symbol_upper_bound (struct bound
>      {
>        if ((MSYMBOL_VALUE_RAW_ADDRESS (msymbol + i)
>  	   != MSYMBOL_VALUE_RAW_ADDRESS (msymbol))
> -	  && MSYMBOL_SECTION (msymbol + i) == section)
> +	  && MSYMBOL_SECTION (msymbol + i) == section
> +	  && MSYMBOL_TYPE (msymbol + i) != mst_abs)
>  	break;
>      }

Note that if we implement the solution of rejecting the symbols with 
section == -1, those mst_abs symbols won't be there anymore.

> However, it still shows the incorrect function name from the
> zero-address symbol:
> 
>   7       }
>   (gdb) n
>   0x00401288 in __register_frame_info ()
>   (gdb) n
>   Single stepping until exit from function __register_frame_info,
>   which has no line number information.
>   [Inferior 1 (process 10424) exited normally]
> 
> I think if we want to avoid showing __register_frame_info, we need
> further changes in lookup_minimal_symbol_by_pc_section.  But I don't
> see how this will help us, unless we also allow displaying the above
> message for functions whose names we don't know, perhaps saying
> something like
> 
>   Single stepping until exit from function <unknown>

The problem is not only that we are missing the name, but most 
importantly that we are missing the bounds of the current function.  
With what you've implemented here, GDB thinks there is a function that 
occupies the range [0,401000[ (something like that), so it single steps 
until it gets out of that range, but the process exits before.

So it kind of works for your use case, but it's not right, IMO.  If the 
process did not exit as it does here, the behavior would be erratic.  If 
GDB doesn't have the data to do something right, it should bail instead 
of doing something random.

>> 2. investigate if there should be some text symbol that should really
>> contain 0x0040126d, that for some reason does not end up in GDB's
>> minimal symbol table.
> 
> The function in which the PC value of 0x401288 lives is
> __mingw_CRTStartup, which ends like this:
> 
>   /* Call the main() function. If the user does not supply one
>    * the one in the 'libmingw32.a' library will be linked in, and
>    * that one calls WinMain().  See main.c in the 'lib' directory
>    * for more details.
>    */
>   nRet = main (_argc, _argv, environ);
> 
>   /* Perform exit processing for the C library. This means flushing
>    * output and calling atexit() registered functions.
>    */
>   _cexit ();
> 
>   ExitProcess (nRet);
> }
> 
> This function is declared in the MinGW runtime sources as follows:
> 
>   static __MINGW_ATTRIB_NORETURN void __mingw_CRTStartup (void);
> 
> But its symbol is not in the symbol table.  Not sure why, perhaps
> because it's a static function?  But the code is there, starting at
> the address 0x4011b0.  The last part, after exiting 'main', which
> corresponds to the above source snippet is this:
> 
>   (gdb) disassemble 0x401283,0x401294
>   Dump of assembler code from 0x401283 to 0x401294:
>      0x00401283 <__register_frame_info+4199043>:  call   0x401460 
> <main>
>      0x00401288 <__register_frame_info+4199048>:  mov    %eax,%ebx
>      0x0040128a <__register_frame_info+4199050>:  call   0x403a90 
> <_cexit>
>      0x0040128f <__register_frame_info+4199055>:  mov    %ebx,(%esp)
>      0x00401292 <__register_frame_info+4199058>:  call   0x403b28
> <ExitProcess@4>
> 
> So when this problem happens, we are at the "mov %eax,%ebx"
> instruction after exiting 'main', as I'd expect.

Ok, well I think it shows the problem quite clearly, some symbol is 
missing for GDB to work properly in that context.  I think that we 
should improve GDB to handle it better error out clearly (instead of 
hitting a failed assert), but I don't think it can do much more.

I guess that having debug info for the file containing 
__mingw_CRTStartup would help, if you really needed to step past main?

Simon

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: GDB internal error in pc_in_thread_step_range
  2018-12-20 23:03                     ` Simon Marchi
@ 2018-12-22  8:44                       ` Eli Zaretskii
  2018-12-22 16:47                         ` Simon Marchi
  0 siblings, 1 reply; 25+ messages in thread
From: Eli Zaretskii @ 2018-12-22  8:44 UTC (permalink / raw)
  To: Simon Marchi; +Cc: gdb-patches

> Date: Thu, 20 Dec 2018 18:03:33 -0500
> From: Simon Marchi <simon.marchi@polymtl.ca>
> Cc: gdb-patches@sourceware.org
> 
> >> Ok.  Well this is already strange.  Why is there an mst_text (code)
> >> symbol with a value of 0?
> > 
> > Its address is zero because it's an unresolved symbol:
> > 
> >   d:\usr\eli>nm -A hello0.exe | fgrep " U "
> >   hello0.exe:         U ___deregister_frame_info
> >   hello0.exe:         U ___register_frame_info
> >   hello0.exe:         U __Jv_RegisterClasses
> 
> Huh, interesting.  I looked at elfread, and similar undefined symbols 
> are skipped:
> 
> https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=blob;f=gdb/elfread.c;h=71e6fcca6ec62ec57f93f06d8a9913612be6f9e2;hb=HEAD#l270

So maybe GDB should skip them as well?

> > This symbol comes from a weak symbol defined in MinGW crtbegin.o:
> > 
> >   d:\usr\eli>nm -A lib/gcc/mingw32/6.3.0/crtbegin.o | fgrep _frame_info
> >   lib/gcc/mingw32/6.3.0/crtbegin.o:00000000 A
> > .weak.___deregister_frame_info.___EH_FRAME_BEGIN__
> >   lib/gcc/mingw32/6.3.0/crtbegin.o:00000000 A
> > .weak.___register_frame_info.___EH_FRAME_BEGIN__
> >   lib/gcc/mingw32/6.3.0/crtbegin.o:         w ___deregister_frame_info
> >   lib/gcc/mingw32/6.3.0/crtbegin.o:         w ___register_frame_info
> 
> Is crtbegin.o an object file you link with statically when compiling 
> with mingw?

Yes.  This file comes with MinGW GCC.

> If so, why would you end up with an undefined reference in 
> the final executable?  Or is it linked dynamically at runtime?

AFAIU, these symbols are only resolved when linking a Java program
using gcj.  See the comments in GCC's source file
libgcc/config/i386/cygming-crtbegin.c, which is where crtbegin.o comes
from.

> > In any case, if we do call the "Cannot find bounds of current
> > function" error, that will throw to the command loop, which I think is
> > undesirable in this case.  We want GDB to step out of this code, not
> > to error out.
> 
> When we have no line information for the current PC and the user asks us 
> to step, we fall back to "single step until out of the current 
> function".  But if the minimal symbol information doesn't let us know 
> the bounds of the current function, then we can't "single step until out 
> of the current function", because we don't know where it starts/end.
> 
> In your binary, the lowest .text function symbol is  
> __mingw32_init_mainargs at 0x000002a0 (0x4012a0 once relocated).  Your 
> pc is 0x40126d (according to an earlier message, but reading lower I 
> realize this may not be valid anymore), which is lower.  So there's just 
> no minimal symbol for GDB to find.  In that case, it sounds right to 
> error our and say "I can't step, I don't have enough information".  The 
> user can still use stepi.

But this use case is somewhat special, IMO: stepping outside of 'main'
can happen unintentionally, and should not cause an error.  It should
let the inferior run to completion without any errors.  Raising an
error in this case is confusing.

> Side-question, are there some debug symbols in the binary that could 
> describe this location?

How do I know that?

> Which debug format (DWARF or equivalent) is generated when you use
> -g with mingw?

It's DWARF2 version 4.

> > --- gdb/minsyms.c~0	2018-07-04 18:41:59.000000000 +0300
> > +++ gdb/minsyms.c	2018-12-20 08:06:11.516834500 +0200
> > @@ -1514,7 +1514,8 @@ minimal_symbol_upper_bound (struct bound
> >      {
> >        if ((MSYMBOL_VALUE_RAW_ADDRESS (msymbol + i)
> >  	   != MSYMBOL_VALUE_RAW_ADDRESS (msymbol))
> > -	  && MSYMBOL_SECTION (msymbol + i) == section)
> > +	  && MSYMBOL_SECTION (msymbol + i) == section
> > +	  && MSYMBOL_TYPE (msymbol + i) != mst_abs)
> >  	break;
> >      }
> 
> Note that if we implement the solution of rejecting the symbols with 
> section == -1, those mst_abs symbols won't be there anymore.

Fine by me.  Should we push such a change?

> > I think if we want to avoid showing __register_frame_info, we need
> > further changes in lookup_minimal_symbol_by_pc_section.  But I don't
> > see how this will help us, unless we also allow displaying the above
> > message for functions whose names we don't know, perhaps saying
> > something like
> > 
> >   Single stepping until exit from function <unknown>
> 
> The problem is not only that we are missing the name, but most 
> importantly that we are missing the bounds of the current function.  
> With what you've implemented here, GDB thinks there is a function that 
> occupies the range [0,401000[ (something like that), so it single steps 
> until it gets out of that range, but the process exits before.

Which IMO is just fine for this specific use case.

> So it kind of works for your use case, but it's not right, IMO.  If the 
> process did not exit as it does here, the behavior would be erratic.

I don't think it would be erratic, we will just see the same

    0x00401nnn in __register_frame_info ()  

for several steps.  Is that so bad?

> Ok, well I think it shows the problem quite clearly, some symbol is 
> missing for GDB to work properly in that context.  I think that we 
> should improve GDB to handle it better error out clearly (instead of 
> hitting a failed assert), but I don't think it can do much more.

Can you suggest a patch?  I'm not sure I understand the behavior that
will be the result.

> I guess that having debug info for the file containing 
> __mingw_CRTStartup would help, if you really needed to step past main?

I don't need to step past main, it just happens in many cases, when I
type one "next" too many.  I would like to avoid any errors in that
case.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: GDB internal error in pc_in_thread_step_range
  2018-12-22  8:44                       ` Eli Zaretskii
@ 2018-12-22 16:47                         ` Simon Marchi
  2018-12-23  5:35                           ` Joel Brobecker
  2018-12-23 16:10                           ` Eli Zaretskii
  0 siblings, 2 replies; 25+ messages in thread
From: Simon Marchi @ 2018-12-22 16:47 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches

On 2018-12-22 03:44, Eli Zaretskii wrote:
>> Date: Thu, 20 Dec 2018 18:03:33 -0500
>> From: Simon Marchi <simon.marchi@polymtl.ca>
>> Cc: gdb-patches@sourceware.org
>> 
>> >> Ok.  Well this is already strange.  Why is there an mst_text (code)
>> >> symbol with a value of 0?
>> >
>> > Its address is zero because it's an unresolved symbol:
>> >
>> >   d:\usr\eli>nm -A hello0.exe | fgrep " U "
>> >   hello0.exe:         U ___deregister_frame_info
>> >   hello0.exe:         U ___register_frame_info
>> >   hello0.exe:         U __Jv_RegisterClasses
>> 
>> Huh, interesting.  I looked at elfread, and similar undefined symbols
>> are skipped:
>> 
>> https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=blob;f=gdb/elfread.c;h=71e6fcca6ec62ec57f93f06d8a9913612be6f9e2;hb=HEAD#l270
> 
> So maybe GDB should skip them as well?

Yes.  Can you please give it a try it?

>> > In any case, if we do call the "Cannot find bounds of current
>> > function" error, that will throw to the command loop, which I think is
>> > undesirable in this case.  We want GDB to step out of this code, not
>> > to error out.
>> 
>> When we have no line information for the current PC and the user asks 
>> us
>> to step, we fall back to "single step until out of the current
>> function".  But if the minimal symbol information doesn't let us know
>> the bounds of the current function, then we can't "single step until 
>> out
>> of the current function", because we don't know where it starts/end.
>> 
>> In your binary, the lowest .text function symbol is
>> __mingw32_init_mainargs at 0x000002a0 (0x4012a0 once relocated).  Your
>> pc is 0x40126d (according to an earlier message, but reading lower I
>> realize this may not be valid anymore), which is lower.  So there's 
>> just
>> no minimal symbol for GDB to find.  In that case, it sounds right to
>> error our and say "I can't step, I don't have enough information".  
>> The
>> user can still use stepi.
> 
> But this use case is somewhat special, IMO: stepping outside of 'main'
> can happen unintentionally, and should not cause an error.  It should
> let the inferior run to completion without any errors.  Raising an
> error in this case is confusing.

Just a precision, it's not the stepping out of main that causes an 
error, it's trying to step again:

<in main>
(gdb) step
<out of main>
(gdb) step
Cannot find bounds of current function

Perhaps the error message could be improved, but I think this is the 
right thing to do.  It is often reported as a bug when "step" lets the 
program run free and acts as "continue".  If you find yourself in that 
situation again, why not just use "continue" to let the program exit?

This case would work just fine if your binary had a matching symbol for 
this location, so I would start looking at the toolchain, see if can 
provide that.

>> Side-question, are there some debug symbols in the binary that could
>> describe this location?
> 
> How do I know that?

I would normally use "readelf --debug-dump" to look at the DWARF info, 
but since this is not an ELF, I don't know.

>> > --- gdb/minsyms.c~0	2018-07-04 18:41:59.000000000 +0300
>> > +++ gdb/minsyms.c	2018-12-20 08:06:11.516834500 +0200
>> > @@ -1514,7 +1514,8 @@ minimal_symbol_upper_bound (struct bound
>> >      {
>> >        if ((MSYMBOL_VALUE_RAW_ADDRESS (msymbol + i)
>> >  	   != MSYMBOL_VALUE_RAW_ADDRESS (msymbol))
>> > -	  && MSYMBOL_SECTION (msymbol + i) == section)
>> > +	  && MSYMBOL_SECTION (msymbol + i) == section
>> > +	  && MSYMBOL_TYPE (msymbol + i) != mst_abs)
>> >  	break;
>> >      }
>> 
>> Note that if we implement the solution of rejecting the symbols with
>> section == -1, those mst_abs symbols won't be there anymore.
> 
> Fine by me.  Should we push such a change?

Based on what we saw, I would be for it.  But you'll need to make the 
change and test it for regression, as I don't have the necessary setup 
(and knowledge) to do that on Windows.

>> > I think if we want to avoid showing __register_frame_info, we need
>> > further changes in lookup_minimal_symbol_by_pc_section.  But I don't
>> > see how this will help us, unless we also allow displaying the above
>> > message for functions whose names we don't know, perhaps saying
>> > something like
>> >
>> >   Single stepping until exit from function <unknown>
>> 
>> The problem is not only that we are missing the name, but most
>> importantly that we are missing the bounds of the current function.
>> With what you've implemented here, GDB thinks there is a function that
>> occupies the range [0,401000[ (something like that), so it single 
>> steps
>> until it gets out of that range, but the process exits before.
> 
> Which IMO is just fine for this specific use case.

Yes, but it's by chance.  If the process didn't exit, it wouldn't be 
"Single stepping until exit from function X", it would be "Single 
stepping until god-knows-when". So it might work fine here, but if we 
adopted this behavior generally, it could just be more confusing in 
other cases.

>> So it kind of works for your use case, but it's not right, IMO.  If 
>> the
>> process did not exit as it does here, the behavior would be erratic.
> 
> I don't think it would be erratic, we will just see the same
> 
>     0x00401nnn in __register_frame_info ()
> 
> for several steps.  Is that so bad?

Well, first thing, I think it's wrong that we show that it's in 
__register_frame_info.  If this was an actual resolved .text symbol, it 
wouldn't be so bad, but here it's not even a function in the program, it 
doesn't make sense.

Also, the user wouldn't do several step.  They would do one step and GDB 
would keep single stepping until execution gets out of the stepping 
range [0,401000[.  This is very unpredictable, from the point of view of 
the user.

>> Ok, well I think it shows the problem quite clearly, some symbol is
>> missing for GDB to work properly in that context.  I think that we
>> should improve GDB to handle it better error out clearly (instead of
>> hitting a failed assert), but I don't think it can do much more.
> 
> Can you suggest a patch?  I'm not sure I understand the behavior that
> will be the result.

I could try later, using a mingw64 executable (though I can't run it, 
just read the symbols in GDB).  But I think you are in a better position 
than me to do that, since you are more familiar with the platform.

I would probably be looking into adding some "if" in coff_symtab_read, 
to filter out the unwanted symbols, as discussed previously.  You can 
now use "set debug symtab -create 2" to confirm that symbols like 
__register_frame_info no longer lead to the creation of a minimal 
symbol.

>> I guess that having debug info for the file containing
>> __mingw_CRTStartup would help, if you really needed to step past main?
> 
> I don't need to step past main, it just happens in many cases, when I
> type one "next" too many.  I would like to avoid any errors in that
> case.

As I mentioned earlier, I think it's fine if step fails with "I don't 
have enough info to do my work", and suggest you use continue instead.

Simon

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: GDB internal error in pc_in_thread_step_range
  2018-12-22 16:47                         ` Simon Marchi
@ 2018-12-23  5:35                           ` Joel Brobecker
  2018-12-23 15:23                             ` Eli Zaretskii
  2018-12-23 16:10                           ` Eli Zaretskii
  1 sibling, 1 reply; 25+ messages in thread
From: Joel Brobecker @ 2018-12-23  5:35 UTC (permalink / raw)
  To: Simon Marchi; +Cc: Eli Zaretskii, gdb-patches

> > > Side-question, are there some debug symbols in the binary that could
> > > describe this location?
> > 
> > How do I know that?
> 
> I would normally use "readelf --debug-dump" to look at the DWARF info, but
> since this is not an ELF, I don't know.

Objdump has the same kind of functionality for both DWARF and
the symbol table (--dwarf, -t, -T, etc).

-- 
Joel

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: GDB internal error in pc_in_thread_step_range
  2018-12-23  5:35                           ` Joel Brobecker
@ 2018-12-23 15:23                             ` Eli Zaretskii
  2018-12-23 15:33                               ` Simon Marchi
  0 siblings, 1 reply; 25+ messages in thread
From: Eli Zaretskii @ 2018-12-23 15:23 UTC (permalink / raw)
  To: Joel Brobecker; +Cc: simon.marchi, gdb-patches

> Date: Sun, 23 Dec 2018 09:35:02 +0400
> From: Joel Brobecker <brobecker@adacore.com>
> Cc: Eli Zaretskii <eliz@gnu.org>, gdb-patches@sourceware.org
> 
> > > > Side-question, are there some debug symbols in the binary that could
> > > > describe this location?
> > > 
> > > How do I know that?
> > 
> > I would normally use "readelf --debug-dump" to look at the DWARF info, but
> > since this is not an ELF, I don't know.
> 
> Objdump has the same kind of functionality for both DWARF and
> the symbol table (--dwarf, -t, -T, etc).

Yes.  But in what part of its output would you expect to see debug
symbols that describe this location?

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: GDB internal error in pc_in_thread_step_range
  2018-12-23 15:23                             ` Eli Zaretskii
@ 2018-12-23 15:33                               ` Simon Marchi
  0 siblings, 0 replies; 25+ messages in thread
From: Simon Marchi @ 2018-12-23 15:33 UTC (permalink / raw)
  To: Eli Zaretskii, Joel Brobecker; +Cc: gdb-patches

On 2018-12-23 10:23 a.m., Eli Zaretskii wrote:
>> Date: Sun, 23 Dec 2018 09:35:02 +0400
>> From: Joel Brobecker <brobecker@adacore.com>
>> Cc: Eli Zaretskii <eliz@gnu.org>, gdb-patches@sourceware.org
>>
>>>>> Side-question, are there some debug symbols in the binary that could
>>>>> describe this location?
>>>>
>>>> How do I know that?
>>>
>>> I would normally use "readelf --debug-dump" to look at the DWARF info, but
>>> since this is not an ELF, I don't know.
>>
>> Objdump has the same kind of functionality for both DWARF and
>> the symbol table (--dwarf, -t, -T, etc).
> 
> Yes.  But in what part of its output would you expect to see debug
> symbols that describe this location?
> 

If you use "objdump --dwarf=info <binary>", then you can see some nodes representing
subprograms (functions), like this:

 <1><51>: Abbrev Number: 5 (DW_TAG_subprogram)
    <52>   DW_AT_external    : 1
    <52>   DW_AT_name        : (indirect string, offset: 0x257b): main
    <56>   DW_AT_decl_file   : 1
    <57>   DW_AT_decl_line   : 6
    <58>   DW_AT_decl_column : 5
    <59>   DW_AT_type        : <0x4a>
    <5d>   DW_AT_low_pc      : 0x1119
    <65>   DW_AT_high_pc     : 0xb
    <6d>   DW_AT_frame_base  : 1 byte block: 9c 	(DW_OP_call_frame_cfa)
    <6f>   DW_AT_GNU_all_call_sites: 1


Here, DW_AT_high_pc is actually an offset relative to DW_AT_low_pc. This means
my function main's range is [0x1119,0x1119+0xb[.  So you could search in that
output for "__mingw_CRTStartup", to see if there's a node describing that function.

Honestly, I would be quite surprised if you had DWARF info for it but not a basic
COFF symbol, but it costs nothing to check.

Simon

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: GDB internal error in pc_in_thread_step_range
  2018-12-22 16:47                         ` Simon Marchi
  2018-12-23  5:35                           ` Joel Brobecker
@ 2018-12-23 16:10                           ` Eli Zaretskii
  2018-12-23 23:31                             ` Simon Marchi
  1 sibling, 1 reply; 25+ messages in thread
From: Eli Zaretskii @ 2018-12-23 16:10 UTC (permalink / raw)
  To: Simon Marchi; +Cc: gdb-patches

> Date: Sat, 22 Dec 2018 11:47:07 -0500
> From: Simon Marchi <simon.marchi@polymtl.ca>
> Cc: gdb-patches@sourceware.org
> 
> >> Huh, interesting.  I looked at elfread, and similar undefined symbols
> >> are skipped:
> >> 
> >> https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=blob;f=gdb/elfread.c;h=71e6fcca6ec62ec57f93f06d8a9913612be6f9e2;hb=HEAD#l270
> > 
> > So maybe GDB should skip them as well?
> 
> Yes.  Can you please give it a try it?

Like this?

--- gdb/coffread.c~1	2018-07-04 18:41:59.000000000 +0300
+++ gdb/coffread.c	2018-12-23 10:24:15.758116900 +0200
@@ -874,8 +874,10 @@ coff_symtab_read (minimal_symbol_reader 
 	  int section = cs_to_section (cs, objfile);
 
 	  tmpaddr = cs->c_value;
-	  record_minimal_symbol (reader, cs, tmpaddr, mst_text,
-				 section, objfile);
+	  /* Don't record unresolved symbols.  */
+	  if (!(cs->c_secnum <= 0 && cs->c_value == 0))
+	    record_minimal_symbol (reader, cs, tmpaddr, mst_text,
+				   section, objfile);
 
 	  fcn_line_ptr = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr;
 	  fcn_start_addr = tmpaddr;

> >> Note that if we implement the solution of rejecting the symbols with
> >> section == -1, those mst_abs symbols won't be there anymore.
> > 
> > Fine by me.  Should we push such a change?
> 
> Based on what we saw, I would be for it.  But you'll need to make the 
> change and test it for regression, as I don't have the necessary setup 
> (and knowledge) to do that on Windows.

I'm sorry, I don't have such a setup, either.  Can anyone else run the
regression tests?  If not, how are MinGW related changes tested when
submitted here?

> >> So it kind of works for your use case, but it's not right, IMO.  If 
> >> the
> >> process did not exit as it does here, the behavior would be erratic.
> > 
> > I don't think it would be erratic, we will just see the same
> > 
> >     0x00401nnn in __register_frame_info ()
> > 
> > for several steps.  Is that so bad?
> 
> Well, first thing, I think it's wrong that we show that it's in 
> __register_frame_info.  If this was an actual resolved .text symbol, it 
> wouldn't be so bad, but here it's not even a function in the program, it 
> doesn't make sense.

The change above causes the following behavior, when stepping out of
'main' with "next":

  6         return 0;
  (gdb) n
  7       }
  (gdb)
  0x00401288 in ?? ()
  (gdb) n
  Cannot find bounds of current function
  (gdb) c
  Continuing.
  [Inferior 1 (process 9228) exited normally]
  (gdb) q

If this is fine with you, it's fine with me.

Thanks.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: GDB internal error in pc_in_thread_step_range
  2018-12-23 16:10                           ` Eli Zaretskii
@ 2018-12-23 23:31                             ` Simon Marchi
  2018-12-24 16:14                               ` Eli Zaretskii
  0 siblings, 1 reply; 25+ messages in thread
From: Simon Marchi @ 2018-12-23 23:31 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches

On 2018-12-23 11:10 a.m., Eli Zaretskii wrote:
> Like this?
> 
> --- gdb/coffread.c~1	2018-07-04 18:41:59.000000000 +0300
> +++ gdb/coffread.c	2018-12-23 10:24:15.758116900 +0200
> @@ -874,8 +874,10 @@ coff_symtab_read (minimal_symbol_reader 
>  	  int section = cs_to_section (cs, objfile);
>  
>  	  tmpaddr = cs->c_value;
> -	  record_minimal_symbol (reader, cs, tmpaddr, mst_text,
> -				 section, objfile);
> +	  /* Don't record unresolved symbols.  */
> +	  if (!(cs->c_secnum <= 0 && cs->c_value == 0))
> +	    record_minimal_symbol (reader, cs, tmpaddr, mst_text,
> +				   section, objfile);
>  
>  	  fcn_line_ptr = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr;
>  	  fcn_start_addr = tmpaddr;

That looks good to me.

> I'm sorry, I don't have such a setup, either.  Can anyone else run the
> regression tests?  If not, how are MinGW related changes tested when
> submitted here?

I thought you were the MinGW reference around here :).  I guess the changes should
be validated the same way we do on GNU/Linux, run the testsuite without and with the
patch applied, diff the gdb.sum files to see if there's any regression.  I don't
know what's the state of the testsuite on Windows though...

Running the testsuite is done using "make check".  There are some tips on this page:

https://sourceware.org/gdb/wiki/TestingGDB

> The change above causes the following behavior, when stepping out of
> 'main' with "next":
> 
>   6         return 0;
>   (gdb) n
>   7       }
>   (gdb)
>   0x00401288 in ?? ()
>   (gdb) n
>   Cannot find bounds of current function
>   (gdb) c
>   Continuing.
>   [Inferior 1 (process 9228) exited normally]
>   (gdb) q
> 
> If this is fine with you, it's fine with me.

That seems good to me, given the information GDB works with.

Simon

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: GDB internal error in pc_in_thread_step_range
  2018-12-23 23:31                             ` Simon Marchi
@ 2018-12-24 16:14                               ` Eli Zaretskii
  2018-12-24 16:29                                 ` Simon Marchi
  0 siblings, 1 reply; 25+ messages in thread
From: Eli Zaretskii @ 2018-12-24 16:14 UTC (permalink / raw)
  To: Simon Marchi; +Cc: gdb-patches

> Cc: gdb-patches@sourceware.org
> From: Simon Marchi <simon.marchi@polymtl.ca>
> Date: Sun, 23 Dec 2018 18:31:45 -0500
> 
> On 2018-12-23 11:10 a.m., Eli Zaretskii wrote:
> > Like this?
> > 
> > --- gdb/coffread.c~1	2018-07-04 18:41:59.000000000 +0300
> > +++ gdb/coffread.c	2018-12-23 10:24:15.758116900 +0200
> > @@ -874,8 +874,10 @@ coff_symtab_read (minimal_symbol_reader 
> >  	  int section = cs_to_section (cs, objfile);
> >  
> >  	  tmpaddr = cs->c_value;
> > -	  record_minimal_symbol (reader, cs, tmpaddr, mst_text,
> > -				 section, objfile);
> > +	  /* Don't record unresolved symbols.  */
> > +	  if (!(cs->c_secnum <= 0 && cs->c_value == 0))
> > +	    record_minimal_symbol (reader, cs, tmpaddr, mst_text,
> > +				   section, objfile);
> >  
> >  	  fcn_line_ptr = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr;
> >  	  fcn_start_addr = tmpaddr;
> 
> That looks good to me.

Should I push it to the master branch?

> > I'm sorry, I don't have such a setup, either.  Can anyone else run the
> > regression tests?  If not, how are MinGW related changes tested when
> > submitted here?
> 
> I thought you were the MinGW reference around here :).

I'm happy to help with this, but setting up the GDB test suite needs a
Cygwin installation as well, and I don't have that.

> > The change above causes the following behavior, when stepping out of
> > 'main' with "next":
> > 
> >   6         return 0;
> >   (gdb) n
> >   7       }
> >   (gdb)
> >   0x00401288 in ?? ()
> >   (gdb) n
> >   Cannot find bounds of current function
> >   (gdb) c
> >   Continuing.
> >   [Inferior 1 (process 9228) exited normally]
> >   (gdb) q
> > 
> > If this is fine with you, it's fine with me.
> 
> That seems good to me, given the information GDB works with.

I agree, so I'd like to install this patch.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: GDB internal error in pc_in_thread_step_range
  2018-12-24 16:14                               ` Eli Zaretskii
@ 2018-12-24 16:29                                 ` Simon Marchi
  2018-12-28  7:09                                   ` Eli Zaretskii
  0 siblings, 1 reply; 25+ messages in thread
From: Simon Marchi @ 2018-12-24 16:29 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches

On 2018-12-24 11:13 a.m., Eli Zaretskii wrote:
>> Cc: gdb-patches@sourceware.org
>> From: Simon Marchi <simon.marchi@polymtl.ca>
>> Date: Sun, 23 Dec 2018 18:31:45 -0500
>>
>> On 2018-12-23 11:10 a.m., Eli Zaretskii wrote:
>>> Like this?
>>>
>>> --- gdb/coffread.c~1	2018-07-04 18:41:59.000000000 +0300
>>> +++ gdb/coffread.c	2018-12-23 10:24:15.758116900 +0200
>>> @@ -874,8 +874,10 @@ coff_symtab_read (minimal_symbol_reader 
>>>  	  int section = cs_to_section (cs, objfile);
>>>  
>>>  	  tmpaddr = cs->c_value;
>>> -	  record_minimal_symbol (reader, cs, tmpaddr, mst_text,
>>> -				 section, objfile);
>>> +	  /* Don't record unresolved symbols.  */
>>> +	  if (!(cs->c_secnum <= 0 && cs->c_value == 0))
>>> +	    record_minimal_symbol (reader, cs, tmpaddr, mst_text,
>>> +				   section, objfile);
>>>  
>>>  	  fcn_line_ptr = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr;
>>>  	  fcn_start_addr = tmpaddr;
>>
>> That looks good to me.
> 
> Should I push it to the master branch?

Yes, just make sure to include the relevant info in the commit log.
It would be a good idea to link back to this thread, so someone doing
archeology can find why we added this.

> I'm happy to help with this, but setting up the GDB test suite needs a
> Cygwin installation as well, and I don't have that.

Ok I see.

Simon

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: GDB internal error in pc_in_thread_step_range
  2018-12-24 16:29                                 ` Simon Marchi
@ 2018-12-28  7:09                                   ` Eli Zaretskii
  2018-12-28 10:09                                     ` Joel Brobecker
  0 siblings, 1 reply; 25+ messages in thread
From: Eli Zaretskii @ 2018-12-28  7:09 UTC (permalink / raw)
  To: Simon Marchi; +Cc: gdb-patches

> Cc: gdb-patches@sourceware.org
> From: Simon Marchi <simon.marchi@polymtl.ca>
> Date: Mon, 24 Dec 2018 11:29:36 -0500
> 
> >>> --- gdb/coffread.c~1	2018-07-04 18:41:59.000000000 +0300
> >>> +++ gdb/coffread.c	2018-12-23 10:24:15.758116900 +0200
> >>> @@ -874,8 +874,10 @@ coff_symtab_read (minimal_symbol_reader 
> >>>  	  int section = cs_to_section (cs, objfile);
> >>>  
> >>>  	  tmpaddr = cs->c_value;
> >>> -	  record_minimal_symbol (reader, cs, tmpaddr, mst_text,
> >>> -				 section, objfile);
> >>> +	  /* Don't record unresolved symbols.  */
> >>> +	  if (!(cs->c_secnum <= 0 && cs->c_value == 0))
> >>> +	    record_minimal_symbol (reader, cs, tmpaddr, mst_text,
> >>> +				   section, objfile);
> >>>  
> >>>  	  fcn_line_ptr = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr;
> >>>  	  fcn_start_addr = tmpaddr;
> >>
> >> That looks good to me.
> > 
> > Should I push it to the master branch?
> 
> Yes, just make sure to include the relevant info in the commit log.
> It would be a good idea to link back to this thread, so someone doing
> archeology can find why we added this.

Done.

Thanks for your help with investigating this issue and with finding
the right solution for it.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: GDB internal error in pc_in_thread_step_range
  2018-12-28  7:09                                   ` Eli Zaretskii
@ 2018-12-28 10:09                                     ` Joel Brobecker
  2018-12-28 10:15                                       ` Eli Zaretskii
  0 siblings, 1 reply; 25+ messages in thread
From: Joel Brobecker @ 2018-12-28 10:09 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Simon Marchi, gdb-patches

> > >>> --- gdb/coffread.c~1	2018-07-04 18:41:59.000000000 +0300
> > >>> +++ gdb/coffread.c	2018-12-23 10:24:15.758116900 +0200
> > >>> @@ -874,8 +874,10 @@ coff_symtab_read (minimal_symbol_reader 
> > >>>  	  int section = cs_to_section (cs, objfile);
> > >>>  
> > >>>  	  tmpaddr = cs->c_value;
> > >>> -	  record_minimal_symbol (reader, cs, tmpaddr, mst_text,
> > >>> -				 section, objfile);
> > >>> +	  /* Don't record unresolved symbols.  */
> > >>> +	  if (!(cs->c_secnum <= 0 && cs->c_value == 0))
> > >>> +	    record_minimal_symbol (reader, cs, tmpaddr, mst_text,
> > >>> +				   section, objfile);
> > >>>  
> > >>>  	  fcn_line_ptr = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr;
> > >>>  	  fcn_start_addr = tmpaddr;
> > >>
> > >> That looks good to me.
> > > 
> > > Should I push it to the master branch?
> > 
> > Yes, just make sure to include the relevant info in the commit log.
> > It would be a good idea to link back to this thread, so someone doing
> > archeology can find why we added this.
> 
> Done.
> 
> Thanks for your help with investigating this issue and with finding
> the right solution for it.

FWIW, I ran this patch through AdaCore's testsuite, on both
x86 and x86_64 Windows, and detected do regressions.

-- 
Joel

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: GDB internal error in pc_in_thread_step_range
  2018-12-28 10:09                                     ` Joel Brobecker
@ 2018-12-28 10:15                                       ` Eli Zaretskii
  0 siblings, 0 replies; 25+ messages in thread
From: Eli Zaretskii @ 2018-12-28 10:15 UTC (permalink / raw)
  To: Joel Brobecker; +Cc: simon.marchi, gdb-patches

> Date: Fri, 28 Dec 2018 14:09:48 +0400
> From: Joel Brobecker <brobecker@adacore.com>
> Cc: Simon Marchi <simon.marchi@polymtl.ca>, gdb-patches@sourceware.org
> 
> FWIW, I ran this patch through AdaCore's testsuite, on both
> x86 and x86_64 Windows, and detected do regressions.

Thank you.

^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2018-12-28 10:15 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <83h8kjr8r6.fsf@gnu.org>
     [not found] ` <100001f1b27aa7d90902a75d5db37710@polymtl.ca>
2018-11-18 16:37   ` GDB internal error in pc_in_thread_step_range Eli Zaretskii
2018-11-30 13:42     ` Eli Zaretskii
2018-12-07  7:22       ` Eli Zaretskii
2018-12-15 12:07         ` Eli Zaretskii
2018-12-16  3:58     ` Simon Marchi
2018-12-16 15:40       ` Eli Zaretskii
2018-12-16 17:06         ` Simon Marchi
2018-12-16 17:22           ` Eli Zaretskii
2018-12-16 18:06             ` Simon Marchi
2018-12-19 15:50               ` Eli Zaretskii
2018-12-20  0:16                 ` Simon Marchi
2018-12-20 15:45                   ` Eli Zaretskii
2018-12-20 23:03                     ` Simon Marchi
2018-12-22  8:44                       ` Eli Zaretskii
2018-12-22 16:47                         ` Simon Marchi
2018-12-23  5:35                           ` Joel Brobecker
2018-12-23 15:23                             ` Eli Zaretskii
2018-12-23 15:33                               ` Simon Marchi
2018-12-23 16:10                           ` Eli Zaretskii
2018-12-23 23:31                             ` Simon Marchi
2018-12-24 16:14                               ` Eli Zaretskii
2018-12-24 16:29                                 ` Simon Marchi
2018-12-28  7:09                                   ` Eli Zaretskii
2018-12-28 10:09                                     ` Joel Brobecker
2018-12-28 10:15                                       ` Eli Zaretskii

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).