usage_with_options(evlist_usage, options);
 
        if (details.event_group && (details.verbose || details.freq)) {
-               pr_err("--group option is not compatible with other options\n");
-               usage_with_options(evlist_usage, options);
+               usage_with_options_msg(evlist_usage, options,
+                       "--group option is not compatible with other options\n");
        }
 
        return __cmd_evlist(input_name, &details);
 
                             PARSE_OPT_STOP_AT_NON_OPTION);
        if (argc > 0) {
                if (strcmp(argv[0], "-") == 0) {
-                       pr_warning("  Error: '-' is not supported.\n");
-                       usage_with_options(probe_usage, options);
+                       usage_with_options_msg(probe_usage, options,
+                               "'-' is not supported.\n");
                }
                if (params.command && params.command != 'a') {
-                       pr_warning("  Error: another command except --add is set.\n");
-                       usage_with_options(probe_usage, options);
+                       usage_with_options_msg(probe_usage, options,
+                               "another command except --add is set.\n");
                }
                ret = parse_probe_event_argv(argc, argv);
                if (ret < 0) {
        switch (params.command) {
        case 'l':
                if (params.uprobes) {
-                       pr_warning("  Error: Don't use --list with --exec.\n");
-                       usage_with_options(probe_usage, options);
+                       pr_err("  Error: Don't use --list with --exec.\n");
+                       parse_options_usage(probe_usage, options, "l", true);
+                       parse_options_usage(NULL, options, "x", true);
+                       return -EINVAL;
                }
                ret = show_perf_probe_events(params.filter);
                if (ret < 0)
        case 'a':
                /* Ensure the last given target is used */
                if (params.target && !params.target_used) {
-                       pr_warning("  Error: -x/-m must follow the probe definitions.\n");
-                       usage_with_options(probe_usage, options);
+                       pr_err("  Error: -x/-m must follow the probe definitions.\n");
+                       parse_options_usage(probe_usage, options, "m", true);
+                       parse_options_usage(NULL, options, "x", true);
+                       return -EINVAL;
                }
 
                ret = perf_add_probe_events(params.events, params.nevents);
 
                usage_with_options(record_usage, record_options);
 
        if (nr_cgroups && !rec->opts.target.system_wide) {
-               ui__error("cgroup monitoring only available in"
-                         " system-wide mode\n");
-               usage_with_options(record_usage, record_options);
+               usage_with_options_msg(record_usage, record_options,
+                       "cgroup monitoring only available in system-wide mode");
+
        }
        if (rec->opts.record_switch_events &&
            !perf_can_record_switch_events()) {
-               ui__error("kernel does not support recording context switch events (--switch-events option)\n");
-               usage_with_options(record_usage, record_options);
+               ui__error("kernel does not support recording context switch events\n");
+               parse_options_usage(record_usage, record_options, "switch-events", 0);
+               return -EINVAL;
        }
 
        if (!rec->itr) {
 
        for (tok = strtok_r(str, ", ", &tmp);
                        tok; tok = strtok_r(NULL, ", ", &tmp)) {
                if (sort_dimension__add(tok, &sched->sort_list) < 0) {
-                       error("Unknown --sort key: `%s'", tok);
-                       usage_with_options(usage_msg, options);
+                       usage_with_options_msg(usage_msg, options,
+                                       "Unknown --sort key: `%s'", tok);
                }
        }
 
 
                rep_script_path = get_script_path(argv[0], REPORT_SUFFIX);
 
                if (!rec_script_path && !rep_script_path) {
-                       fprintf(stderr, " Couldn't find script %s\n\n See perf"
+                       usage_with_options_msg(script_usage, options,
+                               "Couldn't find script `%s'\n\n See perf"
                                " script -l for available scripts.\n", argv[0]);
-                       usage_with_options(script_usage, options);
                }
 
                if (is_top_script(argv[0])) {
                        rep_args = has_required_arg(rep_script_path);
                        rec_args = (argc - 1) - rep_args;
                        if (rec_args < 0) {
-                               fprintf(stderr, " %s script requires options."
+                               usage_with_options_msg(script_usage, options,
+                                       "`%s' script requires options."
                                        "\n\n See perf script -l for available "
                                        "scripts and options.\n", argv[0]);
-                               usage_with_options(script_usage, options);
                        }
                }
 
 
        exit(129);
 }
 
+void usage_with_options_msg(const char * const *usagestr,
+                           const struct option *opts, const char *fmt, ...)
+{
+       va_list ap;
+
+       exit_browser(false);
+
+       va_start(ap, fmt);
+       strbuf_addv(&error_buf, fmt, ap);
+       va_end(ap);
+
+       usage_with_options_internal(usagestr, opts, 0, NULL);
+       exit(129);
+}
+
 int parse_options_usage(const char * const *usagestr,
                        const struct option *opts,
                        const char *optstr, bool short_opt)
 
 
 extern NORETURN void usage_with_options(const char * const *usagestr,
                                         const struct option *options);
+extern NORETURN __attribute__((format(printf,3,4)))
+void usage_with_options_msg(const char * const *usagestr,
+                           const struct option *options,
+                           const char *fmt, ...);
 
 /*----- incremantal advanced APIs -----*/
 
 
        strbuf_setlen(sb, sb->len + len);
 }
 
-void strbuf_addf(struct strbuf *sb, const char *fmt, ...)
+void strbuf_addv(struct strbuf *sb, const char *fmt, va_list ap)
 {
        int len;
-       va_list ap;
+       va_list ap_saved;
 
        if (!strbuf_avail(sb))
                strbuf_grow(sb, 64);
-       va_start(ap, fmt);
+
+       va_copy(ap_saved, ap);
        len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap);
-       va_end(ap);
        if (len < 0)
                die("your vsnprintf is broken");
        if (len > strbuf_avail(sb)) {
                strbuf_grow(sb, len);
-               va_start(ap, fmt);
-               len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap);
-               va_end(ap);
+               len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap_saved);
+               va_end(ap_saved);
                if (len > strbuf_avail(sb)) {
                        die("this should not happen, your vsnprintf is broken");
                }
        strbuf_setlen(sb, sb->len + len);
 }
 
+void strbuf_addf(struct strbuf *sb, const char *fmt, ...)
+{
+       va_list ap;
+
+       va_start(ap, fmt);
+       strbuf_addv(sb, fmt, ap);
+       va_end(ap);
+}
+
 ssize_t strbuf_read(struct strbuf *sb, int fd, ssize_t hint)
 {
        size_t oldlen = sb->len;
 
  */
 
 #include <assert.h>
+#include <stdarg.h>
 
 extern char strbuf_slopbuf[];
 struct strbuf {
 
 __attribute__((format(printf,2,3)))
 extern void strbuf_addf(struct strbuf *sb, const char *fmt, ...);
+extern void strbuf_addv(struct strbuf *sb, const char *fmt, va_list ap);
 
 /* XXX: if read fails, any partial read is undone */
 extern ssize_t strbuf_read(struct strbuf *, int fd, ssize_t hint);