GDB internal error in pc_in_thread_step_range

Simon Marchi simon.marchi@polymtl.ca
Sun Dec 16 17:06:00 GMT 2018


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



More information about the Gdb-patches mailing list