*/
#include "pub_tool_basics.h"
-#include "pub_tool_vki.h"
#include "pub_tool_debuginfo.h"
#include "pub_tool_libcbase.h"
#include "pub_tool_libcassert.h"
#include "pub_tool_libcfile.h"
#include "pub_tool_libcprint.h"
#include "pub_tool_libcproc.h"
-#include "pub_tool_machine.h"
#include "pub_tool_mallocfree.h"
#include "pub_tool_options.h"
#include "pub_tool_oset.h"
/* Set to 1 for very verbose debugging */
#define DEBUG_CG 0
-#define FILE_LEN VKI_PATH_MAX
-
/*------------------------------------------------------------*/
/*--- Options ---*/
/*------------------------------------------------------------*/
/*--- CC table operations ---*/
/*------------------------------------------------------------*/
-static void get_debug_info(Addr instr_addr, HChar dir[FILE_LEN],
- HChar file[FILE_LEN],
- const HChar **fn, UInt* line)
+static void get_debug_info(Addr instr_addr, const HChar **dir,
+ const HChar **file, const HChar **fn, UInt* line)
{
Bool found_dirname;
Bool found_file_line = VG_(get_filename_linenum)(
instr_addr,
- file, FILE_LEN,
- dir, FILE_LEN, &found_dirname,
+ file, dir, &found_dirname,
line
);
Bool found_fn = VG_(get_fnname)(instr_addr, fn);
if (!found_file_line) {
- VG_(strcpy)(file, "???");
+ *file = "???";
*line = 0;
}
if (!found_fn) {
// Returns a pointer to the line CC, creates a new one if necessary.
static LineCC* get_lineCC(Addr origAddr)
{
- HChar file[FILE_LEN], dir[FILE_LEN];
- const HChar *fn;
+ const HChar *fn, *file, *dir;
UInt line;
CodeLoc loc;
LineCC* lineCC;
- get_debug_info(origAddr, dir, file, &fn, &line);
+ get_debug_info(origAddr, &dir, &file, &fn, &line);
// Form an absolute pathname if a directory is available
HChar absfile[VG_(strlen)(dir) + 1 + VG_(strlen)(file) + 1];
/* dump out an address with source info if available */
void CLG_(print_addr)(Addr addr)
{
- HChar fl_buf[FILENAME_LEN];
- HChar dir_buf[FILENAME_LEN];
- const HChar *fn_buf;
+ const HChar *fn_buf, *fl_buf, *dir_buf;
const HChar* obj_name;
DebugInfo* di;
UInt ln, i=0, opos=0;
return;
}
- CLG_(get_debug_info)(addr, dir_buf, fl_buf, &fn_buf, &ln, &di);
+ CLG_(get_debug_info)(addr, &dir_buf, &fl_buf, &fn_buf, &ln, &di);
if (VG_(strcmp)(fn_buf,"???")==0)
VG_(printf)("%#lx", addr);
static /* __inline__ */
Bool get_debug_pos(BBCC* bbcc, Addr addr, AddrPos* p)
{
- HChar file[FILENAME_LEN];
- HChar dir[FILENAME_LEN];
+ const HChar *file, *dir;
Bool found_file_line, found_dirname;
int cachepos = addr % DEBUG_CACHE_SIZE;
}
else {
found_file_line = VG_(get_filename_linenum)(addr,
- file, FILENAME_LEN,
- dir, FILENAME_LEN,
+ &file,
+ &dir,
&found_dirname,
&(p->line));
if (!found_file_line) {
- VG_(strcpy)(file, "???");
+ file = "???";
p->line = 0;
}
p->file = CLG_(get_file_node)(bbcc->bb->obj, dir, file);
Bool CLG_(get_debug_info)(Addr instr_addr,
- HChar dir[FILENAME_LEN],
- HChar file[FILENAME_LEN],
+ const HChar **dir,
+ const HChar **file,
const HChar **fn_name, UInt* line_num,
DebugInfo** pDebugInfo)
{
}
found_file_line = VG_(get_filename_linenum)(instr_addr,
- file, FILENAME_LEN,
- dir, FILENAME_LEN,
+ file,
+ dir,
&found_dirname,
&line);
found_fn = VG_(get_fnname)(instr_addr, fn_name);
if (!found_file_line && !found_fn) {
CLG_(stat).no_debug_BBs++;
- VG_(strcpy)(file, "???");
+ *file = "???";
*fn_name = "???";
if (line_num) *line_num=0;
result = False;
} else /*(!found_file_line && found_fn)*/ {
CLG_(stat).fn_name_debug_BBs++;
- VG_(strcpy)(file, "???");
+ *file = "???";
if (line_num) *line_num=0;
}
*/
fn_node* CLG_(get_fn_node)(BB* bb)
{
- HChar filename[FILENAME_LEN];
- HChar dirname[FILENAME_LEN];
- const HChar *fnname;
+ const HChar *fnname, *filename, *dirname;
DebugInfo* di;
UInt line_num;
fn_node* fn;
* the BB according to debug information
*/
CLG_(get_debug_info)(bb_addr(bb),
- dirname, filename, &fnname, &line_num, &di);
+ &dirname, &filename, &fnname, &line_num, &di);
if (0 == VG_(strcmp)(fnname, "???")) {
int p;
if (0 == VG_(strcmp)(fnname, "vgPlain___libc_freeres_wrapper")
&& exit_bb) {
CLG_(get_debug_info)(bb_addr(exit_bb),
- dirname, filename, &fnname, &line_num, &di);
+ &dirname, &filename, &fnname, &line_num, &di);
CLG_DEBUG(1, "__libc_freeres_wrapper renamed to _exit\n");
}
void CLG_(init_eventsets)(void);
/* from main.c */
-Bool CLG_(get_debug_info)(Addr, HChar dirname[FILENAME_LEN],
- HChar filename[FILENAME_LEN],
+Bool CLG_(get_debug_info)(Addr, const HChar **dirname,
+ const HChar **filename,
const HChar **fn_name, UInt*, DebugInfo**);
void CLG_(collectBlockInfo)(IRSB* bbIn, UInt*, UInt*, Bool*);
void CLG_(set_instrument_state)(const HChar*,Bool);
tnr_else_tid (ai->Addr.Stack.tinfo),
xpost );
if (ai->Addr.Stack.frameNo != -1 && ai->Addr.Stack.IP != 0) {
-#define FLEN 256
const HChar *fn;
Bool hasfn;
- HChar file[FLEN];
+ const HChar *file;
Bool hasfile;
UInt linenum;
Bool haslinenum;
else
haslinenum = False;
- hasfile = VG_(get_filename)(ai->Addr.Stack.IP, file, FLEN);
- if (hasfile && haslinenum) {
- HChar strlinenum[10];
- VG_(snprintf) (strlinenum, 10, ":%d", linenum);
- VG_(strncat) (file, strlinenum,
- FLEN - VG_(strlen)(file) - 1);
- }
+ hasfile = VG_(get_filename)(ai->Addr.Stack.IP, &file);
+
+ HChar strlinenum[16] = ""; // large enough
+ if (hasfile && haslinenum)
+ VG_(sprintf)(strlinenum, "%d", linenum);
hasfn = VG_(get_fnname)(ai->Addr.Stack.IP, &fn);
if (hasfn || hasfile)
- VG_(emit)( "%sin frame #%d, created by %s (%s)%s\n",
+ VG_(emit)( "%sin frame #%d, created by %s (%s:%s)%s\n",
xpre,
ai->Addr.Stack.frameNo,
hasfn ? fn : "???",
- hasfile ? file : "???",
+ hasfile ? file : "???", strlinenum,
xpost );
-#undef FLEN
}
switch (ai->Addr.Stack.stackPos) {
case StackPos_stacked: break; // nothing more to say
return NULL;
}
-/* Map a code address to a filename. Returns True if successful. */
-Bool VG_(get_filename)( Addr a, HChar* filename, Int n_filename )
+/* Map a code address to a filename. Returns True if successful. The
+ returned string is persistent as long as the DebugInfo to which it
+ belongs is not discarded. */
+Bool VG_(get_filename)( Addr a, const HChar** filename )
{
DebugInfo* si;
Word locno;
if (si == NULL)
return False;
fndn_ix = ML_(fndn_ix) (si, locno);
- VG_(strncpy_safely)(filename,
- ML_(fndn_ix2filename) (si, fndn_ix),
- n_filename);
+ *filename = ML_(fndn_ix2filename) (si, fndn_ix);
return True;
}
See prototype for detailed description of behaviour.
*/
Bool VG_(get_filename_linenum) ( Addr a,
- /*OUT*/HChar* filename, Int n_filename,
- /*OUT*/HChar* dirname, Int n_dirname,
+ /*OUT*/const HChar** filename,
+ /*OUT*/const HChar** dirname,
/*OUT*/Bool* dirname_available,
/*OUT*/UInt* lineno )
{
if (si == NULL) {
if (dirname_available) {
*dirname_available = False;
- *dirname = 0;
+ *dirname = "";
}
+ *filename = ""; // this used to be not initialised....
return False;
}
fndn_ix = ML_(fndn_ix)(si, locno);
- VG_(strncpy_safely)(filename,
- ML_(fndn_ix2filename) (si, fndn_ix),
- n_filename);
+ *filename = ML_(fndn_ix2filename) (si, fndn_ix);
*lineno = si->loctab[locno].lineno;
if (dirname) {
/* caller wants directory info too .. */
- vg_assert(n_dirname > 0);
- VG_(strncpy_safely)(dirname,
- ML_(fndn_ix2dirname) (si, fndn_ix),
- n_dirname);
- *dirname_available = *dirname != 0;
+ *dirname = ML_(fndn_ix2dirname) (si, fndn_ix);
+ *dirname_available = (*dirname)[0] != '\0';
}
return True;
static const HChar *buf_fn;
static const HChar *buf_obj;
- static HChar buf_srcloc[BUF_LEN];
- static HChar buf_dirname[BUF_LEN];
- buf_srcloc[0] = buf_dirname[0] = 0;
+ static const HChar *buf_srcloc;
+ static const HChar *buf_dirname;
Bool know_dirinfo = False;
Bool know_fnname;
// The source for the highest level is in the loctab entry.
know_srcloc = VG_(get_filename_linenum)(
eip,
- buf_srcloc, BUF_LEN,
- buf_dirname, BUF_LEN, &know_dirinfo,
+ &buf_srcloc,
+ &buf_dirname, &know_dirinfo,
&lineno
);
} else {
know_dirinfo = False;
// The fndn_ix and lineno for the caller of the inlined fn is in cur_inl.
if (cur_inl->fndn_ix == 0) {
- VG_(snprintf) (buf_srcloc, BUF_LEN, "???");
+ buf_srcloc = "???";
} else {
FnDn *fndn = VG_(indexEltNumber) (iipc->di->fndnpool,
cur_inl->fndn_ix);
if (fndn->dirname) {
- VG_(snprintf) (buf_dirname, BUF_LEN, "%s", fndn->dirname);
+ buf_dirname = fndn->dirname;
know_dirinfo = True;
}
- VG_(snprintf) (buf_srcloc, BUF_LEN, "%s", fndn->filename);
+ buf_srcloc = fndn->filename;
}
lineno = cur_inl->lineno;
know_srcloc = True;
}
- buf_srcloc [ sizeof(buf_srcloc)-1 ] = 0;
- buf_dirname[ sizeof(buf_dirname)-1 ] = 0;
-
if (VG_(clo_xml)) {
Bool human_readable = True;
if (know_srcloc) {
APPEND(" (");
// Get the directory name, if any, possibly pruned, into dirname.
- HChar* dirname = NULL;
+ const HChar* dirname = NULL;
if (VG_(sizeXA)(VG_(clo_fullpath_after)) > 0) {
Int i;
dirname = buf_dirname;
Assert machinery for use in this file. vg_assert cannot be called
here due to cyclic dependencies.
------------------------------------------------------------------ */
+#if 0
#define libcbase_assert(expr) \
((void) (LIKELY(expr) ? 0 : \
(ML_(libcbase_assert_fail)(#expr, \
VG_(debugLog)(0, "libcbase", "Exiting now.\n");
VG_(exit_now)(1);
}
+#endif
/* ---------------------------------------------------------------------
HChar functions.
return dest_orig;
}
-/* Copy bytes, not overrunning the end of dest and always ensuring
- zero termination. */
-void VG_(strncpy_safely) ( HChar* dest, const HChar* src, SizeT ndest )
-{
- libcbase_assert(ndest > 0);
-
- SizeT i = 0;
- while (True) {
- dest[i] = 0;
- if (src[i] == 0) return;
- if (i >= ndest-1) return;
- dest[i] = src[i];
- i++;
- }
-}
-
HChar* VG_(strncpy) ( HChar* dest, const HChar* src, SizeT ndest )
{
SizeT i = 0;
case VG_USERREQ__MAP_IP_TO_SRCLOC: {
Addr ip = arg[1];
- HChar* buf64 = (HChar*)arg[2];
+ HChar* buf64 = (HChar*)arg[2]; // points to a HChar [64] array
+ const HChar *buf; // points to a string of unknown size
VG_(memset)(buf64, 0, 64);
UInt linenum = 0;
Bool ok = VG_(get_filename_linenum)(
- ip, &buf64[0], 50, NULL, 0, NULL, &linenum
+ ip, &buf, NULL, NULL, &linenum
);
if (ok) {
- /* Find the terminating zero in the first 50 bytes. */
+ /* For backward compatibility truncate the filename to
+ 49 characters. */
+ VG_(strncpy)(buf64, buf, 50);
+ buf64[49] = '\0';
UInt i;
for (i = 0; i < 50; i++) {
if (buf64[i] == 0)
break;
}
- /* We must find a zero somewhere in 0 .. 49. Else
- VG_(get_filename_linenum) is not properly zero
- terminating. */
- vg_assert(i < 50);
- VG_(sprintf)(&buf64[i], ":%u", linenum);
+ VG_(sprintf)(buf64+i, ":%u", linenum); // safe
} else {
buf64[0] = 0;
}
returns False. VG_(get_fnname) always
demangles C++ function names. VG_(get_fnname_w_offset) is the
same, except it appends "+N" to symbol names to indicate offsets. */
-extern Bool VG_(get_filename) ( Addr a, HChar* filename, Int n_filename );
+extern Bool VG_(get_filename) ( Addr a, const HChar** filename );
extern Bool VG_(get_fnname) ( Addr a, const HChar** fnname );
extern Bool VG_(get_linenum) ( Addr a, UInt* linenum );
extern Bool VG_(get_fnname_w_offset)
optionally directory name. filename and linenum may not be NULL.
dirname may be NULL, meaning that the caller does not want
directory name info, in which case dirname_available must also be
- NULL. If dirname is non-null, directory info is written to it, if
+ NULL. If dirname is non-null, directory info is written to *dirname, if
it is available; if not available, '\0' is written to the first
byte. In either case *dirname_available is set to indicate whether
or not directory information was available.
+ The character strings returned in *filename and *dirname are not
+ persistent. They will be freed when the DebugInfo they belong to
+ is discarded.
+
Returned value indicates whether any filename/line info could be
found. */
extern Bool VG_(get_filename_linenum)
( Addr a,
- /*OUT*/HChar* filename, Int n_filename,
- /*OUT*/HChar* dirname, Int n_dirname,
+ /*OUT*/const HChar** filename,
+ /*OUT*/const HChar** dirname,
/*OUT*/Bool* dirname_available,
/*OUT*/UInt* linenum );
const HChar *input,
UInt *enum_set);
-/* Like strncpy(), but if 'src' is longer than 'ndest' inserts a '\0' as the
- last character. */
-extern void VG_(strncpy_safely) ( HChar* dest, const HChar* src, SizeT ndest );
-
/* ---------------------------------------------------------------------
mem* functions
------------------------------------------------------------------ */