From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 23361 invoked by alias); 16 Dec 2018 18:06:39 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 23343 invoked by uid 89); 16 Dec 2018 18:06:37 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-10.4 required=5.0 tests=BAYES_00,GIT_PATCH_2,GIT_PATCH_3,KAM_STOCKGEN,SPF_HELO_PASS,SPF_PASS autolearn=ham version=3.3.2 spammy=correspond, closest X-HELO: smtp.polymtl.ca Received: from smtp.polymtl.ca (HELO smtp.polymtl.ca) (132.207.4.11) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 16 Dec 2018 18:06:35 +0000 Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id wBGI6R1l019778 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Sun, 16 Dec 2018 13:06:32 -0500 Received: from [10.0.0.11] (unknown [192.222.164.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id 68FEC1E4C2; Sun, 16 Dec 2018 13:06:27 -0500 (EST) Subject: Re: GDB internal error in pc_in_thread_step_range To: Eli Zaretskii Cc: gdb-patches@sourceware.org References: <83h8kjr8r6.fsf@gnu.org> <100001f1b27aa7d90902a75d5db37710@polymtl.ca> <83a7m6tk92.fsf@gnu.org> <8336qxfpjo.fsf@gnu.org> <83tvjde68l.fsf@gnu.org> From: Simon Marchi Message-ID: Date: Sun, 16 Dec 2018 18:06:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.3.3 MIME-Version: 1.0 In-Reply-To: <83tvjde68l.fsf@gnu.org> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-IsSubscribed: yes X-SW-Source: 2018-12/txt/msg00190.txt.bz2 On 2018-12-16 12:22 p.m., Eli Zaretskii wrote: >> Cc: gdb-patches@sourceware.org >> From: Simon Marchi >> 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