}
}
+/* If we lost communication with the remote server, just give up.
+ Recovering is too difficult. */
+static void give_up(void)
+{
+ VG_(umsg)("\n");
+ VG_(umsg)("Valgrind: Lost communication with the remote "
+ "debuginfo server.\n");
+ VG_(umsg)("Valgrind: I can't recover from that. Giving up. Sorry.\n");
+ VG_(umsg)("\n");
+ VG_(exit)(1);
+ /*NOTREACHED*/
+}
/* "Do" a transaction: that is, send the given frame to the server and
return the frame it sends back. Caller owns the resulting frame
some reason. */
static Frame* do_transaction ( Int sd, Frame* req )
{
-if (0) VG_(printf)("CLIENT: send %c%c%c%c\n", req->data[0], req->data[1], req->data[2], req->data[3]);
+ if (0) VG_(printf)("CLIENT: send %c%c%c%c\n",
+ req->data[0], req->data[1], req->data[2], req->data[3]);
+
/* What goes on the wire is:
adler(le32) n_data(le32) data[0 .. n_data-1]
where the checksum covers n_data as well as data[].
r = my_read(sd, res->data, res->n_data);
if (r != rd_len) return NULL;
-if (0) VG_(printf)("CLIENT: recv %c%c%c%c\n", res->data[0], res->data[1], res->data[2], res->data[3]);
+ if (0) VG_(printf)("CLIENT: recv %c%c%c%c\n",
+ res->data[0], res->data[1], res->data[2], res->data[3]);
/* Compute the checksum for the received data, and check it. */
adler = VG_(adler32)(0, NULL, 0); // initial value
/* So, read off .. off+len-1 into the entry. */
CEnt* ce = img->ces[entNo];
-if (0) {
-static UInt t_last = 0;
-static ULong nread = 0;
-UInt now = VG_(read_millisecond_timer)();
-UInt delay = now - t_last;
-t_last = now;
-nread += len;
-VG_(printf)("XXXXXXXX (tot %lld) read %ld offset %lld %u\n",
- nread, len, off, delay);
-}
+ if (0) {
+ static UInt t_last = 0;
+ static ULong nread = 0;
+ UInt now = VG_(read_millisecond_timer)();
+ UInt delay = now - t_last;
+ t_last = now;
+ nread += len;
+ VG_(printf)("XXXXXXXX (tot %lld) read %ld offset %lld %u\n",
+ nread, len, off, delay);
+ }
if (img->source.is_local) {
// Simple: just read it
VG_(umsg)("set_CEnt (reading data from DI server): fail: "
"server unexpectedly closed the connection\n");
}
+ give_up();
+ /* NOTREACHED */
vg_assert(0);
end_of_else_clause:
{}
if (req) free_Frame(req);
if (res) free_Frame(res);
// FIXME: now what?
+ give_up();
+ /* NOTREACHED */
vg_assert(0);
}
/*NOTREACHED*/
/* Try to find a separate debug file for a given object file. If
- found, return its DiImage, which should be freed by the caller. */
+ found, return its DiImage, which should be freed by the caller. If
+ |buildid| is non-NULL, then a debug object matching it is
+ acceptable. If |buildid| is NULL or doesn't specify a findable
+ debug object, then we look in various places to find a file with
+ the specified CRC. And if that doesn't work out then we give
+ up. */
static
DiImage* find_debug_file( struct _DebugInfo* di,
const HChar* objpath, const HChar* buildid,
debugpath = ML_(dinfo_zalloc)(
"di.fdf.3",
- VG_(strlen)(objdir) + VG_(strlen)(debugname) + 32 +
- (extrapath ? VG_(strlen)(extrapath) : 0));
+ VG_(strlen)(objdir) + VG_(strlen)(debugname) + 64
+ + (extrapath ? VG_(strlen)(extrapath) : 0)
+ + (serverpath ? VG_(strlen)(serverpath) : 0));
VG_(sprintf)(debugpath, "%s/%s", objdir, debugname);
-
dimg = open_debug_file(debugpath, NULL, crc, rel_ok, NULL);
if (dimg != NULL) goto dimg_ok;
if (extrapath) {
VG_(sprintf)(debugpath, "%s%s/%s", extrapath,
- objdir, debugname);
+ objdir, debugname);
dimg = open_debug_file(debugpath, NULL, crc, rel_ok, NULL);
if (dimg != NULL) goto dimg_ok;
}
if (serverpath) {
- dimg = open_debug_file(debugname, NULL, crc, rel_ok, serverpath);
+ /* When looking on the debuginfo server, always just pass the
+ basename. */
+ const HChar* basename = debugname;
+ if (VG_(strstr)(basename, "/") != NULL) {
+ basename = VG_(strrchr)(basename, '/') + 1;
+ }
+ VG_(sprintf)(debugpath, "%s on %s", basename, serverpath);
+ dimg = open_debug_file(basename, NULL, crc, rel_ok, serverpath);
if (dimg) goto dimg_ok;
}
}
+/* Try to find a separate debug file for a given object file, in a
+ hacky and dangerous way: check only the --extra-debuginfo-path and
+ the --debuginfo-server. And don't do a consistency check. */
+static
+DiImage* find_debug_file_ad_hoc( struct _DebugInfo* di,
+ const HChar* objpath )
+{
+ const HChar* extrapath = VG_(clo_extra_debuginfo_path);
+ const HChar* serverpath = VG_(clo_debuginfo_server);
+
+ DiImage* dimg = NULL; /* the img that we found */
+ HChar* debugpath = NULL; /* where we found it */
+
+ HChar *objdir = ML_(dinfo_strdup)("di.fdfah.1", objpath);
+ HChar *objdirptr;
+
+ if ((objdirptr = VG_(strrchr)(objdir, '/')) != NULL)
+ *objdirptr = '\0';
+
+ debugpath = ML_(dinfo_zalloc)(
+ "di.fdfah.3",
+ VG_(strlen)(objdir) + 64
+ + (extrapath ? VG_(strlen)(extrapath) : 0)
+ + (serverpath ? VG_(strlen)(serverpath) : 0));
+
+ if (extrapath) {
+ VG_(sprintf)(debugpath, "%s/%s", extrapath, objpath);
+ dimg = ML_(img_from_local_file)(debugpath);
+ if (dimg != NULL) {
+ if (VG_(clo_verbosity) > 1) {
+ VG_(message)(Vg_DebugMsg, " Using (POSSIBLY MISMATCHED) %s\n",
+ debugpath);
+ }
+ goto dimg_ok;
+ }
+ }
+ if (serverpath) {
+ /* When looking on the debuginfo server, always just pass the
+ basename. */
+ const HChar* basename = objpath;
+ if (VG_(strstr)(basename, "/") != NULL) {
+ basename = VG_(strrchr)(basename, '/') + 1;
+ }
+ VG_(sprintf)(debugpath, "%s on %s", basename, serverpath);
+ dimg = ML_(img_from_di_server)(basename, serverpath);
+ if (dimg != NULL) {
+ if (VG_(clo_verbosity) > 1) {
+ VG_(message)(Vg_DebugMsg, " Using (POSSIBLY MISMATCHED) %s\n",
+ debugpath);
+ }
+ goto dimg_ok;
+ }
+ }
+
+ dimg_ok:
+
+ ML_(dinfo_free)(objdir);
+
+ if (dimg != NULL) {
+ vg_assert(debugpath);
+ TRACE_SYMTAB("\n");
+ TRACE_SYMTAB("------ Found an ad_hoc debuginfo file: %s\n", debugpath);
+ }
+
+ if (debugpath)
+ ML_(dinfo_free)(debugpath);
+
+ return dimg;
+}
+
+
static DiOffT INDEX_BIS ( DiOffT base, UWord idx, UWord scale ) {
// This is a bit stupid. Really, idx and scale ought to be
// 64-bit quantities, always.
/* Look for a build-id */
HChar* buildid = find_buildid(mimg, False, False);
- /* Look for a debug image */
+ /* Look for a debug image that matches either the build-id or
+ the debuglink-CRC32 in the main image. If the main image
+ doesn't contain either of those then this won't even bother
+ to try looking. This looks in all known places, including
+ the --extra-debuginfo-path if specified and on the
+ --debuginfo-server if specified. */
if (buildid != NULL || debuglink_escn.img != NULL) {
/* Do have a debuglink section? */
if (debuglink_escn.img != NULL) {
buildid = NULL; /* paranoia */
}
-# if defined(VGPV_arm_linux_android)
- if (dimg == NULL && VG_(clo_debuginfo_server) != NULL) {
- HChar* basename = di->fsm.filename;
- if (VG_(strstr)(basename, "/") != NULL)
- basename = VG_(strrchr)(basename, '/') + 1;
- VG_(printf)("XXXXXXXXXXX trying ad-hoc %s\n", basename);
- dimg = ML_(img_from_di_server)(basename,
- VG_(clo_debuginfo_server));
+ /* As a last-ditch measure, try looking for in the
+ --extra-debuginfo-path and/or on the --debuginfo-server, but
+ only in the case where --allow-mismatched-debuginfo=yes.
+ This is dangerous in that (1) it gives no assurance that the
+ debuginfo object matches the main one, and hence (2) we will
+ very likely get an assertion in the code below, if indeed
+ there is a mismatch. Hence it is disabled by default
+ (--allow-mismatched-debuginfo=no). Nevertheless it's
+ sometimes a useful way of getting out of a tight spot.
+
+ Note that we're ignoring the name in the .gnu_debuglink
+ section here, and just looking for a file of the same name
+ either the extra-path or on the server. */
+ if (dimg == NULL && VG_(clo_allow_mismatched_debuginfo)) {
+ dimg = find_debug_file_ad_hoc( di, di->fsm.filename );
}
-# endif
/* TOPLEVEL */
/* If we were successful in finding a debug image, pull various