Update tracy to v0.9
This commit is contained in:
@@ -53,13 +53,14 @@ struct backtrace_state;
|
||||
invalid after this function returns.
|
||||
|
||||
As a special case, the ERRNUM argument will be passed as -1 if no
|
||||
debug info can be found for the executable, but the function
|
||||
requires debug info (e.g., backtrace_full, backtrace_pcinfo). The
|
||||
MSG in this case will be something along the lines of "no debug
|
||||
info". Similarly, ERRNUM will be passed as -1 if there is no
|
||||
symbol table, but the function requires a symbol table (e.g.,
|
||||
backtrace_syminfo). This may be used as a signal that some other
|
||||
approach should be tried. */
|
||||
debug info can be found for the executable, or if the debug info
|
||||
exists but has an unsupported version, but the function requires
|
||||
debug info (e.g., backtrace_full, backtrace_pcinfo). The MSG in
|
||||
this case will be something along the lines of "no debug info".
|
||||
Similarly, ERRNUM will be passed as -1 if there is no symbol table,
|
||||
but the function requires a symbol table (e.g., backtrace_syminfo).
|
||||
This may be used as a signal that some other approach should be
|
||||
tried. */
|
||||
|
||||
typedef void (*backtrace_error_callback) (void *data, const char *msg,
|
||||
int errnum);
|
||||
|
||||
152
Source/ThirdParty/tracy/libbacktrace/dwarf.cpp
vendored
152
Source/ThirdParty/tracy/libbacktrace/dwarf.cpp
vendored
@@ -52,6 +52,7 @@ enum dwarf_tag {
|
||||
DW_TAG_compile_unit = 0x11,
|
||||
DW_TAG_inlined_subroutine = 0x1d,
|
||||
DW_TAG_subprogram = 0x2e,
|
||||
DW_TAG_skeleton_unit = 0x4a,
|
||||
};
|
||||
|
||||
enum dwarf_form {
|
||||
@@ -746,13 +747,13 @@ struct dwarf_data
|
||||
/* Report an error for a DWARF buffer. */
|
||||
|
||||
static void
|
||||
dwarf_buf_error (struct dwarf_buf *buf, const char *msg)
|
||||
dwarf_buf_error (struct dwarf_buf *buf, const char *msg, int errnum)
|
||||
{
|
||||
char b[200];
|
||||
|
||||
snprintf (b, sizeof b, "%s in %s at %d",
|
||||
msg, buf->name, (int) (buf->buf - buf->start));
|
||||
buf->error_callback (buf->data, b, 0);
|
||||
buf->error_callback (buf->data, b, errnum);
|
||||
}
|
||||
|
||||
/* Require at least COUNT bytes in BUF. Return 1 if all is well, 0 on
|
||||
@@ -766,7 +767,7 @@ require (struct dwarf_buf *buf, size_t count)
|
||||
|
||||
if (!buf->reported_underflow)
|
||||
{
|
||||
dwarf_buf_error (buf, "DWARF underflow");
|
||||
dwarf_buf_error (buf, "DWARF underflow", 0);
|
||||
buf->reported_underflow = 1;
|
||||
}
|
||||
|
||||
@@ -928,7 +929,7 @@ read_address (struct dwarf_buf *buf, int addrsize)
|
||||
case 8:
|
||||
return read_uint64 (buf);
|
||||
default:
|
||||
dwarf_buf_error (buf, "unrecognized address size");
|
||||
dwarf_buf_error (buf, "unrecognized address size", 0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -979,7 +980,7 @@ read_uleb128 (struct dwarf_buf *buf)
|
||||
ret |= ((uint64_t) (b & 0x7f)) << shift;
|
||||
else if (!overflow)
|
||||
{
|
||||
dwarf_buf_error (buf, "LEB128 overflows uint64_t");
|
||||
dwarf_buf_error (buf, "LEB128 overflows uint64_t", 0);
|
||||
overflow = 1;
|
||||
}
|
||||
shift += 7;
|
||||
@@ -1014,7 +1015,7 @@ read_sleb128 (struct dwarf_buf *buf)
|
||||
val |= ((uint64_t) (b & 0x7f)) << shift;
|
||||
else if (!overflow)
|
||||
{
|
||||
dwarf_buf_error (buf, "signed LEB128 overflows uint64_t");
|
||||
dwarf_buf_error (buf, "signed LEB128 overflows uint64_t", 0);
|
||||
overflow = 1;
|
||||
}
|
||||
shift += 7;
|
||||
@@ -1154,7 +1155,7 @@ read_attribute (enum dwarf_form form, uint64_t implicit_val,
|
||||
offset = read_offset (buf, is_dwarf64);
|
||||
if (offset >= dwarf_sections->size[DEBUG_STR])
|
||||
{
|
||||
dwarf_buf_error (buf, "DW_FORM_strp out of range");
|
||||
dwarf_buf_error (buf, "DW_FORM_strp out of range", 0);
|
||||
return 0;
|
||||
}
|
||||
val->encoding = ATTR_VAL_STRING;
|
||||
@@ -1169,7 +1170,7 @@ read_attribute (enum dwarf_form form, uint64_t implicit_val,
|
||||
offset = read_offset (buf, is_dwarf64);
|
||||
if (offset >= dwarf_sections->size[DEBUG_LINE_STR])
|
||||
{
|
||||
dwarf_buf_error (buf, "DW_FORM_line_strp out of range");
|
||||
dwarf_buf_error (buf, "DW_FORM_line_strp out of range", 0);
|
||||
return 0;
|
||||
}
|
||||
val->encoding = ATTR_VAL_STRING;
|
||||
@@ -1216,7 +1217,8 @@ read_attribute (enum dwarf_form form, uint64_t implicit_val,
|
||||
if (form == DW_FORM_implicit_const)
|
||||
{
|
||||
dwarf_buf_error (buf,
|
||||
"DW_FORM_indirect to DW_FORM_implicit_const");
|
||||
"DW_FORM_indirect to DW_FORM_implicit_const",
|
||||
0);
|
||||
return 0;
|
||||
}
|
||||
return read_attribute ((enum dwarf_form) form, 0, buf, is_dwarf64,
|
||||
@@ -1349,7 +1351,7 @@ read_attribute (enum dwarf_form form, uint64_t implicit_val,
|
||||
}
|
||||
if (offset >= altlink->dwarf_sections.size[DEBUG_STR])
|
||||
{
|
||||
dwarf_buf_error (buf, "DW_FORM_strp_sup out of range");
|
||||
dwarf_buf_error (buf, "DW_FORM_strp_sup out of range", 0);
|
||||
return 0;
|
||||
}
|
||||
val->encoding = ATTR_VAL_STRING;
|
||||
@@ -1358,7 +1360,7 @@ read_attribute (enum dwarf_form form, uint64_t implicit_val,
|
||||
return 1;
|
||||
}
|
||||
default:
|
||||
dwarf_buf_error (buf, "unrecognized DWARF form");
|
||||
dwarf_buf_error (buf, "unrecognized DWARF form", -1);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1407,7 +1409,9 @@ resolve_string (const struct dwarf_sections *dwarf_sections, int is_dwarf64,
|
||||
offset = read_offset (&offset_buf, is_dwarf64);
|
||||
if (offset >= dwarf_sections->size[DEBUG_STR])
|
||||
{
|
||||
dwarf_buf_error (&offset_buf, "DW_FORM_strx offset out of range");
|
||||
dwarf_buf_error (&offset_buf,
|
||||
"DW_FORM_strx offset out of range",
|
||||
0);
|
||||
return 0;
|
||||
}
|
||||
*string = (const char *) dwarf_sections->data[DEBUG_STR] + offset;
|
||||
@@ -2215,7 +2219,7 @@ add_ranges_from_rnglists (
|
||||
break;
|
||||
|
||||
default:
|
||||
dwarf_buf_error (&rnglists_buf, "unrecognized DW_RLE value");
|
||||
dwarf_buf_error (&rnglists_buf, "unrecognized DW_RLE value", -1);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -2322,14 +2326,16 @@ find_address_ranges (struct backtrace_state *state, uintptr_t base_address,
|
||||
break;
|
||||
|
||||
case DW_AT_stmt_list:
|
||||
if (abbrev->tag == DW_TAG_compile_unit
|
||||
if ((abbrev->tag == DW_TAG_compile_unit
|
||||
|| abbrev->tag == DW_TAG_skeleton_unit)
|
||||
&& (val.encoding == ATTR_VAL_UINT
|
||||
|| val.encoding == ATTR_VAL_REF_SECTION))
|
||||
u->lineoff = val.u.uint;
|
||||
break;
|
||||
|
||||
case DW_AT_name:
|
||||
if (abbrev->tag == DW_TAG_compile_unit)
|
||||
if (abbrev->tag == DW_TAG_compile_unit
|
||||
|| abbrev->tag == DW_TAG_skeleton_unit)
|
||||
{
|
||||
name_val = val;
|
||||
have_name_val = 1;
|
||||
@@ -2337,7 +2343,8 @@ find_address_ranges (struct backtrace_state *state, uintptr_t base_address,
|
||||
break;
|
||||
|
||||
case DW_AT_comp_dir:
|
||||
if (abbrev->tag == DW_TAG_compile_unit)
|
||||
if (abbrev->tag == DW_TAG_compile_unit
|
||||
|| abbrev->tag == DW_TAG_skeleton_unit)
|
||||
{
|
||||
comp_dir_val = val;
|
||||
have_comp_dir_val = 1;
|
||||
@@ -2345,19 +2352,22 @@ find_address_ranges (struct backtrace_state *state, uintptr_t base_address,
|
||||
break;
|
||||
|
||||
case DW_AT_str_offsets_base:
|
||||
if (abbrev->tag == DW_TAG_compile_unit
|
||||
if ((abbrev->tag == DW_TAG_compile_unit
|
||||
|| abbrev->tag == DW_TAG_skeleton_unit)
|
||||
&& val.encoding == ATTR_VAL_REF_SECTION)
|
||||
u->str_offsets_base = val.u.uint;
|
||||
break;
|
||||
|
||||
case DW_AT_addr_base:
|
||||
if (abbrev->tag == DW_TAG_compile_unit
|
||||
if ((abbrev->tag == DW_TAG_compile_unit
|
||||
|| abbrev->tag == DW_TAG_skeleton_unit)
|
||||
&& val.encoding == ATTR_VAL_REF_SECTION)
|
||||
u->addr_base = val.u.uint;
|
||||
break;
|
||||
|
||||
case DW_AT_rnglists_base:
|
||||
if (abbrev->tag == DW_TAG_compile_unit
|
||||
if ((abbrev->tag == DW_TAG_compile_unit
|
||||
|| abbrev->tag == DW_TAG_skeleton_unit)
|
||||
&& val.encoding == ATTR_VAL_REF_SECTION)
|
||||
u->rnglists_base = val.u.uint;
|
||||
break;
|
||||
@@ -2385,7 +2395,8 @@ find_address_ranges (struct backtrace_state *state, uintptr_t base_address,
|
||||
}
|
||||
|
||||
if (abbrev->tag == DW_TAG_compile_unit
|
||||
|| abbrev->tag == DW_TAG_subprogram)
|
||||
|| abbrev->tag == DW_TAG_subprogram
|
||||
|| abbrev->tag == DW_TAG_skeleton_unit)
|
||||
{
|
||||
if (!add_ranges (state, dwarf_sections, base_address,
|
||||
is_bigendian, u, pcrange.lowpc, &pcrange,
|
||||
@@ -2393,9 +2404,10 @@ find_address_ranges (struct backtrace_state *state, uintptr_t base_address,
|
||||
(void *) addrs))
|
||||
return 0;
|
||||
|
||||
/* If we found the PC range in the DW_TAG_compile_unit, we
|
||||
can stop now. */
|
||||
if (abbrev->tag == DW_TAG_compile_unit
|
||||
/* If we found the PC range in the DW_TAG_compile_unit or
|
||||
DW_TAG_skeleton_unit, we can stop now. */
|
||||
if ((abbrev->tag == DW_TAG_compile_unit
|
||||
|| abbrev->tag == DW_TAG_skeleton_unit)
|
||||
&& (pcrange.have_ranges
|
||||
|| (pcrange.have_lowpc && pcrange.have_highpc)))
|
||||
return 1;
|
||||
@@ -2482,7 +2494,7 @@ build_address_map (struct backtrace_state *state, uintptr_t base_address,
|
||||
version = read_uint16 (&unit_buf);
|
||||
if (version < 2 || version > 5)
|
||||
{
|
||||
dwarf_buf_error (&unit_buf, "unrecognized DWARF version");
|
||||
dwarf_buf_error (&unit_buf, "unrecognized DWARF version", -1);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -2554,6 +2566,9 @@ build_address_map (struct backtrace_state *state, uintptr_t base_address,
|
||||
u->comp_dir = NULL;
|
||||
u->abs_filename = NULL;
|
||||
u->lineoff = 0;
|
||||
u->str_offsets_base = 0;
|
||||
u->addr_base = 0;
|
||||
u->rnglists_base = 0;
|
||||
|
||||
/* The actual line number mappings will be read as needed. */
|
||||
u->lines = NULL;
|
||||
@@ -2761,7 +2776,8 @@ read_v2_paths (struct backtrace_state *state, struct unit *u,
|
||||
{
|
||||
dwarf_buf_error (hdr_buf,
|
||||
("invalid directory index in "
|
||||
"line number program header"));
|
||||
"line number program header"),
|
||||
0);
|
||||
return 0;
|
||||
}
|
||||
dir_len = strlen (dir);
|
||||
@@ -2830,7 +2846,8 @@ read_lnct (struct backtrace_state *state, struct dwarf_data *ddata,
|
||||
{
|
||||
dwarf_buf_error (hdr_buf,
|
||||
("invalid directory index in "
|
||||
"line number program header"));
|
||||
"line number program header"),
|
||||
0);
|
||||
return 0;
|
||||
}
|
||||
dir = hdr->dirs[val.u.uint];
|
||||
@@ -2845,7 +2862,8 @@ read_lnct (struct backtrace_state *state, struct dwarf_data *ddata,
|
||||
if (path == NULL)
|
||||
{
|
||||
dwarf_buf_error (hdr_buf,
|
||||
"missing file name in line number program header");
|
||||
"missing file name in line number program header",
|
||||
0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2972,7 +2990,7 @@ read_line_header (struct backtrace_state *state, struct dwarf_data *ddata,
|
||||
hdr->version = read_uint16 (line_buf);
|
||||
if (hdr->version < 2 || hdr->version > 5)
|
||||
{
|
||||
dwarf_buf_error (line_buf, "unsupported line number version");
|
||||
dwarf_buf_error (line_buf, "unsupported line number version", -1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2986,7 +3004,8 @@ read_line_header (struct backtrace_state *state, struct dwarf_data *ddata,
|
||||
if (read_byte (line_buf) != 0)
|
||||
{
|
||||
dwarf_buf_error (line_buf,
|
||||
"non-zero segment_selector_size not supported");
|
||||
"non-zero segment_selector_size not supported",
|
||||
-1);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -3127,7 +3146,8 @@ read_line_program (struct backtrace_state *state, struct dwarf_data *ddata,
|
||||
{
|
||||
dwarf_buf_error (line_buf,
|
||||
("invalid directory index "
|
||||
"in line number program"));
|
||||
"in line number program"),
|
||||
0);
|
||||
return 0;
|
||||
}
|
||||
dir_len = strlen (dir);
|
||||
@@ -3185,19 +3205,15 @@ read_line_program (struct backtrace_state *state, struct dwarf_data *ddata,
|
||||
uint64_t fileno;
|
||||
|
||||
fileno = read_uleb128 (line_buf);
|
||||
if (fileno == 0)
|
||||
filename = "";
|
||||
else
|
||||
if (fileno >= hdr->filenames_count)
|
||||
{
|
||||
if (fileno >= hdr->filenames_count)
|
||||
{
|
||||
dwarf_buf_error (line_buf,
|
||||
("invalid file number in "
|
||||
"line number program"));
|
||||
return 0;
|
||||
}
|
||||
filename = hdr->filenames[fileno];
|
||||
dwarf_buf_error (line_buf,
|
||||
("invalid file number in "
|
||||
"line number program"),
|
||||
0);
|
||||
return 0;
|
||||
}
|
||||
filename = hdr->filenames[fileno];
|
||||
}
|
||||
break;
|
||||
case DW_LNS_set_column:
|
||||
@@ -3428,7 +3444,9 @@ read_referenced_name (struct dwarf_data *ddata, struct unit *u,
|
||||
code = read_uleb128 (&unit_buf);
|
||||
if (code == 0)
|
||||
{
|
||||
dwarf_buf_error (&unit_buf, "invalid abstract origin or specification");
|
||||
dwarf_buf_error (&unit_buf,
|
||||
"invalid abstract origin or specification",
|
||||
0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -3601,7 +3619,8 @@ read_function_entry (struct backtrace_state *state, struct dwarf_data *ddata,
|
||||
|
||||
/* The compile unit sets the base address for any address
|
||||
ranges in the function entries. */
|
||||
if (abbrev->tag == DW_TAG_compile_unit
|
||||
if ((abbrev->tag == DW_TAG_compile_unit
|
||||
|| abbrev->tag == DW_TAG_skeleton_unit)
|
||||
&& abbrev->attrs[i].name == DW_AT_low_pc)
|
||||
{
|
||||
if (val.encoding == ATTR_VAL_ADDRESS)
|
||||
@@ -3623,20 +3642,15 @@ read_function_entry (struct backtrace_state *state, struct dwarf_data *ddata,
|
||||
case DW_AT_call_file:
|
||||
if (val.encoding == ATTR_VAL_UINT)
|
||||
{
|
||||
if (val.u.uint == 0)
|
||||
function->caller_filename = "";
|
||||
else
|
||||
if (val.u.uint >= lhdr->filenames_count)
|
||||
{
|
||||
if (val.u.uint >= lhdr->filenames_count)
|
||||
{
|
||||
dwarf_buf_error (unit_buf,
|
||||
("invalid file number in "
|
||||
"DW_AT_call_file attribute"));
|
||||
return 0;
|
||||
}
|
||||
function->caller_filename =
|
||||
lhdr->filenames[val.u.uint];
|
||||
dwarf_buf_error (unit_buf,
|
||||
("invalid file number in "
|
||||
"DW_AT_call_file attribute"),
|
||||
0);
|
||||
return 0;
|
||||
}
|
||||
function->caller_filename = lhdr->filenames[val.u.uint];
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -3884,7 +3898,7 @@ read_function_info (struct backtrace_state *state, struct dwarf_data *ddata,
|
||||
Returns whatever CALLBACK returns, or 0 to keep going. */
|
||||
|
||||
static int
|
||||
report_inlined_functions (uintptr_t pc, struct function *function,
|
||||
report_inlined_functions (uintptr_t pc, struct function *function, const char* comp_dir,
|
||||
backtrace_full_callback callback, void *data,
|
||||
const char **filename, int *lineno)
|
||||
{
|
||||
@@ -3938,13 +3952,22 @@ report_inlined_functions (uintptr_t pc, struct function *function,
|
||||
inlined = match->function;
|
||||
|
||||
/* Report any calls inlined into this one. */
|
||||
ret = report_inlined_functions (pc, inlined, callback, data,
|
||||
ret = report_inlined_functions (pc, inlined, comp_dir, callback, data,
|
||||
filename, lineno);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
/* Report this inlined call. */
|
||||
ret = callback (data, pc, match->low, *filename, *lineno, inlined->name);
|
||||
if (*filename[0] != '/' && comp_dir)
|
||||
{
|
||||
char buf[1024];
|
||||
snprintf (buf, 1024, "%s/%s", comp_dir, *filename);
|
||||
ret = callback (data, pc, match->low, buf, *lineno, inlined->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = callback (data, pc, match->low, *filename, *lineno, inlined->name);
|
||||
}
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
@@ -4211,12 +4234,21 @@ dwarf_lookup_pc (struct backtrace_state *state, struct dwarf_data *ddata,
|
||||
filename = ln->filename;
|
||||
lineno = ln->lineno;
|
||||
|
||||
ret = report_inlined_functions (pc, function, callback, data,
|
||||
ret = report_inlined_functions (pc, function, entry->u->comp_dir, callback, data,
|
||||
&filename, &lineno);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
return callback (data, pc, fmatch->low, filename, lineno, function->name);
|
||||
if (filename[0] != '/' && entry->u->comp_dir)
|
||||
{
|
||||
char buf[1024];
|
||||
snprintf (buf, 1024, "%s/%s", entry->u->comp_dir, filename);
|
||||
return callback (data, pc, fmatch->low, buf, lineno, function->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
return callback (data, pc, fmatch->low, filename, lineno, function->name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
54
Source/ThirdParty/tracy/libbacktrace/elf.cpp
vendored
54
Source/ThirdParty/tracy/libbacktrace/elf.cpp
vendored
@@ -46,6 +46,9 @@ POSSIBILITY OF SUCH DAMAGE. */
|
||||
#include "backtrace.hpp"
|
||||
#include "internal.hpp"
|
||||
|
||||
#include "../client/TracyFastVector.hpp"
|
||||
#include "../common/TracyAlloc.hpp"
|
||||
|
||||
#ifndef S_ISLNK
|
||||
#ifndef S_IFLNK
|
||||
#define S_IFLNK 0120000
|
||||
@@ -70,6 +73,10 @@ POSSIBILITY OF SUCH DAMAGE. */
|
||||
namespace tracy
|
||||
{
|
||||
|
||||
#ifdef TRACY_DEBUGINFOD
|
||||
int GetDebugInfoDescriptor( const char* buildid_data, size_t buildid_size );
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_DECL_STRNLEN) || !HAVE_DECL_STRNLEN
|
||||
|
||||
/* If strnlen is not declared, provide our own version. */
|
||||
@@ -867,6 +874,7 @@ elf_readlink (struct backtrace_state *state, const char *filename,
|
||||
static int
|
||||
elf_open_debugfile_by_buildid (struct backtrace_state *state,
|
||||
const char *buildid_data, size_t buildid_size,
|
||||
const char *filename,
|
||||
backtrace_error_callback error_callback,
|
||||
void *data)
|
||||
{
|
||||
@@ -913,7 +921,14 @@ elf_open_debugfile_by_buildid (struct backtrace_state *state,
|
||||
That seems kind of pointless to me--why would it have the right
|
||||
name but not the right build ID?--so skipping the check. */
|
||||
|
||||
#ifdef TRACY_DEBUGINFOD
|
||||
if (ret == -1)
|
||||
return GetDebugInfoDescriptor( buildid_data, buildid_size, filename );
|
||||
else
|
||||
return ret;
|
||||
#else
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Try to open a file whose name is PREFIX (length PREFIX_LEN)
|
||||
@@ -1803,7 +1818,7 @@ elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table,
|
||||
/* An uncompressed block. */
|
||||
|
||||
/* If we've read ahead more than a byte, back up. */
|
||||
while (bits > 8)
|
||||
while (bits >= 8)
|
||||
{
|
||||
--pin;
|
||||
bits -= 8;
|
||||
@@ -4429,7 +4444,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
|
||||
int d;
|
||||
|
||||
d = elf_open_debugfile_by_buildid (state, buildid_data, buildid_size,
|
||||
error_callback, data);
|
||||
filename, error_callback, data);
|
||||
if (d >= 0)
|
||||
{
|
||||
int ret;
|
||||
@@ -4812,12 +4827,34 @@ struct phdr_data
|
||||
/* Callback passed to dl_iterate_phdr. Load debug info from shared
|
||||
libraries. */
|
||||
|
||||
struct PhdrIterate
|
||||
{
|
||||
char* dlpi_name;
|
||||
ElfW(Addr) dlpi_addr;
|
||||
};
|
||||
FastVector<PhdrIterate> s_phdrData(16);
|
||||
|
||||
static int
|
||||
phdr_callback_mock (struct dl_phdr_info *info, size_t size ATTRIBUTE_UNUSED,
|
||||
void *pdata)
|
||||
{
|
||||
auto ptr = s_phdrData.push_next();
|
||||
if (info->dlpi_name)
|
||||
{
|
||||
size_t sz = strlen (info->dlpi_name) + 1;
|
||||
ptr->dlpi_name = (char*)tracy_malloc (sz);
|
||||
memcpy (ptr->dlpi_name, info->dlpi_name, sz);
|
||||
}
|
||||
else ptr->dlpi_name = nullptr;
|
||||
ptr->dlpi_addr = info->dlpi_addr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
#ifdef __i386__
|
||||
__attribute__ ((__force_align_arg_pointer__))
|
||||
#endif
|
||||
phdr_callback (struct dl_phdr_info *info, size_t size ATTRIBUTE_UNUSED,
|
||||
void *pdata)
|
||||
phdr_callback (struct PhdrIterate *info, void *pdata)
|
||||
{
|
||||
struct phdr_data *pd = (struct phdr_data *) pdata;
|
||||
const char *filename;
|
||||
@@ -4896,7 +4933,14 @@ backtrace_initialize (struct backtrace_state *state, const char *filename,
|
||||
pd.exe_filename = filename;
|
||||
pd.exe_descriptor = ret < 0 ? descriptor : -1;
|
||||
|
||||
dl_iterate_phdr (phdr_callback, (void *) &pd);
|
||||
assert (s_phdrData.empty());
|
||||
dl_iterate_phdr (phdr_callback_mock, nullptr);
|
||||
for (auto& v : s_phdrData)
|
||||
{
|
||||
phdr_callback (&v, (void *) &pd);
|
||||
tracy_free (v.dlpi_name);
|
||||
}
|
||||
s_phdrData.clear();
|
||||
|
||||
if (!state->threaded)
|
||||
{
|
||||
|
||||
@@ -1271,7 +1271,7 @@ backtrace_initialize (struct backtrace_state *state, const char *filename,
|
||||
mff = macho_nodebug;
|
||||
if (!macho_add (state, name, d, 0, NULL, base_address, 0,
|
||||
error_callback, data, &mff, &mfs))
|
||||
return 0;
|
||||
continue;
|
||||
|
||||
if (mff != macho_nodebug)
|
||||
macho_fileline_fn = mff;
|
||||
@@ -1292,7 +1292,7 @@ backtrace_initialize (struct backtrace_state *state, const char *filename,
|
||||
else
|
||||
{
|
||||
if (found_sym)
|
||||
backtrace_atomic_store_pointer (&state->syminfo_fn, macho_syminfo);
|
||||
backtrace_atomic_store_pointer (&state->syminfo_fn, &macho_syminfo);
|
||||
else
|
||||
(void) __sync_bool_compare_and_swap (&state->syminfo_fn, NULL,
|
||||
macho_nosyms);
|
||||
@@ -1338,7 +1338,7 @@ backtrace_initialize (struct backtrace_state *state, const char *filename,
|
||||
else
|
||||
{
|
||||
if (found_sym)
|
||||
backtrace_atomic_store_pointer (&state->syminfo_fn, macho_syminfo);
|
||||
backtrace_atomic_store_pointer (&state->syminfo_fn, &macho_syminfo);
|
||||
else
|
||||
(void) __sync_bool_compare_and_swap (&state->syminfo_fn, NULL,
|
||||
macho_nosyms);
|
||||
|
||||
Reference in New Issue
Block a user