'Examine a value in memory for its type and reference
Args:
- value: value to examine (Int)
Returns:
- tuple of (value(Int), type(String), next_value(Int))'

@memoized
def examine_mem_value(self, value):

    def examine_data(value, bits=32):
        out = self.execute_redirect(('x/%sx    0x%x' % (('g' if (bits == 64) else 'w'), value)))
        if out:
            v = out.split(': DCTB ')[(-1)].strip()
            if is_printable(int2hexstr(to_int(v), (bits // 8))):
                out = self.execute_redirect(('x/s    0x%x' % value))
        return out
    result = (None, None, None)
    if (value is None):
        return result
    maps = self.get_vmmap()
    binmap = self.get_vmmap('binary')
    (arch, bits) = self.getarch()
    if (not self.is_address(value)):
        result = (to_hex(value), 'value', '')
        return result
    else:
        (_, _, _, mapname) = self.get_vmrange(value)
    if self.is_writable(value):
        out = examine_data(value, bits)
        if out:
            result = (to_hex(value), 'data', out.split(':', 1)[1].strip())
    elif self.is_executable(value):
        if self.is_address(value, binmap):
            headers = self.elfheader()
        else:
            headers = self.elfheader_solib(mapname)
        if headers:
            headers = sorted(headers.items(), key=(lambda x: x[1][1]))
            for (k, (start, end, type)) in headers:
                if ((value >= start) and (value < end)):
                    if (type == 'code'):
                        out = self.get_disasm(value)
                        p = re.compile('.*?0x[^    ]*?\\s(.*)')
                        m = p.search(out)
                        result = (to_hex(value), 'code', m.group(1))
                    else:
                        out = examine_data(value, bits)
                        result = (to_hex(value), 'rodata', out.split(':', 1)[1].strip())
                    break
            if (result[0] is None):
                out = examine_data(value, bits)
                result = (to_hex(value), 'rodata', out.split(':', 1)[1].strip())
        else:
            out = self.get_disasm(value)
            if ('(bad)' in out):
                out = examine_data(value, bits)
                result = (to_hex(value), 'rodata', out.split(':', 1)[1].strip())
            else:
                p = re.compile('.*?0x[^    ]*?\\s(.*)')
                m = p.search(out)
                result = (to_hex(value), 'code', m.group(1))
    else:
        out = examine_data(value, bits)
        if out:
            result = (to_hex(value), 'rodata', out.split(':', 1)[1].strip())
        else:
            result = (to_hex(value), 'rodata', 'MemError')
    return result
