--trace-startup: non-zero exit code when fails; enable in iOS runtime (#5309)

diff --git a/packages/flutter_tools/lib/src/commands/run.dart b/packages/flutter_tools/lib/src/commands/run.dart
index 3565d7b..c31c861 100644
--- a/packages/flutter_tools/lib/src/commands/run.dart
+++ b/packages/flutter_tools/lib/src/commands/run.dart
@@ -275,7 +275,7 @@
       Observatory observatory = await Observatory.connect(result.observatoryPort);
       await downloadStartupTrace(observatory);
     } catch (error) {
-      printError('Error connecting to observatory: $error');
+      printError('Error downloading trace from observatory: $error');
       return 1;
     }
   }
diff --git a/packages/flutter_tools/lib/src/commands/trace.dart b/packages/flutter_tools/lib/src/commands/trace.dart
index 7581795..da920b6 100644
--- a/packages/flutter_tools/lib/src/commands/trace.dart
+++ b/packages/flutter_tools/lib/src/commands/trace.dart
@@ -154,6 +154,11 @@
 /// Download the startup trace information from the given observatory client and
 /// store it to build/start_up_info.json.
 Future<Null> downloadStartupTrace(Observatory observatory) async {
+  File traceInfoFile = new File('build/start_up_info.json');
+
+  if (await traceInfoFile.exists())
+    await traceInfoFile.delete();
+
   Tracing tracing = new Tracing(observatory);
 
   Map<String, dynamic> timeline = await tracing.stopTracingAndDownloadTimeline(
@@ -173,16 +178,13 @@
   int firstFrameTimestampMicros = extractInstantEventTimestamp(kFirstUsefulFrameEventName);
 
   if (engineEnterTimestampMicros == null) {
-    printError('Engine start event is missing in the timeline. Cannot compute startup time.');
-    return null;
+    throw 'Engine start event is missing in the timeline. Cannot compute startup time.';
   }
 
   if (firstFrameTimestampMicros == null) {
-    printError('First frame event is missing in the timeline. Cannot compute startup time.');
-    return null;
+    throw 'First frame event is missing in the timeline. Cannot compute startup time.';
   }
 
-  File traceInfoFile = new File('build/start_up_info.json');
   int timeToFirstFrameMicros = firstFrameTimestampMicros - engineEnterTimestampMicros;
   Map<String, dynamic> traceInfo = <String, dynamic>{
     'engineEnterTimestampMicros': engineEnterTimestampMicros,
diff --git a/packages/flutter_tools/lib/src/ios/devices.dart b/packages/flutter_tools/lib/src/ios/devices.dart
index 0d81085..64730d5 100644
--- a/packages/flutter_tools/lib/src/ios/devices.dart
+++ b/packages/flutter_tools/lib/src/ios/devices.dart
@@ -216,6 +216,9 @@
       // the port picked and scrape that later.
     }
 
+    if (platformArgs['trace-startup'] ?? false)
+      launchArguments.add('--trace-startup');
+
     List<String> launchCommand = <String>[
       '/usr/bin/env',
       'ios-deploy',
diff --git a/packages/flutter_tools/lib/src/run.dart b/packages/flutter_tools/lib/src/run.dart
index 1b4f2e8..ad1d3bf 100644
--- a/packages/flutter_tools/lib/src/run.dart
+++ b/packages/flutter_tools/lib/src/run.dart
@@ -188,7 +188,12 @@
 
     if (serviceProtocol != null && traceStartup) {
       printStatus('Downloading startup trace info...');
-      await downloadStartupTrace(serviceProtocol);
+      try {
+        await downloadStartupTrace(serviceProtocol);
+      } catch(error) {
+        printError(error);
+        return 2;
+      }
       appFinished();
     } else {
       setupTerminal();