TLDR: when context has been displayed the higlighted code is cached; if we change the pygmets style, displaying context again does not show the new style. This commit fixes this issue by resetting the memoized/cached highlighted code.

Verified

This commit was created on GitHub.com and signed with a verified signature using GitHub’s key.

Note that there is already Capstone 4.0.1 but it hasn't been released to
pypi yet.
The current `next.zip` points to Capstone 5.0 and currently breaks
pwndbg (due to bindings and capstone versions mismatch).

Verified

This commit was created on GitHub.com and signed with a verified signature using GitHub’s key.

* Fix tcache and support it on targets w/o -lpthread
Short summary:
* fixes tcache having wrong address
* adds heuristic to retrieve tcache address when binary is compiled w/o
-lpthread (may not work on glibc's other than 2.27)
* fixes `pwndbg.symbol.address` as it could return offsets instead of
an address
---
Long description below.
This commit fixes tcache: we used the address of &tcache instead of
tcache for dereferencing the struct. This can be observed with:
```
pwndbg> p *tcache
$8 = {
counts = '\000' <repeats 63 times>,
entries = {0x0 <repeats 64 times>}
}
pwndbg> tcache
{
counts = "\020`uUUU\000\000\000\000\000\000\000\000\000\000"...,
entries = {0x0, 0x0, 0x7ffff7fd7740, 0x7ffff7fd80a0, 0x7ffff7fd7740, 0x1, 0x0, 0x7025de0aec8a0300, 0x236a7550e4a6104e, 0x0 <repeats 55 times>}
}
```
It also adds possibility to retrieve tcache information from targets
that are compiled without -lpthread [-pthread].
**NOTE: This is experimental and may not work across different glibc
versions. It was tested on Ubuntu 18.04 on 2.27 glibc.**
This is because we get tcache pointer by making an assumption that it
will lie 0x10 bytes before one of the addresses that points to
&main_arena.
It also fixes `pwndbg.symbol.address`'s `info address` path when it
returned addresses that were out of memory maps due to the fact GDB may
return a string containing an offset instead of an address. E.g.:
```
pwndbg> info address tcache
Symbol "tcache" is a thread-local variable at offset 0x40 in the thread-local storage for `/lib/x86_64-linux-gnu/libc.so.6'.
```
* Fix tcache retrieval heuristic

Verified

This commit was created on GitHub.com and signed with a verified signature using GitHub’s key.

Fixes the issue caught by ecx86 in:
#500 (comment)
The commands broke when we debugged a remote target which was
hosted on a remote gdbserver (NOT a local one).
This is because we used `pwndbg.proc.exe` (changed in previous commit)
which is a local path to the binary which was then used to filter out
memory pages belonging to the binary.
To fix the issue, the AUXV's AT_EXECFN is used first which was used
before previous commit but the returned path is now normalized
(as in previous version it didn't work because if it returned path './a.out'
it couldn't match it with binary's Page.objfile which was e.g. '/blabla/a.out').

Verified

This commit was created on GitHub.com and signed with a verified signature using GitHub’s key.

Three things here:
1. This fixes `piebase` and `breakrva` commands - a bug with remote targets mentioned in #488 (comment).
2. It also adds a check if result address is still in the memory pages belonging to the given module. This works now as:
```
pwndbg> breakrva main
Offset 0x555555554601 rebased to module /home/dc/pwndbg_bug/a.out as 0xaaaaaaaa8601 is beyond module's memory pages:
0x555555554000 0x555555555000 r-xp 1000 0 /home/dc/pwndbg_bug/a.out
0x555555754000 0x555555755000 r--p 1000 0 /home/dc/pwndbg_bug/a.out
0x555555755000 0x555555756000 rw-p 1000 1000 /home/dc/pwndbg_bug/a.out
```
3. It gives a better output for `piebase`:
```
pwndbg> piebase 1
Calculated VA from /home/dc/pwndbg_bug/a.out = 0x555555554001
```
---
To reproduce the fixed bug, launch any binary on a gdbserver:
```
gdbserver 127.0.0.1:4444 ./a.out
```
Then start a debugging session:
```
gdb -q -ex 'target remote 127.0.0.1:4444' ./a.out
```
and fire e.g. `breakrva 123`.
---
Below you can see the bug case and explanation why it occured:
```
pwndbg> breakrva 1
There are no mappings for specified address or module.
'breakrva': Break at RVA from PIE base.
Traceback (most recent call last):
File "/home/dc/pwndbg/pwndbg/commands/__init__.py", line 109, in __call__
return self.function(*args, **kwargs)
File "/home/dc/pwndbg/pwndbg/commands/__init__.py", line 200, in _OnlyWhenRunning
return function(*a, **kw)
File "/home/dc/pwndbg/pwndbg/commands/pie.py", line 61, in breakrva
spec = "*%#x" % (addr)
TypeError: %x format: an integer is required, not NoneType
```
So what is the issue here?
1. We have the same logic in both `piebase` and `breakrva` - if the user doesn't specify second argument - a module name - we retrieve it with `get_exe_name`:
```python
def breakrva(offset=None, module=None):
offset = int(offset)
if not module:
module = get_exe_name()
addr = translate_addr(offset, module)
spec = "*%#x" % (addr)
# [ ... - some more code, not important here ]
```
2. The `get_exe_name` returns just `pwndbg.auxv.get().get('AT_EXECFN', pwndbg.proc.exe)`. The difference is important here. On the case shown above the `pwndbg.auxv.get()['AT_EXECFN']` returns `./a.out` while `pwndbg.proc.exe` returns the full path: `/home/dc/pwndbg_bug/a.out`.
3. This `module` is then passed to `translate_addr` as can be seen on the code above.
4. The `translate_addr` tries to retrieve memory page (`Page` instance) which belongs to the module:
```python
def translate_addr(offset, module):
mod_filter = lambda page: module in page.objfile
pages = list(filter(mod_filter, pwndbg.vmmap.get()))
if not pages:
print('There are no mappings for specified address or module.')
return
# [ ... - some more code, not important here ]
```
5. The `translate_addr` returns `None` because the `page.objfile` for e.g. binary objfile returns its full path as can be seen below:
```
(Pdb) pwndbg.vmmap.get()[0].objfile
'/home/dc/pwndbg_bug/a.out'
```
6. Because we returned `None`, the `spec = "*%#x" % (addr)` string formatting for breakrva or `print(hex(addr))` for piebase fails.

Verified

This commit was created on GitHub.com and signed with a verified signature using GitHub’s key.

* it would be cool to have tests that run within GDB so that we don't have to parse GDB output and deal with weird problems
* we can't run all tests in one GDB session as `file x; entry; <some pwndbg command>; file y; entry; <some wndbg command>;` may have different results - it seems either us or GDB fails to cleanup everything properly

Verified

This commit was created on GitHub.com and signed with a verified signature using GitHub’s key.

Before that change all shell commands had a description of `None`.
This was because we used string formatting for a docstring and if one
does so, the string isn't a docstring anymore.
This also fixes `r2` command description.

Verified

This commit was created on GitHub.com and signed with a verified signature using GitHub’s key.

* Fix before_prompt event on old GDB versions
This adds an `EventWrapper` class which behaves similar to gdb events but lets us:
* check whether event is a real gdb event or not
* call event callbacks if it is not a real gdb event
* Better comment

Verified

This commit was created on GitHub.com and signed with a verified signature using GitHub’s key.