     Int    i, tmp_log_fd, tmp_xml_fd;
     Int    toolname_len = VG_(strlen)(toolname);
     Char*  tmp_str;         // Used in a couple of places.
-@@ -514,9 +554,13 @@
+@@ -514,9 +570,13 @@
  
        else if VG_STR_CLO(arg, "--log-file", log_fsname_unexpanded) {
           log_to = VgLogTo_File;

-         VG_(log_output_sink).fd = tmp_log_fd;
-         VG_(fcntl)(VG_(log_output_sink).fd, VKI_F_SETFD, VKI_FD_CLOEXEC);
-      }
+      VG_(log_output_sink).fd = tmp_log_fd = VG_(safe_fd)(tmp_log_fd);
    } else {
       // If they said --log-fd=-1, don't print anything.  Plausible for use in
       // regression testing suites that use client requests to count errors.
@@ -886,18 +872,7 @@
    // Finalise the output fds: and the XML fd ..
 
    if (tmp_xml_fd >= 0) {

+  return ret;
+}
+
+static Int move_fd_into_safe_range(Int fd, Bool xml) {
+   OutputSink *sink = xml ? &(VG_(xml_output_sink)) : &(VG_(log_output_sink));
+   // Move fd into the safe range, so it doesn't conflict with any app fds.
+   fd = VG_(fcntl)(fd, VKI_F_DUPFD, VG_(fd_hard_limit));
+   if (fd < 0) {
+      VG_(printf)("valgrind: failed to move %s file fd "
+                  "into safe range, using stderr\n", xml ? "XML" : "log");
+      sink->fd = 2;   // stderr
+      sink->is_socket = False;
+   } else {
+      sink->fd = fd;
+      VG_(fcntl)(fd, VKI_F_SETFD, VKI_FD_CLOEXEC);
+   }
+   return fd;
+}
+
 /* The main processing for command line options.  See comments above
    on early_process_cmd_line_options.
 
@@ -339,13 +397,11 @@
 */
 static
 void main_process_cmd_line_options ( /*OUT*/Bool* logging_to_fd,
