From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: rehan malak Newsgroups: gmane.emacs.bugs Subject: bug#74738: 31.0.50; Freezes in Python-mode on some Python file when searching or scrolling Date: Mon, 9 Dec 2024 15:58:22 +0100 Message-ID: References: <868qsqf54x.fsf@gnu.org> Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="000000000000fe8bf80628d79205" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="6897"; mail-complaints-to="usenet@ciao.gmane.io" Cc: kobarity , Stefan Monnier , 74738@debbugs.gnu.org To: Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Mon Dec 09 16:25:33 2024 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1tKfdd-0001g4-0k for geb-bug-gnu-emacs@m.gmane-mx.org; Mon, 09 Dec 2024 16:25:33 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tKfdI-0002ku-2p; Mon, 09 Dec 2024 10:25:12 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tKfd8-0002ZH-UF for bug-gnu-emacs@gnu.org; Mon, 09 Dec 2024 10:25:03 -0500 Original-Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tKfd8-0004SP-K2 for bug-gnu-emacs@gnu.org; Mon, 09 Dec 2024 10:25:02 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debbugs.gnu.org; s=debbugs-gnu-org; h=Date:From:In-Reply-To:References:MIME-Version:To:Subject; bh=BEGISY+VV9WnBfaD4/OfHpmYZ2N2zlZLeMVeFIfqZ6E=; b=ITo9rPCtouIqCUmmu2u49JXusdT8F64JA9pJxVzM7n4yUbTCNcwtdc9K5BiWmY+PWWMF7br3pQWaloyEf4ry6QwbgYrGeUN+HgQsiqUfJmOynUgJmOrHTMmxok+SWU/IVHxzI1hL7PU+zfidtYKtIznD/BfgLyeHsLhg5hWYNNuPX2Gap0jcCL3a1sYKIaVH5gRNuwgUCdVpCZ0JWtpTkB3hQP2M3WM9SrFWqlkpGhsCfDXBrhtjyqnJQQgtQj0xk3ufr8CRdxcfE5M2hQkUov3+tcx4RaIqSg2MoY5arcOLi3dofMAq0q6spJN40YJOHpXC8mBIktk4OesSwhrmmA==; Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1tKfd8-0002dv-Do for bug-gnu-emacs@gnu.org; Mon, 09 Dec 2024 10:25:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: rehan malak Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 09 Dec 2024 15:25:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 74738 X-GNU-PR-Package: emacs Original-Received: via spool by 74738-submit@debbugs.gnu.org id=B74738.173375787310108 (code B ref 74738); Mon, 09 Dec 2024 15:25:02 +0000 Original-Received: (at 74738) by debbugs.gnu.org; 9 Dec 2024 15:24:33 +0000 Original-Received: from localhost ([127.0.0.1]:55187 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tKfcd-0002cu-H3 for submit@debbugs.gnu.org; Mon, 09 Dec 2024 10:24:33 -0500 Original-Received: from mail-vs1-f46.google.com ([209.85.217.46]:50252) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tKfCo-00017j-B5 for 74738@debbugs.gnu.org; Mon, 09 Dec 2024 09:57:56 -0500 Original-Received: by mail-vs1-f46.google.com with SMTP id ada2fe7eead31-4afe1009960so620213137.0 for <74738@debbugs.gnu.org>; Mon, 09 Dec 2024 06:57:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1733756209; x=1734361009; darn=debbugs.gnu.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=BEGISY+VV9WnBfaD4/OfHpmYZ2N2zlZLeMVeFIfqZ6E=; b=GcrbLlT/am0N6HG41tCtrGzOWViITRy7+n5Ihe7zPoN8FQ35qrAXGuh1FI5wCG4N4i 9LDNRtttmjzQVOKJhxcGCWlTrqdT9cEthrzoImoVpaSQizrOvHJFcc6qdmqRSudub0wS iKngl2oz0cyeLtDsjVSTm9mQH6MHO/ADBwoGMm/gVA3Vfb5Rg0gLnZRkyNZR+YoQ050f hD3+RdadD93IMMhd/pJhaMYWNty0CJ+UO6O648yXc7yW2Ua4ZXBCtpuJa56dgXYb/MsY 1newzxLT37hfP1CwqQ/uN0H8gaIxj2xw/LJHtIef+84rtdQ7x7CJ+hZYpnVUOIgu229C i6jQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1733756209; x=1734361009; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=BEGISY+VV9WnBfaD4/OfHpmYZ2N2zlZLeMVeFIfqZ6E=; b=OCJym1TPq8VzRgvZfJDyEpZST0zfGkSqLXsIm9BU/rnLIaNA0Tf/iLeciElsrVwgYx jerJYtyKV1sMpjtU1Zr5o+hKnSlh2kIHjZZJmr/nu2a1pjHf4lP1FBg4HJslLHzd4bfW C8Hy67Zpjb7u4xYc4UDHUFcJ9XNaFsYQCPA78IsCej7eTiWWySdRllO3S9/e8YXNUAZ6 /Q0GW90oxcQsGpE6SJupR8si3ff9otDd2rJ5jdTzw9ARNfrFkDcD1AeEmIrRueudHAWC TWij2NyGLnaWcKRF3B70HKcPgx+/uVlZnYREbyNErs5La/PAHs2yEfHKrWZcB064HcKb Ap/A== X-Forwarded-Encrypted: i=1; AJvYcCVAd/Uu7La7A5xPxUkimreKbYSF/S+U/VzSZFVp/8Ksi61+FbkHXwaN1ya8VhbwZVanYjhjdA==@debbugs.gnu.org X-Gm-Message-State: AOJu0Yx/ddU9LGeMVtBKqAuJ79C7CYcWzr2hgQag1mxxAR5T4Q9z8QzE ypQnDYz5abmtZWrfw+qBZ4eVjcTC7FRamMIjhkXW+/PtVJcv7NQ2o2SuY7x6X0nXrwlharOsHxr ogyMKRMmzTSJ0gKzPBwWNBryRcWI= X-Gm-Gg: ASbGncsKh/nZrhad6/0YOxPsDHAmA1akgSx0m8VEqWoI5OoFCnTbyWN4jdoYReZ0eUL 2GikbSvoAgiod20aKMqy8PQJiRIixBAVU X-Google-Smtp-Source: AGHT+IGZ9BSOEeR1hawEJx14XhLUnEflc5hh7q973quEQKYHZ34JCsLkaZ4/boMf4P19C0B2/3IMvSXUcO5MQM2ghAo= X-Received: by 2002:a05:6102:b14:b0:4af:3f89:44d8 with SMTP id ada2fe7eead31-4b116104d25mr943980137.8.1733756209496; Mon, 09 Dec 2024 06:56:49 -0800 (PST) In-Reply-To: <868qsqf54x.fsf@gnu.org> X-Mailman-Approved-At: Mon, 09 Dec 2024 10:24:29 -0500 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:296699 Archived-At: --000000000000fe8bf80628d79205 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi, Deleting all the "#" in the f-string of the gef.py file removes the problem on my side. sed -i -e 's/#0{align/0{align/g' gef.py sed -i -e 's/#0{width/0{width/g' gef.py sed -i -e 's/#07x}/07x}/g' gef.py sed -i -e 's/#06x}/06x}/g' gef.py sed -i -e 's/#04x}/04x}/g' gef.py sed -i -e 's/#4x}/4x}/g' gef.py sed -i -e 's/#8x}/8x}/g' gef.py sed -i -e 's/#10x}/10x}/g' gef.py sed -i -e 's/#x}/x}/g' gef.py Your smaller example Eli also contains a f-string with the "#". This python f-string format specifier is described here: https://docs.python.org/3/library/string.html#format-specification-mini-lan= guage Is this format specifier supported from the beginning ? For example : value =3D 0xab print(f"{value:x} is a value") =3D> color syntax : *is a value* has the color defined by font-lock-string-face while value =3D 0xab print(f"{value:#x} is a value") =3D> color are messed up... *is* has color defined by font-lock-keyword-fac= e and *a value* has color defined by default face Best, Rehan On Sun, Dec 8, 2024 at 6:37=E2=80=AFPM Eli Zaretskii wrote: > > From: rehan malak > > Date: Sun, 8 Dec 2024 14:05:36 +0100 > > > > I can reproduce systematically this freeze dealing with a 10000lines > > Python file : > > > > wget https://raw.githubusercontent.com/hugsy/gef/refs/heads/main/gef.py > > emacs -Q gef.py > > A much smaller reproducer is attached below. Just visiting it freezes > Emacs. But if I change the line marked below: > > @classmethod > def is_valid(cls, _: pathlib.Path) -> bool: > raise NotImplementedError > > def __str__(self) -> str: > >>>>> return f"{self.name}('{self.path.absolute()}', entry @ > {self.entry_point:#x})" > > to say this instead: > > return self.name > > the problem goes away. So it is something in that complex expression > that trips syntax-ppss. > > Stefan and kobarity, any suggestions or ideas? > > > PageDown several times or scrolling with the mouse > > > > Emacs freezes, Ctrl-g not working, CPU 100% > > > > It works also by searching : Ctrl-s show RET > > then Ctrl-s several times > > > > With a minimal .emacs : > > > > (set debug-on-error t) > > (set debug-on-quit t) > > > > and before scrolling > > > > M-x profiler-start RET > > > > then in an external terminal > > > > pkill -SIGUSR2 emacs > > > > I get the backtrace : > > > > Debugger entered--entering a function: > > * #f(compiled-function () #)() > > syntax-ppss() > > python-syntax-context-type() > > python-nav-forward-block(-1) > > python-nav-backward-block() > > python-nav-beginning-of-block() > > python-nav-end-of-block() > > python-info-statement-ends-block-p() > > python-info-end-of-block-p() > > python-nav--forward-sexp(1 nil nil) > > python-nav-forward-sexp(1) > > forward-sexp(1) > > up-list(1) > > python--font-lock-f-strings(30419) > > font-lock-fontify-keywords-region(28914 30419 nil) > > font-lock-default-fontify-region(28914 30414 nil) > > font-lock-fontify-region(28914 30414) > > #f(compiled-function (fun) # -0x8a96d65e1315e71>)(font-lock-fontify-region) > > run-hook-wrapped(#f(compiled-function (fun) # -0x8a96d65e1315e71>) font-lock-fontify-region) > > jit-lock--run-functions(28914 30414) > > jit-lock-fontify-now(28914 30414) > > jit-lock-function(28914) > > I see something different, in GDB: > > Lisp Backtrace: > "parse-partial-sexp" (0x9f1a788) > "syntax-ppss" (0x9f1a710) > "python-info-line-ends-backslash-p" (0x9f1a6b8) > "python-nav-end-of-statement" (0x9f1a670) > "python-nav-end-of-block" (0x9f1a630) > "python-info-statement-ends-block-p" (0x9f1a610) > "python-info-end-of-block-p" (0x9f1a5c0) > "python-nav--forward-sexp" (0x9f1a548) > "python-nav-forward-sexp" (0x9f1a4f8) > "forward-sexp" (0x9f1a4a8) > "up-list" (0x9f1a438) > "python--font-lock-f-strings" (0x9f1a3a0) > "font-lock-fontify-keywords-region" (0x9f1a308) > "font-lock-default-fontify-region" (0x9f1a2a0) > "font-lock-fontify-region" (0x9f1a230) > 0xb9117d0 PVEC_CLOSURE > "run-hook-wrapped" (0x9f1a1c0) > "jit-lock--run-functions" (0x9f1a0e8) > "jit-lock-fontify-now" (0x9f1a058) > "jit-lock-function" (0x5ffba98) > "redisplay_internal (C function)" (0x0) > > Here's the file with which I can reproduce the problem? > > > class FileFormat: > name: str > path: pathlib.Path > entry_point: int > checksec: dict[str, bool] > sections: list[FileFormatSection] > > def __init__(self, path: str | pathlib.Path) -> None: > raise NotImplementedError > > def __init_subclass__(cls: Type["FileFormat"], **kwargs): > global __registered_file_formats__ > super().__init_subclass__(**kwargs) > required_attributes =3D ("name", "entry_point", "is_valid", > "checksec",) > for attr in required_attributes: > if not hasattr(cls, attr): > raise NotImplementedError(f"File format '{cls.__name__}' > is invalid: missing attribute '{attr}'") > __registered_file_formats__.add(cls) > return > > @classmethod > def is_valid(cls, _: pathlib.Path) -> bool: > raise NotImplementedError > > def __str__(self) -> str: > return f"{self.name}('{self.path.absolute()}', entry @ > {self.entry_point:#x})" > > > class Elf(FileFormat): > """Basic ELF parsing. > Ref: > - http://www.skyfree.org/linux/references/ELF_Format.pdf > - https://refspecs.linuxfoundation.org/elf/elfspec_ppc.pdf > - https://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi.html > """ > class Class(enum.Enum): > ELF_32_BITS =3D 0x01 > ELF_64_BITS =3D 0x02 > > ELF_MAGIC =3D 0x7f454c46 > > class Abi(enum.Enum): > X86_64 =3D 0x3e > X86_32 =3D 0x03 > ARM =3D 0x28 > MIPS =3D 0x08 > POWERPC =3D 0x14 > POWERPC64 =3D 0x15 > SPARC =3D 0x02 > SPARC64 =3D 0x2b > AARCH64 =3D 0xb7 > RISCV =3D 0xf3 > IA64 =3D 0x32 > M68K =3D 0x04 > > class Type(enum.Enum): > ET_RELOC =3D 1 > ET_EXEC =3D 2 > ET_DYN =3D 3 > ET_CORE =3D 4 > > class OsAbi(enum.Enum): > SYSTEMV =3D 0x00 > HPUX =3D 0x01 > NETBSD =3D 0x02 > LINUX =3D 0x03 > SOLARIS =3D 0x06 > AIX =3D 0x07 > IRIX =3D 0x08 > FREEBSD =3D 0x09 > OPENBSD =3D 0x0C > > e_magic: int =3D ELF_MAGIC > e_class: "Elf.Class" =3D Class.ELF_32_BITS > e_endianness: Endianness =3D Endianness.LITTLE_ENDIAN > e_eiversion: int > e_osabi: "Elf.OsAbi" > e_abiversion: int > e_pad: bytes > e_type: "Elf.Type" =3D Type.ET_EXEC > e_machine: Abi =3D Abi.X86_32 > e_version: int > e_entry: int > e_phoff: int > e_shoff: int > e_flags: int > e_ehsize: int > e_phentsize: int > e_phnum: int > e_shentsize: int > e_shnum: int > e_shstrndx: int > > path: pathlib.Path > phdrs : list["Phdr"] > shdrs : list["Shdr"] > name: str =3D "ELF" > > __checksec : dict[str, bool] > > def __init__(self, path: str | pathlib.Path) -> None: > """Instantiate an ELF object. A valid ELF must be provided, or an > exception will be thrown.""" > > if isinstance(path, str): > self.path =3D pathlib.Path(path).expanduser() > elif isinstance(path, pathlib.Path): > self.path =3D path > else: > raise TypeError > > if not self.path.exists(): > raise FileNotFoundError(f"'{self.path}' not found/readable, > most gef features will not work") > > self.__checksec =3D {} > > with self.path.open("rb") as self.fd: > # off 0x0 > self.e_magic, e_class, e_endianness, self.e_eiversion =3D > self.read_and_unpack(">IBBB") > if self.e_magic !=3D Elf.ELF_MAGIC: > # The ELF is corrupted, GDB won't handle it, no point > going further > raise RuntimeError("Not a valid ELF file (magic)") > > self.e_class, self.e_endianness =3D Elf.Class(e_class), > Endianness(e_endianness) > > if self.e_endianness !=3D gef.arch.endianness: > warn("Unexpected endianness for architecture") > > endian =3D self.e_endianness > > # off 0x7 > e_osabi, self.e_abiversion =3D > self.read_and_unpack(f"{endian}BB") > self.e_osabi =3D Elf.OsAbi(e_osabi) > > # off 0x9 > self.e_pad =3D self.read(7) > > # off 0x10 > e_type, e_machine, self.e_version =3D > self.read_and_unpack(f"{endian}HHI") > self.e_type, self.e_machine =3D Elf.Type(e_type), > Elf.Abi(e_machine) > > # off 0x18 > if self.e_class =3D=3D Elf.Class.ELF_64_BITS: > self.e_entry, self.e_phoff, self.e_shoff =3D > self.read_and_unpack(f"{endian}QQQ") > else: > self.e_entry, self.e_phoff, self.e_shoff =3D > self.read_and_unpack(f"{endian}III") > > self.e_flags, self.e_ehsize, self.e_phentsize, self.e_phnum = =3D > self.read_and_unpack(f"{endian}IHHH") > self.e_shentsize, self.e_shnum, self.e_shstrndx =3D > self.read_and_unpack(f"{endian}HHH") > > self.phdrs =3D [] > for i in range(self.e_phnum): > self.phdrs.append(Phdr(self, self.e_phoff + > self.e_phentsize * i)) > > self.shdrs =3D [] > for i in range(self.e_shnum): > self.shdrs.append(Shdr(self, self.e_shoff + > self.e_shentsize * i)) > return > > def read(self, size: int) -> bytes: > return self.fd.read(size) > > def read_and_unpack(self, fmt: str) -> tuple[Any, ...]: > size =3D struct.calcsize(fmt) > data =3D self.fd.read(size) > return struct.unpack(fmt, data) > > def seek(self, off: int) -> None: > self.fd.seek(off, 0) > > def __str__(self) -> str: > return f"ELF('{self.path.absolute()}', {self.e_class.name}, { > self.e_machine.name})" > > def __repr__(self) -> str: > return f"ELF('{self.path.absolute()}', {self.e_class.name}, { > self.e_machine.name})" > > @property > def entry_point(self) -> int: > return self.e_entry > > @classmethod > def is_valid(cls, path: pathlib.Path) -> bool: > return u32(path.open("rb").read(4), e =3D Endianness.BIG_ENDIAN) = =3D=3D > Elf.ELF_MAGIC > > @property > def checksec(self) -> dict[str, bool]: > """Check the security property of the ELF binary. The following > properties are: > - Canary > - NX > - PIE > - Fortify > - Partial/Full RelRO. > Return a dict() with the different keys mentioned above, and the > boolean > associated whether the protection was found.""" > if not self.__checksec: > def __check_security_property(opt: str, filename: str, > pattern: str) -> bool: > cmd =3D [readelf,] > cmd +=3D opt.split() > cmd +=3D [filename,] > lines =3D gef_execute_external(cmd, as_list=3DTrue) > for line in lines: > if re.search(pattern, line): > return True > return False > > abspath =3D str(self.path.absolute()) > readelf =3D gef.session.constants["readelf"] > self.__checksec["Canary"] =3D __check_security_property("-rs"= , > abspath, r"__stack_chk_fail") is True > has_gnu_stack =3D __check_security_property("-W -l", abspath, > r"GNU_STACK") is True > if has_gnu_stack: > self.__checksec["NX"] =3D __check_security_property("-W -= l", > abspath, r"GNU_STACK.*RWE") is False > else: > self.__checksec["NX"] =3D False > self.__checksec["PIE"] =3D __check_security_property("-h", > abspath, r":.*EXEC") is False > self.__checksec["Fortify"] =3D __check_security_property("-s"= , > abspath, r"_chk@GLIBC") is True > self.__checksec["Partial RelRO"] =3D > __check_security_property("-l", abspath, r"GNU_RELRO") is True > self.__checksec["Full RelRO"] =3D self.__checksec["Partial > RelRO"] and __check_security_property("-d", abspath, r"BIND_NOW") is True > return self.__checksec > > @classproperty > @deprecated("use `Elf.Abi.X86_64`") > def X86_64(cls) -> int: return Elf.Abi.X86_64.value # pylint: > disable=3Dno-self-argument > > @classproperty > @deprecated("use `Elf.Abi.X86_32`") > def X86_32(cls) -> int : return Elf.Abi.X86_32.value # pylint: > disable=3Dno-self-argument > > @classproperty > @deprecated("use `Elf.Abi.ARM`") > def ARM(cls) -> int : return Elf.Abi.ARM.value # pylint: > disable=3Dno-self-argument > > @classproperty > @deprecated("use `Elf.Abi.MIPS`") > def MIPS(cls) -> int : return Elf.Abi.MIPS.value # pylint: > disable=3Dno-self-argument > > @classproperty > @deprecated("use `Elf.Abi.POWERPC`") > def POWERPC(cls) -> int : return Elf.Abi.POWERPC.value # pylint: > disable=3Dno-self-argument > > @classproperty > @deprecated("use `Elf.Abi.POWERPC64`") > def POWERPC64(cls) -> int : return Elf.Abi.POWERPC64.value # pylint: > disable=3Dno-self-argument > > @classproperty > @deprecated("use `Elf.Abi.SPARC`") > def SPARC(cls) -> int : return Elf.Abi.SPARC.value # pylint: > disable=3Dno-self-argument > > @classproperty > @deprecated("use `Elf.Abi.SPARC64`") > def SPARC64(cls) -> int : return Elf.Abi.SPARC64.value # pylint: > disable=3Dno-self-argument > > @classproperty > @deprecated("use `Elf.Abi.AARCH64`") > def AARCH64(cls) -> int : return Elf.Abi.AARCH64.value # pylint: > disable=3Dno-self-argument > > @classproperty > @deprecated("use `Elf.Abi.RISCV`") > def RISCV(cls) -> int : return Elf.Abi.RISCV.value # pylint: > disable=3Dno-self-argument > > --000000000000fe8bf80628d79205 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi,

Dele= ting all the "#" in the f-string of the gef.py file removes the p= roblem on my side.
=C2=A0sed -i -e 's/#0{align/0{align/g&= #39; gef.py
=C2=A0sed -i -e 's/#0{width/0{width/g' gef.py
=C2= =A0sed -i -e 's/#07x}/07x}/g' gef.py
=C2=A0sed -i -e 's/#06x= }/06x}/g' gef.py
=C2=A0sed -i -e 's/#04x}/04x}/g' gef.py
= =C2=A0sed -i -e 's/#4x}/4x}/g' gef.py
=C2=A0sed -i -e 's/#8x= }/8x}/g' gef.py
=C2=A0sed -i -e 's/#10x}/10x}/g' gef.py
= =C2=A0sed -i -e 's/#x}/x}/g' gef.py

Your smaller example Eli= also contains a f-string with the "#".

<= div>This python f-string format specifier is described here: https://docs.python.org/3/library/string.html#format-specification-mini= -language

Is this format specifier supported from the be= ginning ?

For example :

value =3D 0xab
print(f"= {value:x} is a value")

=3D> color syntax : is = a value=C2=A0=C2=A0=C2=A0 has the color defined by font-lock-string-fac= e

while

value =3D 0xab
print(f"{value:#x} = is a value")

=3D> color are messed up... is has color defined by font-lock-keyword-face and a value has color = defined by default face

Best,

=
Rehan=C2=A0

On Sun, Dec 8, 2024 at 6:3= 7=E2=80=AFPM Eli Zaretskii <eliz@gnu.org= > wrote:
= > From: rehan malak <rehan.malak@gmail.com>
> Date: Sun, 8 Dec 2024 14:05:36 +0100
>
> I can reproduce systematically this freeze dealing with a 10000lines > Python file :
>
> wget https://raw.githubuserco= ntent.com/hugsy/gef/refs/heads/main/gef.py
> emacs -Q gef.py

A much smaller reproducer is attached below.=C2=A0 Just visiting it freezes=
Emacs.=C2=A0 But if I change the line marked below:

=C2=A0 =C2=A0 @classmethod
=C2=A0 =C2=A0 def is_valid(cls, _: pathlib.Path) -> bool:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 raise NotImplementedError

=C2=A0 =C2=A0 def __str__(self) -> str:
=C2=A0 >>>>> return f"{self.name}('{self.path.absolute()= }', entry @ {self.entry_point:#x})"

to say this instead:

=C2=A0 =C2=A0 =C2=A0 =C2=A0 return self.name

the problem goes away.=C2=A0 So it is something in that complex expression<= br> that trips syntax-ppss.

Stefan and kobarity, any suggestions or ideas?

> PageDown several times or scrolling with the mouse
>
> Emacs freezes, Ctrl-g not working, CPU 100%
>
> It works also by searching : Ctrl-s show RET
> then Ctrl-s several times
>
> With a minimal .emacs :
>
> (set debug-on-error t)
> (set debug-on-quit t)
>
> and before scrolling
>
> M-x profiler-start RET
>
> then in an external terminal
>
> pkill -SIGUSR2 emacs
>
> I get the backtrace :
>
> Debugger entered--entering a function:
> * #f(compiled-function () #<bytecode -0x179dcd1db31182ae>)()
>=C2=A0 =C2=A0syntax-ppss()
>=C2=A0 =C2=A0python-syntax-context-type()
>=C2=A0 =C2=A0python-nav-forward-block(-1)
>=C2=A0 =C2=A0python-nav-backward-block()
>=C2=A0 =C2=A0python-nav-beginning-of-block()
>=C2=A0 =C2=A0python-nav-end-of-block()
>=C2=A0 =C2=A0python-info-statement-ends-block-p()
>=C2=A0 =C2=A0python-info-end-of-block-p()
>=C2=A0 =C2=A0python-nav--forward-sexp(1 nil nil)
>=C2=A0 =C2=A0python-nav-forward-sexp(1)
>=C2=A0 =C2=A0forward-sexp(1)
>=C2=A0 =C2=A0up-list(1)
>=C2=A0 =C2=A0python--font-lock-f-strings(30419)
>=C2=A0 =C2=A0font-lock-fontify-keywords-region(28914 30419 nil)
>=C2=A0 =C2=A0font-lock-default-fontify-region(28914 30414 nil)
>=C2=A0 =C2=A0font-lock-fontify-region(28914 30414)
>=C2=A0 =C2=A0#f(compiled-function (fun) #<bytecode -0x8a96d65e1315e7= 1>)(font-lock-fontify-region)
>=C2=A0 =C2=A0run-hook-wrapped(#f(compiled-function (fun) #<bytecode = -0x8a96d65e1315e71>) font-lock-fontify-region)
>=C2=A0 =C2=A0jit-lock--run-functions(28914 30414)
>=C2=A0 =C2=A0jit-lock-fontify-now(28914 30414)
>=C2=A0 =C2=A0jit-lock-function(28914)

I see something different, in GDB:

=C2=A0 Lisp Backtrace:
=C2=A0 "parse-partial-sexp" (0x9f1a788)
=C2=A0 "syntax-ppss" (0x9f1a710)
=C2=A0 "python-info-line-ends-backslash-p" (0x9f1a6b8)
=C2=A0 "python-nav-end-of-statement" (0x9f1a670)
=C2=A0 "python-nav-end-of-block" (0x9f1a630)
=C2=A0 "python-info-statement-ends-block-p" (0x9f1a610)
=C2=A0 "python-info-end-of-block-p" (0x9f1a5c0)
=C2=A0 "python-nav--forward-sexp" (0x9f1a548)
=C2=A0 "python-nav-forward-sexp" (0x9f1a4f8)
=C2=A0 "forward-sexp" (0x9f1a4a8)
=C2=A0 "up-list" (0x9f1a438)
=C2=A0 "python--font-lock-f-strings" (0x9f1a3a0)
=C2=A0 "font-lock-fontify-keywords-region" (0x9f1a308)
=C2=A0 "font-lock-default-fontify-region" (0x9f1a2a0)
=C2=A0 "font-lock-fontify-region" (0x9f1a230)
=C2=A0 0xb9117d0 PVEC_CLOSURE
=C2=A0 "run-hook-wrapped" (0x9f1a1c0)
=C2=A0 "jit-lock--run-functions" (0x9f1a0e8)
=C2=A0 "jit-lock-fontify-now" (0x9f1a058)
=C2=A0 "jit-lock-function" (0x5ffba98)
=C2=A0 "redisplay_internal (C function)" (0x0)

Here's the file with which I can reproduce the problem?


class FileFormat:
=C2=A0 =C2=A0 name: str
=C2=A0 =C2=A0 path: pathlib.Path
=C2=A0 =C2=A0 entry_point: int
=C2=A0 =C2=A0 checksec: dict[str, bool]
=C2=A0 =C2=A0 sections: list[FileFormatSection]

=C2=A0 =C2=A0 def __init__(self, path: str | pathlib.Path) -> None:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 raise NotImplementedError

=C2=A0 =C2=A0 def __init_subclass__(cls: Type["FileFormat"], **kw= args):
=C2=A0 =C2=A0 =C2=A0 =C2=A0 global __registered_file_formats__
=C2=A0 =C2=A0 =C2=A0 =C2=A0 super().__init_subclass__(**kwargs)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 required_attributes =3D ("name", &quo= t;entry_point", "is_valid", "checksec",)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 for attr in required_attributes:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if not hasattr(cls, attr):
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 raise NotImplemente= dError(f"File format '{cls.__name__}' is invalid: missing attr= ibute '{attr}'")
=C2=A0 =C2=A0 =C2=A0 =C2=A0 __registered_file_formats__.add(cls)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 return

=C2=A0 =C2=A0 @classmethod
=C2=A0 =C2=A0 def is_valid(cls, _: pathlib.Path) -> bool:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 raise NotImplementedError

=C2=A0 =C2=A0 def __str__(self) -> str:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 return f"{self.name}('{self.path.absolute()= }', entry @ {self.entry_point:#x})"


class Elf(FileFormat):
=C2=A0 =C2=A0 """Basic ELF parsing.
=C2=A0 =C2=A0 Ref:
=C2=A0 =C2=A0 - http://www.skyfree.org/linux/r= eferences/ELF_Format.pdf
=C2=A0 =C2=A0 - https://refspecs.linuxfounda= tion.org/elf/elfspec_ppc.pdf
=C2=A0 =C2=A0 - https://refspecs.lin= uxfoundation.org/ELF/ppc64/PPC-elf64abi.html
=C2=A0 =C2=A0 """
=C2=A0 =C2=A0 class Class(enum.Enum):
=C2=A0 =C2=A0 =C2=A0 =C2=A0 ELF_32_BITS=C2=A0 =C2=A0 =C2=A0 =C2=A0=3D 0x01<= br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 ELF_64_BITS=C2=A0 =C2=A0 =C2=A0 =C2=A0=3D 0x02<= br>
=C2=A0 =C2=A0 ELF_MAGIC=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=3D 0x7f454c46

=C2=A0 =C2=A0 class Abi(enum.Enum):
=C2=A0 =C2=A0 =C2=A0 =C2=A0 X86_64=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =3D 0x3e
=C2=A0 =C2=A0 =C2=A0 =C2=A0 X86_32=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =3D 0x03
=C2=A0 =C2=A0 =C2=A0 =C2=A0 ARM=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0=3D 0x28
=C2=A0 =C2=A0 =C2=A0 =C2=A0 MIPS=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =3D 0x08
=C2=A0 =C2=A0 =C2=A0 =C2=A0 POWERPC=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0=3D 0x14
=C2=A0 =C2=A0 =C2=A0 =C2=A0 POWERPC64=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=3D = 0x15
=C2=A0 =C2=A0 =C2=A0 =C2=A0 SPARC=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0=3D 0x02
=C2=A0 =C2=A0 =C2=A0 =C2=A0 SPARC64=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0=3D 0x2b
=C2=A0 =C2=A0 =C2=A0 =C2=A0 AARCH64=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0=3D 0xb7
=C2=A0 =C2=A0 =C2=A0 =C2=A0 RISCV=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0=3D 0xf3
=C2=A0 =C2=A0 =C2=A0 =C2=A0 IA64=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =3D 0x32
=C2=A0 =C2=A0 =C2=A0 =C2=A0 M68K=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =3D 0x04

=C2=A0 =C2=A0 class Type(enum.Enum):
=C2=A0 =C2=A0 =C2=A0 =C2=A0 ET_RELOC=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =3D = 1
=C2=A0 =C2=A0 =C2=A0 =C2=A0 ET_EXEC=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0=3D 2
=C2=A0 =C2=A0 =C2=A0 =C2=A0 ET_DYN=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =3D 3
=C2=A0 =C2=A0 =C2=A0 =C2=A0 ET_CORE=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0=3D 4

=C2=A0 =C2=A0 class OsAbi(enum.Enum):
=C2=A0 =C2=A0 =C2=A0 =C2=A0 SYSTEMV=C2=A0 =C2=A0 =C2=A0=3D 0x00
=C2=A0 =C2=A0 =C2=A0 =C2=A0 HPUX=C2=A0 =C2=A0 =C2=A0 =C2=A0 =3D 0x01
=C2=A0 =C2=A0 =C2=A0 =C2=A0 NETBSD=C2=A0 =C2=A0 =C2=A0 =3D 0x02
=C2=A0 =C2=A0 =C2=A0 =C2=A0 LINUX=C2=A0 =C2=A0 =C2=A0 =C2=A0=3D 0x03
=C2=A0 =C2=A0 =C2=A0 =C2=A0 SOLARIS=C2=A0 =C2=A0 =C2=A0=3D 0x06
=C2=A0 =C2=A0 =C2=A0 =C2=A0 AIX=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=3D 0x07 =C2=A0 =C2=A0 =C2=A0 =C2=A0 IRIX=C2=A0 =C2=A0 =C2=A0 =C2=A0 =3D 0x08
=C2=A0 =C2=A0 =C2=A0 =C2=A0 FREEBSD=C2=A0 =C2=A0 =C2=A0=3D 0x09
=C2=A0 =C2=A0 =C2=A0 =C2=A0 OPENBSD=C2=A0 =C2=A0 =C2=A0=3D 0x0C

=C2=A0 =C2=A0 e_magic: int=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =3D ELF_MAGIC
=C2=A0 =C2=A0 e_class: "Elf.Class"=C2=A0 =C2=A0 =C2=A0 =C2=A0 =3D= Class.ELF_32_BITS
=C2=A0 =C2=A0 e_endianness: Endianness=C2=A0 =C2=A0 =3D Endianness.LITTLE_E= NDIAN
=C2=A0 =C2=A0 e_eiversion: int
=C2=A0 =C2=A0 e_osabi: "Elf.OsAbi"
=C2=A0 =C2=A0 e_abiversion: int
=C2=A0 =C2=A0 e_pad: bytes
=C2=A0 =C2=A0 e_type: "Elf.Type"=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =3D Type.ET_EXEC
=C2=A0 =C2=A0 e_machine: Abi=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =3D Abi.X86_32
=C2=A0 =C2=A0 e_version: int
=C2=A0 =C2=A0 e_entry: int
=C2=A0 =C2=A0 e_phoff: int
=C2=A0 =C2=A0 e_shoff: int
=C2=A0 =C2=A0 e_flags: int
=C2=A0 =C2=A0 e_ehsize: int
=C2=A0 =C2=A0 e_phentsize: int
=C2=A0 =C2=A0 e_phnum: int
=C2=A0 =C2=A0 e_shentsize: int
=C2=A0 =C2=A0 e_shnum: int
=C2=A0 =C2=A0 e_shstrndx: int

=C2=A0 =C2=A0 path: pathlib.Path
=C2=A0 =C2=A0 phdrs : list["Phdr"]
=C2=A0 =C2=A0 shdrs : list["Shdr"]
=C2=A0 =C2=A0 name: str =3D "ELF"

=C2=A0 =C2=A0 __checksec : dict[str, bool]

=C2=A0 =C2=A0 def __init__(self, path: str | pathlib.Path) -> None:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 """Instantiate an ELF object. A = valid ELF must be provided, or an exception will be thrown.""&quo= t;

=C2=A0 =C2=A0 =C2=A0 =C2=A0 if isinstance(path, str):
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.path =3D pathlib.Path(path).= expanduser()
=C2=A0 =C2=A0 =C2=A0 =C2=A0 elif isinstance(path, pathlib.Path):
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.path =3D path
=C2=A0 =C2=A0 =C2=A0 =C2=A0 else:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 raise TypeError

=C2=A0 =C2=A0 =C2=A0 =C2=A0 if not self.path.exists():
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 raise FileNotFoundError(f"&#= 39;{self.path}' not found/readable, most gef features will not work&quo= t;)

=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.__checksec =3D {}

=C2=A0 =C2=A0 =C2=A0 =C2=A0 with self.path.open("rb") as self.fd:=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # off 0x0
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.e_magic, e_class, e_endianne= ss, self.e_eiversion =3D self.read_and_unpack(">IBBB")
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if self.e_magic !=3D Elf.ELF_MAGI= C:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # The ELF is corrup= ted, GDB won't handle it, no point going further
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 raise RuntimeError(= "Not a valid ELF file (magic)")

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.e_class, self.e_endianness = =3D Elf.Class(e_class), Endianness(e_endianness)

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if self.e_endianness !=3D gef.arc= h.endianness:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 warn("Unexpect= ed endianness for architecture")

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 endian =3D self.e_endianness

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # off 0x7
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 e_osabi, self.e_abiversion =3D se= lf.read_and_unpack(f"{endian}BB")
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.e_osabi =3D Elf.OsAbi(e_osab= i)

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # off 0x9
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.e_pad =3D self.read(7)

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # off 0x10
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 e_type, e_machine, self.e_version= =3D self.read_and_unpack(f"{endian}HHI")
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.e_type, self.e_machine =3D E= lf.Type(e_type), Elf.Abi(e_machine)

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # off 0x18
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if self.e_class =3D=3D Elf.Class.= ELF_64_BITS:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.e_entry, self.= e_phoff, self.e_shoff =3D self.read_and_unpack(f"{endian}QQQ") =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 else:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.e_entry, self.= e_phoff, self.e_shoff =3D self.read_and_unpack(f"{endian}III")
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.e_flags, self.e_ehsize, self= .e_phentsize, self.e_phnum =3D self.read_and_unpack(f"{endian}IHHH&quo= t;)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.e_shentsize, self.e_shnum, s= elf.e_shstrndx =3D self.read_and_unpack(f"{endian}HHH")

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.phdrs =3D []
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 for i in range(self.e_phnum):
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.phdrs.append(P= hdr(self, self.e_phoff + self.e_phentsize * i))

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.shdrs =3D []
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 for i in range(self.e_shnum):
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.shdrs.append(S= hdr(self, self.e_shoff + self.e_shentsize * i))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 return

=C2=A0 =C2=A0 def read(self, size: int) -> bytes:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 return self.fd.read(size)

=C2=A0 =C2=A0 def read_and_unpack(self, fmt: str) -> tuple[Any, ...]: =C2=A0 =C2=A0 =C2=A0 =C2=A0 size =3D struct.calcsize(fmt)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 data =3D self.fd.read(size)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 return struct.unpack(fmt, data)

=C2=A0 =C2=A0 def seek(self, off: int) -> None:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.fd.seek(off, 0)

=C2=A0 =C2=A0 def __str__(self) -> str:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 return f"ELF('{self.path.absolute()}&#= 39;, {self.e_class.name}, {self.e_machine.name})"

=C2=A0 =C2=A0 def __repr__(self) -> str:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 return f"ELF('{self.path.absolute()}&#= 39;, {self.e_class.name}, {self.e_machine.name})"

=C2=A0 =C2=A0 @property
=C2=A0 =C2=A0 def entry_point(self) -> int:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 return self.e_entry

=C2=A0 =C2=A0 @classmethod
=C2=A0 =C2=A0 def is_valid(cls, path: pathlib.Path) -> bool:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 return u32(path.open("rb").read(4), e= =3D Endianness.BIG_ENDIAN) =3D=3D Elf.ELF_MAGIC

=C2=A0 =C2=A0 @property
=C2=A0 =C2=A0 def checksec(self) -> dict[str, bool]:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 """Check the security property o= f the ELF binary. The following properties are:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 - Canary
=C2=A0 =C2=A0 =C2=A0 =C2=A0 - NX
=C2=A0 =C2=A0 =C2=A0 =C2=A0 - PIE
=C2=A0 =C2=A0 =C2=A0 =C2=A0 - Fortify
=C2=A0 =C2=A0 =C2=A0 =C2=A0 - Partial/Full RelRO.
=C2=A0 =C2=A0 =C2=A0 =C2=A0 Return a dict() with the different keys mention= ed above, and the boolean
=C2=A0 =C2=A0 =C2=A0 =C2=A0 associated whether the protection was found.&qu= ot;""
=C2=A0 =C2=A0 =C2=A0 =C2=A0 if not self.__checksec:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 def __check_security_property(opt= : str, filename: str, pattern: str) -> bool:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 cmd=C2=A0 =C2=A0=3D= [readelf,]
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 cmd=C2=A0 +=3D opt.= split()
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 cmd=C2=A0 +=3D [fil= ename,]
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 lines =3D gef_execu= te_external(cmd, as_list=3DTrue)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 for line in lines:<= br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if re= .search(pattern, line):
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 return True
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return False

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 abspath =3D str(self.path.absolut= e())
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 readelf =3D gef.session.constants= ["readelf"]
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.__checksec["Canary"= ;] =3D __check_security_property("-rs", abspath, r"__stack_c= hk_fail") is True
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 has_gnu_stack =3D __check_securit= y_property("-W -l", abspath, r"GNU_STACK") is True
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if has_gnu_stack:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.__checksec[&qu= ot;NX"] =3D __check_security_property("-W -l", abspath, r&qu= ot;GNU_STACK.*RWE") is False
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 else:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.__checksec[&qu= ot;NX"] =3D False
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.__checksec["PIE"] = =3D __check_security_property("-h", abspath, r":.*EXEC"= ) is False
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.__checksec["Fortify&quo= t;] =3D __check_security_property("-s", abspath, r"_chk@GLIB= C") is True
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.__checksec["Partial Rel= RO"] =3D __check_security_property("-l", abspath, r"GNU= _RELRO") is True
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.__checksec["Full RelRO&= quot;] =3D self.__checksec["Partial RelRO"] and __check_security_= property("-d", abspath, r"BIND_NOW") is True
=C2=A0 =C2=A0 =C2=A0 =C2=A0 return self.__checksec

=C2=A0 =C2=A0 @classproperty
=C2=A0 =C2=A0 @deprecated("use `Elf.Abi.X86_64`")
=C2=A0 =C2=A0 def X86_64(cls) -> int: return Elf.Abi.X86_64.value # pyli= nt: disable=3Dno-self-argument

=C2=A0 =C2=A0 @classproperty
=C2=A0 =C2=A0 @deprecated("use `Elf.Abi.X86_32`")
=C2=A0 =C2=A0 def X86_32(cls) -> int : return Elf.Abi.X86_32.value # pyl= int: disable=3Dno-self-argument

=C2=A0 =C2=A0 @classproperty
=C2=A0 =C2=A0 @deprecated("use `Elf.Abi.ARM`")
=C2=A0 =C2=A0 def ARM(cls) -> int : return Elf.Abi.ARM.value # pylint: d= isable=3Dno-self-argument

=C2=A0 =C2=A0 @classproperty
=C2=A0 =C2=A0 @deprecated("use `Elf.Abi.MIPS`")
=C2=A0 =C2=A0 def MIPS(cls) -> int : return Elf.Abi.MIPS.value # pylint:= disable=3Dno-self-argument

=C2=A0 =C2=A0 @classproperty
=C2=A0 =C2=A0 @deprecated("use `Elf.Abi.POWERPC`")
=C2=A0 =C2=A0 def POWERPC(cls) -> int : return Elf.Abi.POWERPC.value # p= ylint: disable=3Dno-self-argument

=C2=A0 =C2=A0 @classproperty
=C2=A0 =C2=A0 @deprecated("use `Elf.Abi.POWERPC64`")
=C2=A0 =C2=A0 def POWERPC64(cls) -> int : return Elf.Abi.POWERPC64.value= # pylint: disable=3Dno-self-argument

=C2=A0 =C2=A0 @classproperty
=C2=A0 =C2=A0 @deprecated("use `Elf.Abi.SPARC`")
=C2=A0 =C2=A0 def SPARC(cls) -> int : return Elf.Abi.SPARC.value # pylin= t: disable=3Dno-self-argument

=C2=A0 =C2=A0 @classproperty
=C2=A0 =C2=A0 @deprecated("use `Elf.Abi.SPARC64`")
=C2=A0 =C2=A0 def SPARC64(cls) -> int : return Elf.Abi.SPARC64.value # p= ylint: disable=3Dno-self-argument

=C2=A0 =C2=A0 @classproperty
=C2=A0 =C2=A0 @deprecated("use `Elf.Abi.AARCH64`")
=C2=A0 =C2=A0 def AARCH64(cls) -> int : return Elf.Abi.AARCH64.value=C2= =A0 # pylint: disable=3Dno-self-argument

=C2=A0 =C2=A0 @classproperty
=C2=A0 =C2=A0 @deprecated("use `Elf.Abi.RISCV`")
=C2=A0 =C2=A0 def RISCV(cls) -> int : return Elf.Abi.RISCV.value # pylin= t: disable=3Dno-self-argument

--000000000000fe8bf80628d79205--