We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
heap_config should give an example format for GLIBC version
The UX for the glibc version setting is not great.

1. The `heap_config` should give user an example format of GLIBC version we do expect. Currently it only shows this:
```
pwndbg> heap_config
Name                             Value (Def)  Documentation
-----------------------------------------------------------
glibc                            ''           GLIBC version for heuristics
...
```

2. When one sets the `glibc` parameter, we should have a setter that will validate it against the expected version format. Currently it does not:
```
pwndbg> set glibc as
Set GLIBC version for heuristics to 'as'.
```



--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pwndbg/glibc.py`
Content:
```
1 """
2 Get information about the GLibc
3 """
4 
5 import functools
6 import os
7 import re
8 from typing import Optional
9 from typing import Tuple
10 
11 import gdb
12 from elftools.elf.relocation import Relocation
13 
14 import pwndbg.gdblib.config
15 import pwndbg.gdblib.elf
16 import pwndbg.gdblib.file
17 import pwndbg.gdblib.info
18 import pwndbg.gdblib.memory
19 import pwndbg.gdblib.proc
20 import pwndbg.gdblib.symbol
21 import pwndbg.heap
22 import pwndbg.lib.cache
23 import pwndbg.search
24 
25 safe_lnk = pwndbg.gdblib.config.add_param(
26     "safe-linking",
27     None,
28     "whether glibc use safe-linking (on/off/auto)",
29     param_class=gdb.PARAM_AUTO_BOOLEAN,
30 )
31 
32 glibc_version = pwndbg.gdblib.config.add_param(
33     "glibc", "", "GLIBC version for heuristics", scope="heap"
34 )
35 
36 
37 @pwndbg.gdblib.proc.OnlyWhenRunning
38 def get_version() -> Optional[Tuple[int, ...]]:
39     if glibc_version.value:
40         ret = re.search(r"(\d+)\.(\d+)", glibc_version.value)
41         if ret:
42             return tuple(int(_) for _ in ret.groups())
43         else:
44             raise ValueError(
45                 f"Invalid GLIBC version: `{glibc_version.value}`, you should provide something like: 2.31 or 2.34"
46             )
47     return _get_version()
48 
49 
50 @pwndbg.gdblib.proc.OnlyWhenRunning
51 @pwndbg.lib.cache.cache_until("start", "objfile")
52 def _get_version() -> Optional[Tuple[int, ...]]:
53     if pwndbg.heap.current.libc_has_debug_syms():
54         addr = pwndbg.gdblib.symbol.address("__libc_version")
55         if addr is not None:
56             ver = pwndbg.gdblib.memory.string(addr)
57             return tuple(int(_) for _ in ver.split(b"."))
58     libc_filename = get_libc_filename_from_info_sharedlibrary()
59     if not libc_filename:
60         return None
61     result = pwndbg.gdblib.elf.dump_section_by_name(libc_filename, ".rodata", try_local_path=True)
62     if not result:
63         return None
64     _, _, data = result
65     banner_start = data.find(b"GNU C Library")
66     if banner_start == -1:
67         return None
68     banner = data[banner_start : data.find(b"\x00", banner_start)]
69     ret = re.search(rb"release version (\d+)\.(\d+)", banner)
70     return tuple(int(_) for _ in ret.groups()) if ret else None
71 
72 
73 @pwndbg.gdblib.proc.OnlyWhenRunning
74 @pwndbg.lib.cache.cache_until("start", "objfile")
75 def get_libc_filename_from_info_sharedlibrary() -> Optional[str]:
76     """
77     Get the filename of the libc by parsing the output of `info sharedlibrary`.
78     """
79     possible_libc_path = []
80     for path in pwndbg.gdblib.info.sharedlibrary_paths():
81         basename = os.path.basename(
82             path[7:] if path.startswith("target:") else path
83         )  # "target:" prefix is for remote debugging
84         if basename == "libc.so.6":
85             # The default filename of libc should be libc.so.6, so if we found it, we just return it directly.
86             return path
87         elif re.search(r"^libc6?[-_\.]", basename):
88             # Maybe user loaded the libc with LD_PRELOAD.
89             # Some common libc names: libc-2.36.so, libc6_2.36-0ubuntu4_amd64.so, libc.so
90             possible_libc_path.append(
91                 path
92             )  # We don't return it, maybe there is a libc.so.6 and this match is just a false positive.
93     # TODO: This might fail if user use LD_PRELOAD to load libc with a weird name or there are multiple shared libraries match the pattern.
94     # (But do we really need to support this case? Maybe we can wait until users really need it :P.)
95     if possible_libc_path:
96         return possible_libc_path[0]  # just return the first match for now :)
97     return None
98 
99 
100 @pwndbg.gdblib.proc.OnlyWhenRunning
101 @pwndbg.lib.cache.cache_until("start", "objfile")
102 def dump_elf_data_section() -> Optional[Tuple[int, int, bytes]]:
103     """
104     Dump .data section of libc ELF file
105     """
106     libc_filename = get_libc_filename_from_info_sharedlibrary()
107     if not libc_filename:
108         # libc not loaded yet, or it's static linked
109         return None
110     return pwndbg.gdblib.elf.dump_section_by_name(libc_filename, ".data", try_local_path=True)
111 
112 
113 @pwndbg.gdblib.proc.OnlyWhenRunning
114 @pwndbg.lib.cache.cache_until("start", "objfile")
115 def dump_relocations_by_section_name(section_name: str) -> Optional[Tuple[Relocation, ...]]:
116     """
117     Dump relocations of a section by section name of libc ELF file
118     """
119     libc_filename = get_libc_filename_from_info_sharedlibrary()
120     if not libc_filename:
121         # libc not loaded yet, or it's static linked
122         return None
123     return pwndbg.gdblib.elf.dump_relocations_by_section_name(
124         libc_filename, section_name, try_local_path=True
125     )
126 
127 
128 @pwndbg.gdblib.proc.OnlyWhenRunning
129 @pwndbg.lib.cache.cache_until("start", "objfile")
130 def get_data_section_address() -> int:
131     """
132     Find .data section address of libc
133     """
134     libc_filename = get_libc_filename_from_info_sharedlibrary()
135     if not libc_filename:
136         # libc not loaded yet, or it's static linked
137         return 0
138     # TODO: If we are debugging a remote process, this might not work if GDB cannot load the so file
139     out = pwndbg.gdblib.info.files()
140     for line in out.splitlines():
141         if line.endswith(" is .data in " + libc_filename):
142             return int(line.split()[0], 16)
143     return 0
144 
145 
146 @pwndbg.gdblib.proc.OnlyWhenRunning
147 @pwndbg.lib.cache.cache_until("start", "objfile")
148 def get_got_section_address() -> int:
149     """
150     Find .got section address of libc
151     """
152     libc_filename = get_libc_filename_from_info_sharedlibrary()
153     if not libc_filename:
154         # libc not loaded yet, or it's static linked
155         return 0
156     # TODO: If we are debugging a remote process, this might not work if GDB cannot load the so file
157     out = pwndbg.gdblib.info.files()
158     for line in out.splitlines():
159         if line.endswith(" is .got in " + libc_filename):
160             return int(line.split()[0], 16)
161     return 0
162 
163 
164 def OnlyWhenGlibcLoaded(function):
165     @functools.wraps(function)
166     def _OnlyWhenGlibcLoaded(*a, **kw):
167         if get_version() is not None:
168             return function(*a, **kw)
169         else:
170             print(f"{function.__name__}: GLibc not loaded yet.")
171 
172     return _OnlyWhenGlibcLoaded
173 
174 
175 @OnlyWhenGlibcLoaded
176 def check_safe_linking():
177     """
178     Safe-linking is a glibc 2.32 mitigation; see:
179     - https://lanph3re.blogspot.com/2020/08/blog-post.html
180     - https://research.checkpoint.com/2020/safe-linking-eliminating-a-20-year-old-malloc-exploit-primitive/
181     """
182     return (get_version() >= (2, 32) or safe_lnk) and safe_lnk is not False
183
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/pwndbg/glibc.py b/pwndbg/glibc.py
--- a/pwndbg/glibc.py
+++ b/pwndbg/glibc.py
@@ -21,6 +21,7 @@
 import pwndbg.heap
 import pwndbg.lib.cache
 import pwndbg.search
+from pwndbg.color import message
 
 safe_lnk = pwndbg.gdblib.config.add_param(
     "safe-linking",
@@ -30,21 +31,28 @@
 )
 
 glibc_version = pwndbg.gdblib.config.add_param(
-    "glibc", "", "GLIBC version for heuristics", scope="heap"
+    "glibc", "", "GLIBC version for heap heuristics resolution (e.g. 2.31)", scope="heap"
 )
 
 
+@pwndbg.gdblib.config.trigger(glibc_version)
+def set_glibc_version() -> None:
+    ret = re.search(r"(\d+)\.(\d+)", glibc_version.value)
+    if ret:
+        glibc_version.value = tuple(map(int, ret.groups()))
+        return
+
+    print(
+        message.warn(
+            f"Invalid GLIBC version: `{glibc_version.value}`, you should provide something like: 2.31 or 2.34"
+        )
+    )
+    glibc_version.revert_default()
+
+
 @pwndbg.gdblib.proc.OnlyWhenRunning
 def get_version() -> Optional[Tuple[int, ...]]:
-    if glibc_version.value:
-        ret = re.search(r"(\d+)\.(\d+)", glibc_version.value)
-        if ret:
-            return tuple(int(_) for _ in ret.groups())
-        else:
-            raise ValueError(
-                f"Invalid GLIBC version: `{glibc_version.value}`, you should provide something like: 2.31 or 2.34"
-            )
-    return _get_version()
+    return glibc_version or _get_version()
 
 
 @pwndbg.gdblib.proc.OnlyWhenRunning

{"golden_diff": "diff --git a/pwndbg/glibc.py b/pwndbg/glibc.py\n--- a/pwndbg/glibc.py\n+++ b/pwndbg/glibc.py\n@@ -21,6 +21,7 @@\n import pwndbg.heap\n import pwndbg.lib.cache\n import pwndbg.search\n+from pwndbg.color import message\n \n safe_lnk = pwndbg.gdblib.config.add_param(\n     \"safe-linking\",\n@@ -30,21 +31,28 @@\n )\n \n glibc_version = pwndbg.gdblib.config.add_param(\n-    \"glibc\", \"\", \"GLIBC version for heuristics\", scope=\"heap\"\n+    \"glibc\", \"\", \"GLIBC version for heap heuristics resolution (e.g. 2.31)\", scope=\"heap\"\n )\n \n \n+@pwndbg.gdblib.config.trigger(glibc_version)\n+def set_glibc_version() -> None:\n+    ret = re.search(r\"(\\d+)\\.(\\d+)\", glibc_version.value)\n+    if ret:\n+        glibc_version.value = tuple(map(int, ret.groups()))\n+        return\n+\n+    print(\n+        message.warn(\n+            f\"Invalid GLIBC version: `{glibc_version.value}`, you should provide something like: 2.31 or 2.34\"\n+        )\n+    )\n+    glibc_version.revert_default()\n+\n+\n @pwndbg.gdblib.proc.OnlyWhenRunning\n def get_version() -> Optional[Tuple[int, ...]]:\n-    if glibc_version.value:\n-        ret = re.search(r\"(\\d+)\\.(\\d+)\", glibc_version.value)\n-        if ret:\n-            return tuple(int(_) for _ in ret.groups())\n-        else:\n-            raise ValueError(\n-                f\"Invalid GLIBC version: `{glibc_version.value}`, you should provide something like: 2.31 or 2.34\"\n-            )\n-    return _get_version()\n+    return glibc_version or _get_version()\n \n \n @pwndbg.gdblib.proc.OnlyWhenRunning\n", "issue": "heap_config should give an example format for GLIBC version\nThe UX for the glibc version setting is not great.\r\n\r\n1. The `heap_config` should give user an example format of GLIBC version we do expect. Currently it only shows this:\r\n```\r\npwndbg> heap_config\r\nName                             Value (Def)  Documentation\r\n-----------------------------------------------------------\r\nglibc                            ''           GLIBC version for heuristics\r\n...\r\n```\r\n\r\n2. When one sets the `glibc` parameter, we should have a setter that will validate it against the expected version format. Currently it does not:\r\n```\r\npwndbg> set glibc as\r\nSet GLIBC version for heuristics to 'as'.\r\n```\r\n\r\n\n", "before_files": [{"content": "\"\"\"\nGet information about the GLibc\n\"\"\"\n\nimport functools\nimport os\nimport re\nfrom typing import Optional\nfrom typing import Tuple\n\nimport gdb\nfrom elftools.elf.relocation import Relocation\n\nimport pwndbg.gdblib.config\nimport pwndbg.gdblib.elf\nimport pwndbg.gdblib.file\nimport pwndbg.gdblib.info\nimport pwndbg.gdblib.memory\nimport pwndbg.gdblib.proc\nimport pwndbg.gdblib.symbol\nimport pwndbg.heap\nimport pwndbg.lib.cache\nimport pwndbg.search\n\nsafe_lnk = pwndbg.gdblib.config.add_param(\n    \"safe-linking\",\n    None,\n    \"whether glibc use safe-linking (on/off/auto)\",\n    param_class=gdb.PARAM_AUTO_BOOLEAN,\n)\n\nglibc_version = pwndbg.gdblib.config.add_param(\n    \"glibc\", \"\", \"GLIBC version for heuristics\", scope=\"heap\"\n)\n\n\n@pwndbg.gdblib.proc.OnlyWhenRunning\ndef get_version() -> Optional[Tuple[int, ...]]:\n    if glibc_version.value:\n        ret = re.search(r\"(\\d+)\\.(\\d+)\", glibc_version.value)\n        if ret:\n            return tuple(int(_) for _ in ret.groups())\n        else:\n            raise ValueError(\n                f\"Invalid GLIBC version: `{glibc_version.value}`, you should provide something like: 2.31 or 2.34\"\n            )\n    return _get_version()\n\n\n@pwndbg.gdblib.proc.OnlyWhenRunning\n@pwndbg.lib.cache.cache_until(\"start\", \"objfile\")\ndef _get_version() -> Optional[Tuple[int, ...]]:\n    if pwndbg.heap.current.libc_has_debug_syms():\n        addr = pwndbg.gdblib.symbol.address(\"__libc_version\")\n        if addr is not None:\n            ver = pwndbg.gdblib.memory.string(addr)\n            return tuple(int(_) for _ in ver.split(b\".\"))\n    libc_filename = get_libc_filename_from_info_sharedlibrary()\n    if not libc_filename:\n        return None\n    result = pwndbg.gdblib.elf.dump_section_by_name(libc_filename, \".rodata\", try_local_path=True)\n    if not result:\n        return None\n    _, _, data = result\n    banner_start = data.find(b\"GNU C Library\")\n    if banner_start == -1:\n        return None\n    banner = data[banner_start : data.find(b\"\\x00\", banner_start)]\n    ret = re.search(rb\"release version (\\d+)\\.(\\d+)\", banner)\n    return tuple(int(_) for _ in ret.groups()) if ret else None\n\n\n@pwndbg.gdblib.proc.OnlyWhenRunning\n@pwndbg.lib.cache.cache_until(\"start\", \"objfile\")\ndef get_libc_filename_from_info_sharedlibrary() -> Optional[str]:\n    \"\"\"\n    Get the filename of the libc by parsing the output of `info sharedlibrary`.\n    \"\"\"\n    possible_libc_path = []\n    for path in pwndbg.gdblib.info.sharedlibrary_paths():\n        basename = os.path.basename(\n            path[7:] if path.startswith(\"target:\") else path\n        )  # \"target:\" prefix is for remote debugging\n        if basename == \"libc.so.6\":\n            # The default filename of libc should be libc.so.6, so if we found it, we just return it directly.\n            return path\n        elif re.search(r\"^libc6?[-_\\.]\", basename):\n            # Maybe user loaded the libc with LD_PRELOAD.\n            # Some common libc names: libc-2.36.so, libc6_2.36-0ubuntu4_amd64.so, libc.so\n            possible_libc_path.append(\n                path\n            )  # We don't return it, maybe there is a libc.so.6 and this match is just a false positive.\n    # TODO: This might fail if user use LD_PRELOAD to load libc with a weird name or there are multiple shared libraries match the pattern.\n    # (But do we really need to support this case? Maybe we can wait until users really need it :P.)\n    if possible_libc_path:\n        return possible_libc_path[0]  # just return the first match for now :)\n    return None\n\n\n@pwndbg.gdblib.proc.OnlyWhenRunning\n@pwndbg.lib.cache.cache_until(\"start\", \"objfile\")\ndef dump_elf_data_section() -> Optional[Tuple[int, int, bytes]]:\n    \"\"\"\n    Dump .data section of libc ELF file\n    \"\"\"\n    libc_filename = get_libc_filename_from_info_sharedlibrary()\n    if not libc_filename:\n        # libc not loaded yet, or it's static linked\n        return None\n    return pwndbg.gdblib.elf.dump_section_by_name(libc_filename, \".data\", try_local_path=True)\n\n\n@pwndbg.gdblib.proc.OnlyWhenRunning\n@pwndbg.lib.cache.cache_until(\"start\", \"objfile\")\ndef dump_relocations_by_section_name(section_name: str) -> Optional[Tuple[Relocation, ...]]:\n    \"\"\"\n    Dump relocations of a section by section name of libc ELF file\n    \"\"\"\n    libc_filename = get_libc_filename_from_info_sharedlibrary()\n    if not libc_filename:\n        # libc not loaded yet, or it's static linked\n        return None\n    return pwndbg.gdblib.elf.dump_relocations_by_section_name(\n        libc_filename, section_name, try_local_path=True\n    )\n\n\n@pwndbg.gdblib.proc.OnlyWhenRunning\n@pwndbg.lib.cache.cache_until(\"start\", \"objfile\")\ndef get_data_section_address() -> int:\n    \"\"\"\n    Find .data section address of libc\n    \"\"\"\n    libc_filename = get_libc_filename_from_info_sharedlibrary()\n    if not libc_filename:\n        # libc not loaded yet, or it's static linked\n        return 0\n    # TODO: If we are debugging a remote process, this might not work if GDB cannot load the so file\n    out = pwndbg.gdblib.info.files()\n    for line in out.splitlines():\n        if line.endswith(\" is .data in \" + libc_filename):\n            return int(line.split()[0], 16)\n    return 0\n\n\n@pwndbg.gdblib.proc.OnlyWhenRunning\n@pwndbg.lib.cache.cache_until(\"start\", \"objfile\")\ndef get_got_section_address() -> int:\n    \"\"\"\n    Find .got section address of libc\n    \"\"\"\n    libc_filename = get_libc_filename_from_info_sharedlibrary()\n    if not libc_filename:\n        # libc not loaded yet, or it's static linked\n        return 0\n    # TODO: If we are debugging a remote process, this might not work if GDB cannot load the so file\n    out = pwndbg.gdblib.info.files()\n    for line in out.splitlines():\n        if line.endswith(\" is .got in \" + libc_filename):\n            return int(line.split()[0], 16)\n    return 0\n\n\ndef OnlyWhenGlibcLoaded(function):\n    @functools.wraps(function)\n    def _OnlyWhenGlibcLoaded(*a, **kw):\n        if get_version() is not None:\n            return function(*a, **kw)\n        else:\n            print(f\"{function.__name__}: GLibc not loaded yet.\")\n\n    return _OnlyWhenGlibcLoaded\n\n\n@OnlyWhenGlibcLoaded\ndef check_safe_linking():\n    \"\"\"\n    Safe-linking is a glibc 2.32 mitigation; see:\n    - https://lanph3re.blogspot.com/2020/08/blog-post.html\n    - https://research.checkpoint.com/2020/safe-linking-eliminating-a-20-year-old-malloc-exploit-primitive/\n    \"\"\"\n    return (get_version() >= (2, 32) or safe_lnk) and safe_lnk is not False\n", "path": "pwndbg/glibc.py"}], "after_files": [{"content": "\"\"\"\nGet information about the GLibc\n\"\"\"\n\nimport functools\nimport os\nimport re\nfrom typing import Optional\nfrom typing import Tuple\n\nimport gdb\nfrom elftools.elf.relocation import Relocation\n\nimport pwndbg.gdblib.config\nimport pwndbg.gdblib.elf\nimport pwndbg.gdblib.file\nimport pwndbg.gdblib.info\nimport pwndbg.gdblib.memory\nimport pwndbg.gdblib.proc\nimport pwndbg.gdblib.symbol\nimport pwndbg.heap\nimport pwndbg.lib.cache\nimport pwndbg.search\nfrom pwndbg.color import message\n\nsafe_lnk = pwndbg.gdblib.config.add_param(\n    \"safe-linking\",\n    None,\n    \"whether glibc use safe-linking (on/off/auto)\",\n    param_class=gdb.PARAM_AUTO_BOOLEAN,\n)\n\nglibc_version = pwndbg.gdblib.config.add_param(\n    \"glibc\", \"\", \"GLIBC version for heap heuristics resolution (e.g. 2.31)\", scope=\"heap\"\n)\n\n\n@pwndbg.gdblib.config.trigger(glibc_version)\ndef set_glibc_version() -> None:\n    ret = re.search(r\"(\\d+)\\.(\\d+)\", glibc_version.value)\n    if ret:\n        glibc_version.value = tuple(map(int, ret.groups()))\n        return\n\n    print(\n        message.warn(\n            f\"Invalid GLIBC version: `{glibc_version.value}`, you should provide something like: 2.31 or 2.34\"\n        )\n    )\n    glibc_version.revert_default()\n\n\n@pwndbg.gdblib.proc.OnlyWhenRunning\ndef get_version() -> Optional[Tuple[int, ...]]:\n    return glibc_version or _get_version()\n\n\n@pwndbg.gdblib.proc.OnlyWhenRunning\n@pwndbg.lib.cache.cache_until(\"start\", \"objfile\")\ndef _get_version() -> Optional[Tuple[int, ...]]:\n    if pwndbg.heap.current.libc_has_debug_syms():\n        addr = pwndbg.gdblib.symbol.address(\"__libc_version\")\n        if addr is not None:\n            ver = pwndbg.gdblib.memory.string(addr)\n            return tuple(int(_) for _ in ver.split(b\".\"))\n    libc_filename = get_libc_filename_from_info_sharedlibrary()\n    if not libc_filename:\n        return None\n    result = pwndbg.gdblib.elf.dump_section_by_name(libc_filename, \".rodata\", try_local_path=True)\n    if not result:\n        return None\n    _, _, data = result\n    banner_start = data.find(b\"GNU C Library\")\n    if banner_start == -1:\n        return None\n    banner = data[banner_start : data.find(b\"\\x00\", banner_start)]\n    ret = re.search(rb\"release version (\\d+)\\.(\\d+)\", banner)\n    return tuple(int(_) for _ in ret.groups()) if ret else None\n\n\n@pwndbg.gdblib.proc.OnlyWhenRunning\n@pwndbg.lib.cache.cache_until(\"start\", \"objfile\")\ndef get_libc_filename_from_info_sharedlibrary() -> Optional[str]:\n    \"\"\"\n    Get the filename of the libc by parsing the output of `info sharedlibrary`.\n    \"\"\"\n    possible_libc_path = []\n    for path in pwndbg.gdblib.info.sharedlibrary_paths():\n        basename = os.path.basename(\n            path[7:] if path.startswith(\"target:\") else path\n        )  # \"target:\" prefix is for remote debugging\n        if basename == \"libc.so.6\":\n            # The default filename of libc should be libc.so.6, so if we found it, we just return it directly.\n            return path\n        elif re.search(r\"^libc6?[-_\\.]\", basename):\n            # Maybe user loaded the libc with LD_PRELOAD.\n            # Some common libc names: libc-2.36.so, libc6_2.36-0ubuntu4_amd64.so, libc.so\n            possible_libc_path.append(\n                path\n            )  # We don't return it, maybe there is a libc.so.6 and this match is just a false positive.\n    # TODO: This might fail if user use LD_PRELOAD to load libc with a weird name or there are multiple shared libraries match the pattern.\n    # (But do we really need to support this case? Maybe we can wait until users really need it :P.)\n    if possible_libc_path:\n        return possible_libc_path[0]  # just return the first match for now :)\n    return None\n\n\n@pwndbg.gdblib.proc.OnlyWhenRunning\n@pwndbg.lib.cache.cache_until(\"start\", \"objfile\")\ndef dump_elf_data_section() -> Optional[Tuple[int, int, bytes]]:\n    \"\"\"\n    Dump .data section of libc ELF file\n    \"\"\"\n    libc_filename = get_libc_filename_from_info_sharedlibrary()\n    if not libc_filename:\n        # libc not loaded yet, or it's static linked\n        return None\n    return pwndbg.gdblib.elf.dump_section_by_name(libc_filename, \".data\", try_local_path=True)\n\n\n@pwndbg.gdblib.proc.OnlyWhenRunning\n@pwndbg.lib.cache.cache_until(\"start\", \"objfile\")\ndef dump_relocations_by_section_name(section_name: str) -> Optional[Tuple[Relocation, ...]]:\n    \"\"\"\n    Dump relocations of a section by section name of libc ELF file\n    \"\"\"\n    libc_filename = get_libc_filename_from_info_sharedlibrary()\n    if not libc_filename:\n        # libc not loaded yet, or it's static linked\n        return None\n    return pwndbg.gdblib.elf.dump_relocations_by_section_name(\n        libc_filename, section_name, try_local_path=True\n    )\n\n\n@pwndbg.gdblib.proc.OnlyWhenRunning\n@pwndbg.lib.cache.cache_until(\"start\", \"objfile\")\ndef get_data_section_address() -> int:\n    \"\"\"\n    Find .data section address of libc\n    \"\"\"\n    libc_filename = get_libc_filename_from_info_sharedlibrary()\n    if not libc_filename:\n        # libc not loaded yet, or it's static linked\n        return 0\n    # TODO: If we are debugging a remote process, this might not work if GDB cannot load the so file\n    out = pwndbg.gdblib.info.files()\n    for line in out.splitlines():\n        if line.endswith(\" is .data in \" + libc_filename):\n            return int(line.split()[0], 16)\n    return 0\n\n\n@pwndbg.gdblib.proc.OnlyWhenRunning\n@pwndbg.lib.cache.cache_until(\"start\", \"objfile\")\ndef get_got_section_address() -> int:\n    \"\"\"\n    Find .got section address of libc\n    \"\"\"\n    libc_filename = get_libc_filename_from_info_sharedlibrary()\n    if not libc_filename:\n        # libc not loaded yet, or it's static linked\n        return 0\n    # TODO: If we are debugging a remote process, this might not work if GDB cannot load the so file\n    out = pwndbg.gdblib.info.files()\n    for line in out.splitlines():\n        if line.endswith(\" is .got in \" + libc_filename):\n            return int(line.split()[0], 16)\n    return 0\n\n\ndef OnlyWhenGlibcLoaded(function):\n    @functools.wraps(function)\n    def _OnlyWhenGlibcLoaded(*a, **kw):\n        if get_version() is not None:\n            return function(*a, **kw)\n        else:\n            print(f\"{function.__name__}: GLibc not loaded yet.\")\n\n    return _OnlyWhenGlibcLoaded\n\n\n@OnlyWhenGlibcLoaded\ndef check_safe_linking():\n    \"\"\"\n    Safe-linking is a glibc 2.32 mitigation; see:\n    - https://lanph3re.blogspot.com/2020/08/blog-post.html\n    - https://research.checkpoint.com/2020/safe-linking-eliminating-a-20-year-old-malloc-exploit-primitive/\n    \"\"\"\n    return (get_version() >= (2, 32) or safe_lnk) and safe_lnk is not False\n", "path": "pwndbg/glibc.py"}]}