We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Refactor symbol.py skipped exceptions
The list created here: https://github.com/pwndbg/pwndbg/blob/85eb6c8bf9c59280f82f2168048071de104cd9dc/pwndbg/gdblib/symbol.py#L123-L140

should be a global variable and should be created with `(item1, item2, ...)` instead of appending to a list. The comments should still stand.

If anyone wants to go ahead and refactor it, please send a PR :).


--- 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/gdblib/symbol.py`
Content:
```
1 """
2 Looking up addresses for function names / symbols, and
3 vice-versa.
4 
5 Uses IDA when available if there isn't sufficient symbol
6 information available.
7 """
8 from __future__ import annotations
9 
10 import re
11 
12 import gdb
13 
14 import pwndbg.gdblib.android
15 import pwndbg.gdblib.arch
16 import pwndbg.gdblib.elf
17 import pwndbg.gdblib.events
18 import pwndbg.gdblib.file
19 import pwndbg.gdblib.memory
20 import pwndbg.gdblib.qemu
21 import pwndbg.gdblib.remote
22 import pwndbg.gdblib.stack
23 import pwndbg.gdblib.vmmap
24 import pwndbg.ida
25 import pwndbg.lib.cache
26 
27 
28 def _get_debug_file_directory():
29     """
30     Retrieve the debug file directory path.
31 
32     The debug file directory path ('show debug-file-directory') is a comma-
33     separated list of directories which GDB will look in to find the binaries
34     currently loaded.
35     """
36     result = gdb.execute("show debug-file-directory", to_string=True, from_tty=False)
37     expr = r'The directory where separate debug symbols are searched for is "(.*)".\n'
38 
39     match = re.search(expr, result)
40 
41     if match:
42         return match.group(1)
43     return ""
44 
45 
46 def _set_debug_file_directory(d) -> None:
47     gdb.execute(f"set debug-file-directory {d}", to_string=True, from_tty=False)
48 
49 
50 def _add_debug_file_directory(d) -> None:
51     current = _get_debug_file_directory()
52     if current:
53         _set_debug_file_directory(f"{current}:{d}")
54     else:
55         _set_debug_file_directory(d)
56 
57 
58 if "/usr/lib/debug" not in _get_debug_file_directory():
59     _add_debug_file_directory("/usr/lib/debug")
60 
61 
62 @pwndbg.lib.cache.cache_until("objfile")
63 def get(address: int, gdb_only=False) -> str:
64     """
65     Retrieve the name for the symbol located at `address` - either from GDB or from IDA sync
66     Passing `gdb_only=True`
67     """
68     # Note: we do not return "" on `address < pwndbg.gdblib.memory.MMAP_MIN_ADDR`
69     # because this may be used to find out the symbol name on PIE binaries that weren't started yet
70     # and then their symbol addresses can be found by GDB on their (non-rebased) offsets
71 
72     # Fast path: GDB's `info symbol` returns 'Numeric constant too large' here
73     if address >= ((1 << 64) - 1):
74         return ""
75 
76     # This sucks, but there's not a GDB API for this.
77     result = gdb.execute("info symbol %#x" % int(address), to_string=True, from_tty=False)
78 
79     if not gdb_only and result.startswith("No symbol"):
80         address = int(address)
81         exe = pwndbg.gdblib.elf.exe()
82         if exe:
83             exe_map = pwndbg.gdblib.vmmap.find(exe.address)
84             if exe_map and address in exe_map:
85                 res = pwndbg.ida.Name(address) or pwndbg.ida.GetFuncOffset(address)
86                 return res or ""
87 
88     # If there are newlines, which means that there are multiple symbols for the address
89     # then use the first one (see also #1610)
90     result = result[: result.index("\n")]
91 
92     # See https://github.com/bminor/binutils-gdb/blob/d1702fea87aa62dff7de465464097dba63cc8c0f/gdb/printcmd.c#L1594-L1624
93     # The most often encountered formats looks like this:
94     #   "main in section .text of /bin/bash"
95     #   "main + 3 in section .text of /bin/bash"
96     #   "system + 1 in section .text of /lib/x86_64-linux-gnu/libc.so.6"
97     #   "No symbol matches system-1"
98     # But there are some others that we have to account for as well
99     if " in section " in result:
100         loc_string, _ = result.split(" in section ")
101     elif " in load address range of " in result:
102         loc_string, _ = result.split(" in load address range of ")
103     elif " overlay section " in result:
104         result, _ = result.split(" overlay section ")
105         loc_string, _ = result.split(" in ")
106     else:
107         loc_string = ""
108 
109     # If there is 'main + 87' we want to replace it with 'main+87' etc.
110     return loc_string.replace(" + ", "+")
111 
112 
113 @pwndbg.lib.cache.cache_until("objfile")
114 def address(symbol: str) -> int:
115     """
116     Get the address for `symbol`
117     """
118     try:
119         symbol_obj = gdb.lookup_symbol(symbol)[0]
120         if symbol_obj:
121             return int(symbol_obj.value().address)
122     except gdb.error as e:
123         # Symbol lookup only throws exceptions on errors, not if it failed to
124         # lookup a symbol. We want to raise these errors so we can handle them
125         # properly, but there are some we haven't figured out how to fix yet, so
126         # we ignore those here
127         skipped_exceptions = []
128 
129         # This is exception is being thrown by the Go typeinfo tests, we should
130         # investigate why this is happening and see if we can explicitly check
131         # for it with `gdb.selected_frame()`
132         skipped_exceptions.append("No frame selected")
133 
134         # If we try to look up a TLS variable when there is no TLS, this
135         # exception occurs. Ideally we should come up with a way to check for
136         # this case before calling `gdb.lookup_symbol`
137         skipped_exceptions.append("Cannot find thread-local")
138 
139         # This reproduced on GDB 12.1 and caused #1878
140         skipped_exceptions.append("symbol requires a frame to compute its value")
141 
142         if all(x not in str(e) for x in skipped_exceptions):
143             raise e
144 
145     try:
146         # Unfortunately, `gdb.lookup_symbol` does not seem to handle all
147         # symbols, so we need to fallback to using `gdb.parse_and_eval`. See
148         # https://sourceware.org/pipermail/gdb/2022-October/050362.html
149         # (We tried parsing the output of the `info address` before, but there were some issues. See #1628 and #1666)
150         if "\\" in symbol:
151             # Is it possible that happens? Probably not, but just in case
152             raise ValueError(f"Symbol {symbol!r} contains a backslash")
153         sanitized_symbol_name = symbol.replace("'", "\\'")
154         return int(gdb.parse_and_eval(f"&'{sanitized_symbol_name}'"))
155 
156     except gdb.error:
157         return None
158 
159 
160 @pwndbg.lib.cache.cache_until("objfile", "thread")
161 def static_linkage_symbol_address(symbol: str) -> int:
162     """
163     Get the address for static linkage `symbol`
164     """
165 
166     try:
167         symbol_obj = gdb.lookup_static_symbol(symbol)
168         return int(symbol_obj.value().address) if symbol_obj else None
169     except gdb.error:
170         return None
171 
172 
173 @pwndbg.lib.cache.cache_until("stop", "start")
174 def selected_frame_source_absolute_filename():
175     """
176     Retrieve the symbol table’s source absolute file name from the selected frame.
177 
178     In case of missing symbol table or frame information, None is returned.
179     """
180     try:
181         frame = gdb.selected_frame()
182     except gdb.error:
183         return None
184 
185     if not frame:
186         return None
187 
188     sal = frame.find_sal()
189     if not sal:
190         return None
191 
192     symtab = sal.symtab
193     if not symtab:
194         return None
195 
196     return symtab.fullname()
197 
198 
199 def parse_and_eval(expression: str) -> gdb.Value | None:
200     """Error handling wrapper for GDBs parse_and_eval function"""
201     try:
202         return gdb.parse_and_eval(expression)
203     except gdb.error:
204         return None
205
```
--- 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/gdblib/symbol.py b/pwndbg/gdblib/symbol.py
--- a/pwndbg/gdblib/symbol.py
+++ b/pwndbg/gdblib/symbol.py
@@ -24,6 +24,25 @@
 import pwndbg.ida
 import pwndbg.lib.cache
 
+# Symbol lookup only throws exceptions on errors, not if it failed to
+# look up a symbol. We want to raise these errors so we can handle them
+# properly, but there are some we haven't figured out how to fix yet, so
+# we ignore those here
+skipped_exceptions = None
+
+skipped_exceptions = (
+    # This exception is being thrown by the Go typeinfo tests, we should
+    # investigate why this is happening and see if we can explicitly check
+    # for it with `gdb.selected_frame()`
+    "No frame selected",
+    # If we try to look up a TLS variable when there is no TLS, this
+    # exception occurs. Ideally we should come up with a way to check for
+    # this case before calling `gdb.lookup_symbol`
+    "Cannot find thread-local",
+    # This reproduced on GDB 12.1 and caused #1878
+    "Symbol requires a frame to compute its value",
+)
+
 
 def _get_debug_file_directory():
     """
@@ -120,25 +139,6 @@
         if symbol_obj:
             return int(symbol_obj.value().address)
     except gdb.error as e:
-        # Symbol lookup only throws exceptions on errors, not if it failed to
-        # lookup a symbol. We want to raise these errors so we can handle them
-        # properly, but there are some we haven't figured out how to fix yet, so
-        # we ignore those here
-        skipped_exceptions = []
-
-        # This is exception is being thrown by the Go typeinfo tests, we should
-        # investigate why this is happening and see if we can explicitly check
-        # for it with `gdb.selected_frame()`
-        skipped_exceptions.append("No frame selected")
-
-        # If we try to look up a TLS variable when there is no TLS, this
-        # exception occurs. Ideally we should come up with a way to check for
-        # this case before calling `gdb.lookup_symbol`
-        skipped_exceptions.append("Cannot find thread-local")
-
-        # This reproduced on GDB 12.1 and caused #1878
-        skipped_exceptions.append("symbol requires a frame to compute its value")
-
         if all(x not in str(e) for x in skipped_exceptions):
             raise e

{"golden_diff": "diff --git a/pwndbg/gdblib/symbol.py b/pwndbg/gdblib/symbol.py\n--- a/pwndbg/gdblib/symbol.py\n+++ b/pwndbg/gdblib/symbol.py\n@@ -24,6 +24,25 @@\n import pwndbg.ida\n import pwndbg.lib.cache\n \n+# Symbol lookup only throws exceptions on errors, not if it failed to\n+# look up a symbol. We want to raise these errors so we can handle them\n+# properly, but there are some we haven't figured out how to fix yet, so\n+# we ignore those here\n+skipped_exceptions = None\n+\n+skipped_exceptions = (\n+    # This exception is being thrown by the Go typeinfo tests, we should\n+    # investigate why this is happening and see if we can explicitly check\n+    # for it with `gdb.selected_frame()`\n+    \"No frame selected\",\n+    # If we try to look up a TLS variable when there is no TLS, this\n+    # exception occurs. Ideally we should come up with a way to check for\n+    # this case before calling `gdb.lookup_symbol`\n+    \"Cannot find thread-local\",\n+    # This reproduced on GDB 12.1 and caused #1878\n+    \"Symbol requires a frame to compute its value\",\n+)\n+\n \n def _get_debug_file_directory():\n     \"\"\"\n@@ -120,25 +139,6 @@\n         if symbol_obj:\n             return int(symbol_obj.value().address)\n     except gdb.error as e:\n-        # Symbol lookup only throws exceptions on errors, not if it failed to\n-        # lookup a symbol. We want to raise these errors so we can handle them\n-        # properly, but there are some we haven't figured out how to fix yet, so\n-        # we ignore those here\n-        skipped_exceptions = []\n-\n-        # This is exception is being thrown by the Go typeinfo tests, we should\n-        # investigate why this is happening and see if we can explicitly check\n-        # for it with `gdb.selected_frame()`\n-        skipped_exceptions.append(\"No frame selected\")\n-\n-        # If we try to look up a TLS variable when there is no TLS, this\n-        # exception occurs. Ideally we should come up with a way to check for\n-        # this case before calling `gdb.lookup_symbol`\n-        skipped_exceptions.append(\"Cannot find thread-local\")\n-\n-        # This reproduced on GDB 12.1 and caused #1878\n-        skipped_exceptions.append(\"symbol requires a frame to compute its value\")\n-\n         if all(x not in str(e) for x in skipped_exceptions):\n             raise e\n", "issue": "Refactor symbol.py skipped exceptions\nThe list created here: https://github.com/pwndbg/pwndbg/blob/85eb6c8bf9c59280f82f2168048071de104cd9dc/pwndbg/gdblib/symbol.py#L123-L140\r\n\r\nshould be a global variable and should be created with `(item1, item2, ...)` instead of appending to a list. The comments should still stand.\r\n\r\nIf anyone wants to go ahead and refactor it, please send a PR :).\r\n\n", "before_files": [{"content": "\"\"\"\nLooking up addresses for function names / symbols, and\nvice-versa.\n\nUses IDA when available if there isn't sufficient symbol\ninformation available.\n\"\"\"\nfrom __future__ import annotations\n\nimport re\n\nimport gdb\n\nimport pwndbg.gdblib.android\nimport pwndbg.gdblib.arch\nimport pwndbg.gdblib.elf\nimport pwndbg.gdblib.events\nimport pwndbg.gdblib.file\nimport pwndbg.gdblib.memory\nimport pwndbg.gdblib.qemu\nimport pwndbg.gdblib.remote\nimport pwndbg.gdblib.stack\nimport pwndbg.gdblib.vmmap\nimport pwndbg.ida\nimport pwndbg.lib.cache\n\n\ndef _get_debug_file_directory():\n    \"\"\"\n    Retrieve the debug file directory path.\n\n    The debug file directory path ('show debug-file-directory') is a comma-\n    separated list of directories which GDB will look in to find the binaries\n    currently loaded.\n    \"\"\"\n    result = gdb.execute(\"show debug-file-directory\", to_string=True, from_tty=False)\n    expr = r'The directory where separate debug symbols are searched for is \"(.*)\".\\n'\n\n    match = re.search(expr, result)\n\n    if match:\n        return match.group(1)\n    return \"\"\n\n\ndef _set_debug_file_directory(d) -> None:\n    gdb.execute(f\"set debug-file-directory {d}\", to_string=True, from_tty=False)\n\n\ndef _add_debug_file_directory(d) -> None:\n    current = _get_debug_file_directory()\n    if current:\n        _set_debug_file_directory(f\"{current}:{d}\")\n    else:\n        _set_debug_file_directory(d)\n\n\nif \"/usr/lib/debug\" not in _get_debug_file_directory():\n    _add_debug_file_directory(\"/usr/lib/debug\")\n\n\n@pwndbg.lib.cache.cache_until(\"objfile\")\ndef get(address: int, gdb_only=False) -> str:\n    \"\"\"\n    Retrieve the name for the symbol located at `address` - either from GDB or from IDA sync\n    Passing `gdb_only=True`\n    \"\"\"\n    # Note: we do not return \"\" on `address < pwndbg.gdblib.memory.MMAP_MIN_ADDR`\n    # because this may be used to find out the symbol name on PIE binaries that weren't started yet\n    # and then their symbol addresses can be found by GDB on their (non-rebased) offsets\n\n    # Fast path: GDB's `info symbol` returns 'Numeric constant too large' here\n    if address >= ((1 << 64) - 1):\n        return \"\"\n\n    # This sucks, but there's not a GDB API for this.\n    result = gdb.execute(\"info symbol %#x\" % int(address), to_string=True, from_tty=False)\n\n    if not gdb_only and result.startswith(\"No symbol\"):\n        address = int(address)\n        exe = pwndbg.gdblib.elf.exe()\n        if exe:\n            exe_map = pwndbg.gdblib.vmmap.find(exe.address)\n            if exe_map and address in exe_map:\n                res = pwndbg.ida.Name(address) or pwndbg.ida.GetFuncOffset(address)\n                return res or \"\"\n\n    # If there are newlines, which means that there are multiple symbols for the address\n    # then use the first one (see also #1610)\n    result = result[: result.index(\"\\n\")]\n\n    # See https://github.com/bminor/binutils-gdb/blob/d1702fea87aa62dff7de465464097dba63cc8c0f/gdb/printcmd.c#L1594-L1624\n    # The most often encountered formats looks like this:\n    #   \"main in section .text of /bin/bash\"\n    #   \"main + 3 in section .text of /bin/bash\"\n    #   \"system + 1 in section .text of /lib/x86_64-linux-gnu/libc.so.6\"\n    #   \"No symbol matches system-1\"\n    # But there are some others that we have to account for as well\n    if \" in section \" in result:\n        loc_string, _ = result.split(\" in section \")\n    elif \" in load address range of \" in result:\n        loc_string, _ = result.split(\" in load address range of \")\n    elif \" overlay section \" in result:\n        result, _ = result.split(\" overlay section \")\n        loc_string, _ = result.split(\" in \")\n    else:\n        loc_string = \"\"\n\n    # If there is 'main + 87' we want to replace it with 'main+87' etc.\n    return loc_string.replace(\" + \", \"+\")\n\n\n@pwndbg.lib.cache.cache_until(\"objfile\")\ndef address(symbol: str) -> int:\n    \"\"\"\n    Get the address for `symbol`\n    \"\"\"\n    try:\n        symbol_obj = gdb.lookup_symbol(symbol)[0]\n        if symbol_obj:\n            return int(symbol_obj.value().address)\n    except gdb.error as e:\n        # Symbol lookup only throws exceptions on errors, not if it failed to\n        # lookup a symbol. We want to raise these errors so we can handle them\n        # properly, but there are some we haven't figured out how to fix yet, so\n        # we ignore those here\n        skipped_exceptions = []\n\n        # This is exception is being thrown by the Go typeinfo tests, we should\n        # investigate why this is happening and see if we can explicitly check\n        # for it with `gdb.selected_frame()`\n        skipped_exceptions.append(\"No frame selected\")\n\n        # If we try to look up a TLS variable when there is no TLS, this\n        # exception occurs. Ideally we should come up with a way to check for\n        # this case before calling `gdb.lookup_symbol`\n        skipped_exceptions.append(\"Cannot find thread-local\")\n\n        # This reproduced on GDB 12.1 and caused #1878\n        skipped_exceptions.append(\"symbol requires a frame to compute its value\")\n\n        if all(x not in str(e) for x in skipped_exceptions):\n            raise e\n\n    try:\n        # Unfortunately, `gdb.lookup_symbol` does not seem to handle all\n        # symbols, so we need to fallback to using `gdb.parse_and_eval`. See\n        # https://sourceware.org/pipermail/gdb/2022-October/050362.html\n        # (We tried parsing the output of the `info address` before, but there were some issues. See #1628 and #1666)\n        if \"\\\\\" in symbol:\n            # Is it possible that happens? Probably not, but just in case\n            raise ValueError(f\"Symbol {symbol!r} contains a backslash\")\n        sanitized_symbol_name = symbol.replace(\"'\", \"\\\\'\")\n        return int(gdb.parse_and_eval(f\"&'{sanitized_symbol_name}'\"))\n\n    except gdb.error:\n        return None\n\n\n@pwndbg.lib.cache.cache_until(\"objfile\", \"thread\")\ndef static_linkage_symbol_address(symbol: str) -> int:\n    \"\"\"\n    Get the address for static linkage `symbol`\n    \"\"\"\n\n    try:\n        symbol_obj = gdb.lookup_static_symbol(symbol)\n        return int(symbol_obj.value().address) if symbol_obj else None\n    except gdb.error:\n        return None\n\n\n@pwndbg.lib.cache.cache_until(\"stop\", \"start\")\ndef selected_frame_source_absolute_filename():\n    \"\"\"\n    Retrieve the symbol table\u2019s source absolute file name from the selected frame.\n\n    In case of missing symbol table or frame information, None is returned.\n    \"\"\"\n    try:\n        frame = gdb.selected_frame()\n    except gdb.error:\n        return None\n\n    if not frame:\n        return None\n\n    sal = frame.find_sal()\n    if not sal:\n        return None\n\n    symtab = sal.symtab\n    if not symtab:\n        return None\n\n    return symtab.fullname()\n\n\ndef parse_and_eval(expression: str) -> gdb.Value | None:\n    \"\"\"Error handling wrapper for GDBs parse_and_eval function\"\"\"\n    try:\n        return gdb.parse_and_eval(expression)\n    except gdb.error:\n        return None\n", "path": "pwndbg/gdblib/symbol.py"}], "after_files": [{"content": "\"\"\"\nLooking up addresses for function names / symbols, and\nvice-versa.\n\nUses IDA when available if there isn't sufficient symbol\ninformation available.\n\"\"\"\nfrom __future__ import annotations\n\nimport re\n\nimport gdb\n\nimport pwndbg.gdblib.android\nimport pwndbg.gdblib.arch\nimport pwndbg.gdblib.elf\nimport pwndbg.gdblib.events\nimport pwndbg.gdblib.file\nimport pwndbg.gdblib.memory\nimport pwndbg.gdblib.qemu\nimport pwndbg.gdblib.remote\nimport pwndbg.gdblib.stack\nimport pwndbg.gdblib.vmmap\nimport pwndbg.ida\nimport pwndbg.lib.cache\n\n# Symbol lookup only throws exceptions on errors, not if it failed to\n# look up a symbol. We want to raise these errors so we can handle them\n# properly, but there are some we haven't figured out how to fix yet, so\n# we ignore those here\nskipped_exceptions = None\n\nskipped_exceptions = (\n    # This exception is being thrown by the Go typeinfo tests, we should\n    # investigate why this is happening and see if we can explicitly check\n    # for it with `gdb.selected_frame()`\n    \"No frame selected\",\n    # If we try to look up a TLS variable when there is no TLS, this\n    # exception occurs. Ideally we should come up with a way to check for\n    # this case before calling `gdb.lookup_symbol`\n    \"Cannot find thread-local\",\n    # This reproduced on GDB 12.1 and caused #1878\n    \"Symbol requires a frame to compute its value\",\n)\n\n\ndef _get_debug_file_directory():\n    \"\"\"\n    Retrieve the debug file directory path.\n\n    The debug file directory path ('show debug-file-directory') is a comma-\n    separated list of directories which GDB will look in to find the binaries\n    currently loaded.\n    \"\"\"\n    result = gdb.execute(\"show debug-file-directory\", to_string=True, from_tty=False)\n    expr = r'The directory where separate debug symbols are searched for is \"(.*)\".\\n'\n\n    match = re.search(expr, result)\n\n    if match:\n        return match.group(1)\n    return \"\"\n\n\ndef _set_debug_file_directory(d) -> None:\n    gdb.execute(f\"set debug-file-directory {d}\", to_string=True, from_tty=False)\n\n\ndef _add_debug_file_directory(d) -> None:\n    current = _get_debug_file_directory()\n    if current:\n        _set_debug_file_directory(f\"{current}:{d}\")\n    else:\n        _set_debug_file_directory(d)\n\n\nif \"/usr/lib/debug\" not in _get_debug_file_directory():\n    _add_debug_file_directory(\"/usr/lib/debug\")\n\n\n@pwndbg.lib.cache.cache_until(\"objfile\")\ndef get(address: int, gdb_only=False) -> str:\n    \"\"\"\n    Retrieve the name for the symbol located at `address` - either from GDB or from IDA sync\n    Passing `gdb_only=True`\n    \"\"\"\n    # Note: we do not return \"\" on `address < pwndbg.gdblib.memory.MMAP_MIN_ADDR`\n    # because this may be used to find out the symbol name on PIE binaries that weren't started yet\n    # and then their symbol addresses can be found by GDB on their (non-rebased) offsets\n\n    # Fast path: GDB's `info symbol` returns 'Numeric constant too large' here\n    if address >= ((1 << 64) - 1):\n        return \"\"\n\n    # This sucks, but there's not a GDB API for this.\n    result = gdb.execute(\"info symbol %#x\" % int(address), to_string=True, from_tty=False)\n\n    if not gdb_only and result.startswith(\"No symbol\"):\n        address = int(address)\n        exe = pwndbg.gdblib.elf.exe()\n        if exe:\n            exe_map = pwndbg.gdblib.vmmap.find(exe.address)\n            if exe_map and address in exe_map:\n                res = pwndbg.ida.Name(address) or pwndbg.ida.GetFuncOffset(address)\n                return res or \"\"\n\n    # If there are newlines, which means that there are multiple symbols for the address\n    # then use the first one (see also #1610)\n    result = result[: result.index(\"\\n\")]\n\n    # See https://github.com/bminor/binutils-gdb/blob/d1702fea87aa62dff7de465464097dba63cc8c0f/gdb/printcmd.c#L1594-L1624\n    # The most often encountered formats looks like this:\n    #   \"main in section .text of /bin/bash\"\n    #   \"main + 3 in section .text of /bin/bash\"\n    #   \"system + 1 in section .text of /lib/x86_64-linux-gnu/libc.so.6\"\n    #   \"No symbol matches system-1\"\n    # But there are some others that we have to account for as well\n    if \" in section \" in result:\n        loc_string, _ = result.split(\" in section \")\n    elif \" in load address range of \" in result:\n        loc_string, _ = result.split(\" in load address range of \")\n    elif \" overlay section \" in result:\n        result, _ = result.split(\" overlay section \")\n        loc_string, _ = result.split(\" in \")\n    else:\n        loc_string = \"\"\n\n    # If there is 'main + 87' we want to replace it with 'main+87' etc.\n    return loc_string.replace(\" + \", \"+\")\n\n\n@pwndbg.lib.cache.cache_until(\"objfile\")\ndef address(symbol: str) -> int:\n    \"\"\"\n    Get the address for `symbol`\n    \"\"\"\n    try:\n        symbol_obj = gdb.lookup_symbol(symbol)[0]\n        if symbol_obj:\n            return int(symbol_obj.value().address)\n    except gdb.error as e:\n        if all(x not in str(e) for x in skipped_exceptions):\n            raise e\n\n    try:\n        # Unfortunately, `gdb.lookup_symbol` does not seem to handle all\n        # symbols, so we need to fallback to using `gdb.parse_and_eval`. See\n        # https://sourceware.org/pipermail/gdb/2022-October/050362.html\n        # (We tried parsing the output of the `info address` before, but there were some issues. See #1628 and #1666)\n        if \"\\\\\" in symbol:\n            # Is it possible that happens? Probably not, but just in case\n            raise ValueError(f\"Symbol {symbol!r} contains a backslash\")\n        sanitized_symbol_name = symbol.replace(\"'\", \"\\\\'\")\n        return int(gdb.parse_and_eval(f\"&'{sanitized_symbol_name}'\"))\n\n    except gdb.error:\n        return None\n\n\n@pwndbg.lib.cache.cache_until(\"objfile\", \"thread\")\ndef static_linkage_symbol_address(symbol: str) -> int:\n    \"\"\"\n    Get the address for static linkage `symbol`\n    \"\"\"\n\n    try:\n        symbol_obj = gdb.lookup_static_symbol(symbol)\n        return int(symbol_obj.value().address) if symbol_obj else None\n    except gdb.error:\n        return None\n\n\n@pwndbg.lib.cache.cache_until(\"stop\", \"start\")\ndef selected_frame_source_absolute_filename():\n    \"\"\"\n    Retrieve the symbol table\u2019s source absolute file name from the selected frame.\n\n    In case of missing symbol table or frame information, None is returned.\n    \"\"\"\n    try:\n        frame = gdb.selected_frame()\n    except gdb.error:\n        return None\n\n    if not frame:\n        return None\n\n    sal = frame.find_sal()\n    if not sal:\n        return None\n\n    symtab = sal.symtab\n    if not symtab:\n        return None\n\n    return symtab.fullname()\n\n\ndef parse_and_eval(expression: str) -> gdb.Value | None:\n    \"\"\"Error handling wrapper for GDBs parse_and_eval function\"\"\"\n    try:\n        return gdb.parse_and_eval(expression)\n    except gdb.error:\n        return None\n", "path": "pwndbg/gdblib/symbol.py"}]}