diff --git a/src/brpc/details/jemalloc_profiler.cpp b/src/brpc/details/jemalloc_profiler.cpp
index c14d5490..df479ab3 100644
--- a/src/brpc/details/jemalloc_profiler.cpp
+++ b/src/brpc/details/jemalloc_profiler.cpp
@@ -23,6 +23,7 @@
 #include "butil/files/file_path.h"
 #include "butil/iobuf.h"
 #include "butil/popen.h"
+#include "butil/string_printf.h"
 #include "gflags/gflags.h"
 #include "gflags/gflags_declare.h"
 #include <brpc/details/jemalloc_profiler.h>
@@ -32,6 +33,7 @@
 #include <bthread/bthread.h>
 #include <cerrno>
 #include <cstdlib>
+#include <unordered_set>
 
 extern "C" {
 // weak symbol: resolved at runtime by the linker if we are using jemalloc, nullptr otherwise
@@ -166,6 +168,23 @@ static int JeProfileReset(size_t lg_sample) {
     return 0;
 }
 
+// https://github.com/jemalloc/jemalloc/blob/5.3.0/bin/jeprof.in#L211-L222
+static const std::unordered_set<const char*> g_extra_options_set = {
+    "inuse_space", "inuse_objects", "alloc_space",
+    "alloc_objects", "show_bytes", "drop_negative",
+    "total_delay", "contentions", "mean_delay"
+};
+
+std::string GlobalExtraOptionsString() {
+    std::string result;
+    result.reserve(64);
+    for (const auto& option : g_extra_options_set) {
+        result.append(option);
+        result.append(" ");
+    }
+    return result;
+}
+
 void JeControlProfile(Controller* cntl) {
     const brpc::URI& uri = cntl->http_request().uri();
     // http:ip:port/pprof/heap?display=(text|svg|stats|flamegraph)&extra_options=(inuse_space|inuse_objects..)
@@ -228,13 +247,20 @@ void JeControlProfile(Controller* cntl) {
     }
     const std::string process_file(process_path, len);
 
-    std::string cmd_str = jeprof + " " + process_file + " " + prof_name;
+    std::string cmd_str = butil::string_printf(
+        "%s %s %s", jeprof.c_str(), process_file.c_str(), prof_name.c_str());
 
     // https://github.com/jemalloc/jemalloc/blob/5.3.0/bin/jeprof.in#L211-L222
     // e.g: inuse_space, contentions
     const std::string* uri_extra_options = uri.GetQuery("extra_options");
     if (uri_extra_options != nullptr && !uri_extra_options->empty()) {
-        cmd_str += " --" + *uri_extra_options + " ";
+        if (g_extra_options_set.count(uri_extra_options->c_str()) > 0) {
+            butil::string_appendf(&cmd_str, " --%s", uri_extra_options->c_str());
+        } else {
+            static std::string g_options_str = GlobalExtraOptionsString();
+            LOG(WARNING) << "Unsupported jemalloc options=" << *uri_extra_options
+                         << ", only support [" << g_options_str << "]";
+        }
     }
 
     bool display_img = false;
@@ -249,7 +275,8 @@ void JeControlProfile(Controller* cntl) {
             return;
         }
         const int width_size = FLAGS_max_flame_graph_width > 0 ? FLAGS_max_flame_graph_width : 1200;
-        cmd_str += " --collapsed | " + std::string(flamegraph_tool) + " --colors mem --width " + std::to_string(width_size);
+        butil::string_appendf(&cmd_str, " --collapsed | %s --colors mem --width %d",
+                              flamegraph_tool, width_size);
         display_img = true;
     } else if (*uri_display == "text") {
         cmd_str += " --text ";
