From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.223.130]) by sourceware.org (Postfix) with ESMTPS id 2771C3858D39 for ; Wed, 17 Apr 2024 08:28:53 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 2771C3858D39 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=suse.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=suse.de ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 2771C3858D39 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=195.135.223.130 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1713342537; cv=none; b=mpywUQEY4hoWRXxdEkA0YTthqSyRSvQpWDdD5PnhzNw3laclzRRLqwYvR5rAey4F3RgFZ2eu1G3LIvQDjpKppjq5xHNBV3QHy/FXEdb/rUGAaOxUgAy5YGPwnu0gyP7pNBJVfmMEDsqfev5wdpG/oTLI/eTH9b5IsZKawNydPj8= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1713342537; c=relaxed/simple; bh=gpGHcfw6dZUmxPuofWjWfdSt3j/4e2FeXE2z8716pD0=; h=DKIM-Signature:DKIM-Signature:DKIM-Signature:DKIM-Signature: Message-ID:Date:MIME-Version:Subject:To:From; b=Jvu5BwLUmfl6oztsu5Ix96Ga0C+fpjWP6yCCYi8m0i5rjhZulE9i3TEYQYVzglSLJUlbnvxNTh896t0jz4IW9gqkFrVyd2VtsR6BhIv5s6p6PKTrzpIX8MYB2/Lw2Du2CHODnqwG9gwVD6m1mjdopRbuWzSUaPlSrtJx4RwyFWg= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from imap1.dmz-prg2.suse.org (imap1.dmz-prg2.suse.org [10.150.64.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 14842339E2; Wed, 17 Apr 2024 08:28:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1713342532; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=3EkuM/NfUZytsNCyKmt/8KH50HaCqWqLU3A8eGmbtSU=; b=pUAFbhcC6SR4fsVDbkknluArqqjlgFtog81LNXSl98N5UUBH3kpzj7y7D6XEX5aihgk3wM 8LuD9Djk7e7iQdF4CFUBYRTBImJL5oadzfPjLYtThMO5GjjIvxt83qAD/JAj7wExaJ6XrO 91O41xsHDmHm6vkgKYpZGPd9DepASfc= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1713342532; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=3EkuM/NfUZytsNCyKmt/8KH50HaCqWqLU3A8eGmbtSU=; b=urZWSLAS3sTNNU8oXQPcduMI2Tdi6S7UcxBYKESLr/VowoI35Vr4zKkALT1fVQVfHeQ4qr zV1pacdutc5sLoBg== Authentication-Results: smtp-out1.suse.de; none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1713342531; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=3EkuM/NfUZytsNCyKmt/8KH50HaCqWqLU3A8eGmbtSU=; b=a+K7M12/O6f3B/xXbvnGRERLugi20YIpIrsk+Ogz8UDLvks+GA6Ju3gbO46G6eHHjWBdg1 TldkQ1K4U857EjcFn907UyNyPTa4n9fdA41py5EWclfkDd8piTnykKKEmFnKsS25hkGGEd 278MVF8v73+rE3Juw+Oh7ZpAx4H8aRA= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1713342531; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=3EkuM/NfUZytsNCyKmt/8KH50HaCqWqLU3A8eGmbtSU=; b=sWd6FHdqvvjKJH3OmYD1ktoEQ96ERHuyaG96XFUWrNAGAbGJte8NldWDD20GwNeF5BSkdK eOINZGw+/i3xypBA== Received: from imap1.dmz-prg2.suse.org (localhost [127.0.0.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by imap1.dmz-prg2.suse.org (Postfix) with ESMTPS id EA5391384C; Wed, 17 Apr 2024 08:28:50 +0000 (UTC) Received: from dovecot-director2.suse.de ([2a07:de40:b281:106:10:150:64:167]) by imap1.dmz-prg2.suse.org with ESMTPSA id K6zJN0KIH2akQQAAD6G6ig (envelope-from ); Wed, 17 Apr 2024 08:28:50 +0000 Message-ID: <5dda7d2f-82c9-4154-86fa-8bedeb962f0e@suse.de> Date: Wed, 17 Apr 2024 10:29:08 +0200 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH] [gdb/python] Throw MemoryError in inferior.read_memory if malloc fails To: Simon Marchi , Tom Tromey Cc: gdb-patches@sourceware.org References: <20240411105257.15421-1-tdevries@suse.de> <875xwn51dq.fsf@tromey.com> <40c3c863-1369-4f4f-bef4-f2d35357c8eb@simark.ca> Content-Language: en-US From: Tom de Vries In-Reply-To: <40c3c863-1369-4f4f-bef4-f2d35357c8eb@simark.ca> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Level: X-Spamd-Result: default: False [-4.29 / 50.00]; BAYES_HAM(-3.00)[100.00%]; NEURAL_HAM_LONG(-1.00)[-1.000]; NEURAL_HAM_SHORT(-0.20)[-0.995]; MIME_GOOD(-0.10)[text/plain]; XM_UA_NO_VERSION(0.01)[]; RCVD_VIA_SMTP_AUTH(0.00)[]; MIME_TRACE(0.00)[0:+]; TO_DN_SOME(0.00)[]; MID_RHS_MATCH_FROM(0.00)[]; ARC_NA(0.00)[]; RCVD_TLS_ALL(0.00)[]; DKIM_SIGNED(0.00)[suse.de:s=susede2_rsa,suse.de:s=susede2_ed25519]; FUZZY_BLOCKED(0.00)[rspamd.com]; FROM_HAS_DN(0.00)[]; RCPT_COUNT_THREE(0.00)[3]; FROM_EQ_ENVFROM(0.00)[]; TO_MATCH_ENVRCPT_ALL(0.00)[]; RCVD_COUNT_TWO(0.00)[2]; DBL_BLOCKED_OPENRESOLVER(0.00)[gnu.org:url,python.org:url,suse.de:email,sourceware.org:url] X-Spam-Score: -4.29 X-Spam-Status: No, score=-12.3 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_SHORT,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On 4/16/24 21:10, Simon Marchi wrote: > On 4/12/24 3:09 AM, Tom de Vries wrote: >> On 4/11/24 18:07, Tom Tromey wrote: >>>>>>>> "Tom" == Tom de Vries writes: >>> >>> Tom> PR python/31631 reports a gdb internal error when doing: >>> Tom> ... >>> Tom> (gdb) python gdb.selected_inferior().read_memory (0, 0xffffffffffffffff) >>> Tom> utils.c:709: internal-error: virtual memory exhausted. >>> Tom> A problem internal to GDB has been detected, >>> Tom> further debugging may prove unreliable. >>> Tom> ... >>> >>> Tom> Fix this by throwing a python MemoryError, such that we have instead: >>> Tom> ... >>> Tom> (gdb) python gdb.selected_inferior().read_memory (0, 0xffffffffffffffff) >>> Tom> Python Exception : >>> Tom> Error occurred in Python. >>> Tom> (gdb) >>> Tom> ... >>> >>> I tend to think you will regret opening this door, because I imagine >>> there are a large number of ways to crash gdb by passing nonsensical >>> values to Python APIs. >>> >> >> Hm, ok then let's hope I don't regret it. >> >>> Tom> @request("readMemory") >>> Tom> @capability("supportsReadMemoryRequest") >>> Tom> def read_memory(*, memoryReference: str, offset: int = 0, count: int, **extra): >>> Tom> addr = int(memoryReference, 0) + offset >>> Tom> - buf = gdb.selected_inferior().read_memory(addr, count) >>> Tom> + oom = False >>> Tom> + try: >>> Tom> + buf = gdb.selected_inferior().read_memory(addr, count) >>> Tom> + except MemoryError: >>> Tom> + oom = True >>> Tom> + if oom: >>> Tom> + raise DAPException("Out of memory") >>> >>> This should probably chain the memory error in the except block and >>> re-throw. See https://peps.python.org/pep-3134/ >>> >> >> Ack, that's what I had initially, but I ran into an error that I can no longer reproduce ... so, I'm not sure what happened there. Anyway, fixed. >> >>> However I don't really understand why this is needed. Isn't the >>> exception already propagated back to the server thread? >>> >> >> Without it I run into: >> ... >> FAIL: gdb.dap/memory.exp: exceptions in log file >> ... >> because in the dap log we have: >> ... >> READ: <<<{"seq": 7, "type": "request", "command": "readMemory", "arguments": {"memoryReference": "0x402010", "count": 18446744073709551615}}>>> >> Traceback (most recent call last): >> File "/data/vries/gdb/leap-15-5/build/gdb/data-directory/python/gdb/dap/server.py", line 157, in _handle_command >> body = _commands[params["command"]](**args) >> File "/data/vries/gdb/leap-15-5/build/gdb/data-directory/python/gdb/dap/server.py", line 300, in check >> return func(*args, **kwargs) >> File "/data/vries/gdb/leap-15-5/build/gdb/data-directory/python/gdb/dap/server.py", line 360, in sync_call >> return send_gdb_with_response(lambda: func(**args)) >> File "/data/vries/gdb/leap-15-5/build/gdb/data-directory/python/gdb/dap/server.py", line 514, in send_gdb_with_response >> raise val >> File "/data/vries/gdb/leap-15-5/build/gdb/data-directory/python/gdb/dap/server.py", line 470, in __call__ >> val = self.fn() >> File "/data/vries/gdb/leap-15-5/build/gdb/data-directory/python/gdb/dap/server.py", line 360, in >> return send_gdb_with_response(lambda: func(**args)) >> File "/data/vries/gdb/leap-15-5/build/gdb/data-directory/python/gdb/dap/startup.py", line 113, in ensure_gdb_thread >> return func(*args, **kwargs) >> File "/data/vries/gdb/leap-15-5/build/gdb/data-directory/python/gdb/dap/memory.py", line 28, in read_memory >> buf = gdb.selected_inferior().read_memory(addr, count) >> MemoryError >> WROTE: <<<{"request_seq": 7, "type": "response", "command": "readMemory", "success": false, "message": ""}>>> >> ... >> >> So that needs fixing here: >> ... >> diff --git a/gdb/python/lib/gdb/dap/server.py b/gdb/python/lib/gdb/dap/server.py >> index 7eb87177710..8408232eceb 100644 >> --- a/gdb/python/lib/gdb/dap/server.py >> +++ b/gdb/python/lib/gdb/dap/server.py >> @@ -173,6 +173,9 @@ class Server: >> log_stack(LogLevel.FULL) >> result["success"] = False >> result["message"] = str(e) >> + except MemoryError as e: >> + result["success"] = False >> + result["message"] = str(e) >> except BaseException as e: >> ... >> >> But I couldn't come up with a good rationale as to why I should handle MemoryError differently from BaseException, so I decided to catch it locally and turn it into a DAPException. >> >>> Tom> + /* We used to use xmalloc, which does this trick to avoid malloc >>> Tom> + returning a nullptr for a valid reason. Keep doing the same. */ >>> Tom> + if (length == 0) >>> Tom> + length = 1; >>> >>> This is most likely a workaround for vendor implementations of malloc >>> that return NULL for malloc(0). See >>> https://www.gnu.org/software/gnulib/manual/html_node/malloc.html >>> >>> However, here this is not necessary, because a 0-length memory read is >>> meaningless, and so this case can simply be reported as an error. >> >> I went for backward compatibility here, but ok, fixed. Updated version attached. >> >> Thanks, >> - Tom > > In an Asan-enabled build, I get: > > > 74 (gdb) python gdb.selected_inferior().read_memory (0, 0xffffffffffffffff)^M > 75 =================================================================^M > 76 ^[[1m^[[31m==791047==ERROR: AddressSanitizer: requested allocation size 0xffffffffffffffff (0x800 after adjustments for alignment, red zones etc.) exceeds maximum supported size of 0x100 00000000 (thread T0)^M > 77 ^[[1m^[[0m #0 0x7f02c58d49cf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69^M > 78 #1 0x55cc5937f257 in infpy_read_memory /home/smarchi/src/binutils-gdb/gdb/python/py-inferior.c:565^M > 79 #2 0x7f02c4ea9709 in method_vectorcall_VARARGS_KEYWORDS ../Objects/descrobject.c:364^M > 80 ^M > 81 ==791047==HINT: if you don't care about these errors you may set allocator_may_return_null=1^M > 82 SUMMARY: AddressSanitizer: allocation-size-too-big ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69 in __interceptor_malloc^M > Hi Simon, thanks for the report. I've submitted a fix here ( https://sourceware.org/pipermail/gdb-patches/2024-April/208178.html ). Thanks, - Tom