Created
January 9, 2017 19:07
-
-
Save aclements/ad65da1167cc8b503b4ba3c8441dfce8 to your computer and use it in GitHub Desktop.
$getg() function for gdb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import gdb | |
_Gdead = 6 | |
class SliceValue: | |
"""Wrapper for slice values.""" | |
def __init__(self, val): | |
self.val = val | |
@property | |
def len(self): | |
return int(self.val['len']) | |
@property | |
def cap(self): | |
return int(self.val['cap']) | |
def __getitem__(self, i): | |
if i < 0 or i >= self.len: | |
raise IndexError(i) | |
ptr = self.val["array"] | |
return (ptr + i).dereference() | |
def getg(sp=None, n=None): | |
if sp is None and n is None: | |
sp = gdb.parse_and_eval('$sp') | |
found = [None] | |
def checkg(gp): | |
if gp == 0: | |
return | |
if gp['atomicstatus'] == _Gdead: | |
return | |
if sp != None and gp['stack']['lo'] < sp and sp <= gp['stack']['hi']: | |
if found[0] is not None: | |
raise gdb.GdbError('multiple Gs with overlapping stacks!') | |
found[0] = gp | |
if n != None and gp['goid'] == n: | |
if found[0] is not None: | |
raise gdb.GdbError('multiple Gs with same goid!') | |
found[0] = gp | |
# Check allgs. | |
for gp in SliceValue(gdb.parse_and_eval("'runtime.allgs'")): | |
checkg(gp) | |
# Check g0s and gsignals, which aren't on allgs. | |
if sp is not None: | |
mp = gdb.parse_and_eval("'runtime.allm'") | |
while mp != 0: | |
checkg(mp['g0']) | |
checkg(mp['gsignal']) | |
mp = mp['alllink'] | |
return found[0] | |
class GetG(gdb.Function): | |
"""Return the current *g.""" | |
def __init__(self): | |
super(GetG, self).__init__("getg") | |
def invoke(self, n=None): | |
g = getg(n=n) | |
if g is None: | |
raise gdb.GdbError('G not found') | |
return g | |
GetG() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment