From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from [87.239.111.99] (localhost [127.0.0.1]) by dev.tarantool.org (Postfix) with ESMTP id DECE2F4AE5F; Mon, 24 Feb 2025 21:37:23 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org DECE2F4AE5F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1740422244; bh=egEJqWBUTvzQ1pr4O+rWce6qJCtZEUvsdNB2BSbjpJg=; h=Date:To:Cc:References:In-Reply-To:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=qhPkvKRsWZhSA1hGf2K+FDcGmVyDbOKjEnpBuz+7tES21sSjVFF78bez+mBKunJpr sPJydQu6FrQ4Hz4Y0xscuC1byzprVCy2MERHnws3i5lMuf534h3+1rufaho5S8Ttor 88V3g3z2dCfLu2ZYn9uJzdlhp8Buts9xkRf70MHc= Received: from send37.i.mail.ru (send37.i.mail.ru [89.221.237.132]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id 67A976FCB3 for ; Mon, 24 Feb 2025 21:37:22 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 67A976FCB3 Received: by exim-smtp-75f5fcb77d-k42gr with esmtpa (envelope-from ) id 1tmdKT-00000000BZ5-08Rz; Mon, 24 Feb 2025 21:37:21 +0300 Content-Type: multipart/alternative; boundary="------------gFOQcyeNrASQASiyh5jC76kY" Message-ID: <85fb2edc-efda-4f99-a1e0-fb9945106023@tarantool.org> Date: Mon, 24 Feb 2025 21:37:20 +0300 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Content-Language: en-US To: Sergey Kaplun , Sergey Bronnikov Cc: tarantool-patches@dev.tarantool.org References: <4080c2556ca20ee272c4283ff75361c43e39d674.1740050074.git.sergeyb@tarantool.org> In-Reply-To: X-Mailru-Src: smtp X-4EC0790: 10 X-7564579A: 646B95376F6C166E X-77F55803: 4F1203BC0FB41BD957BCB5CA1E0F722CEFAA33340EA34A59FD4AC33E956578C0182A05F538085040221046C0980F592E3DE06ABAFEAF6705E5A19846AE2A9BF72108A7ABA525422271713673A8881951 X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE7548C33FFD72831AFEA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F790063770398A047C76876C8638F802B75D45FF36EB9D2243A4F8B5A6FCA7DBDB1FC311F39EFFDF887939037866D6147AF826D858B14A39D8DF75F7DEF6A6604AB2E9CD8B2FEB6D4011A6EACC7F00164DA146DAFE8445B8C89999728AA50765F7900637F924B32C592EA89F389733CBF5DBD5E9C8A9BA7A39EFB766F5D81C698A659EA7CC7F00164DA146DA9985D098DBDEAEC8A9FF340AA05FB58CF6B57BC7E6449061A352F6E88A58FB86F5D81C698A659EA73AA81AA40904B5D9A18204E546F3947C17119E5299B287EE040F9FF01DFDA4A84AD6D5ED66289B523666184CF4C3C14F6136E347CC761E07725E5C173C3A84C3D1CB9C1829AC0833BA3038C0950A5D36B5C8C57E37DE458B330BD67F2E7D9AF16D1867E19FE14079C09775C1D3CA48CF3D321E7403792E342EB15956EA79C166A417C69337E82CC275ECD9A6C639B01B78DA827A17800CE75B51C8FB0C3E748C731C566533BA786AA5CC5B56E945C8DA X-C1DE0DAB: 0D63561A33F958A5A5BBB4EA6C9A43EB5002B1117B3ED696DABB88DF88CCDC03F5FEB6EB1EB183FD823CB91A9FED034534781492E4B8EEAD21D4E6D365FE45D1BDAD6C7F3747799A X-C8649E89: 1C3962B70DF3F0ADE00A9FD3E00BEEDF3FED46C3ACD6F73ED3581295AF09D3DF87807E0823442EA2ED31085941D9CD0AF7F820E7B07EA4CF10ABB5DD702A7A718A909FDC36D7271CEE033BC2FF36FF8770485B8C143D7FCDBC84317DE6256153DD1EB5C6CC1B9E944D003892DFB87B70C9E3BBC14D63D83D26F3F050228BDBEE5F4332CA8FE04980913E6812662D5F2AB9AF64DB4688768036DF5FE9C0001AF333F2C28C22F508233FCF178C6DD14203 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu53w8ahmwBjZKM/YPHZyZHvz5uv+WouB9+ObcCpyrx6l7KImUglyhkEat/+ysWwi0gdhEs0JGjl6ggRWTy1haxBpVdbIX1nthFXMZebaIdHP2ghjoIc/363UZI6Kf1ptIMVQQG/FugD0/CS9MGGBfp62g= X-Mailru-Sender: C4F68CFF4024C8867DFDF7C7F2588458363D2E0FFD3EFC7B4756507F36A35F4BF5BA8630914C8D7959366FB134B5BD8F645D15D82EE4B272BD6E4642A116CA93524AA66B5ACBE6721EF430B9A63E2A504198E0F3ECE9B5443453F38A29522196 X-Mras: Ok Subject: Re: [Tarantool-patches] [PATCH luajit 7/8][v3] misc: specific message for disabled profilers X-BeenThere: tarantool-patches@dev.tarantool.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Sergey Bronnikov via Tarantool-patches Reply-To: Sergey Bronnikov Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" This is a multi-part message in MIME format. --------------gFOQcyeNrASQASiyh5jC76kY Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Hi, Sergey! thanks for review! Updated and force-pushed. Sergey On 24.02.2025 14:28, Sergey Kaplun via Tarantool-patches wrote: > Hi, Sergey! > Thanks for the fixes! > LGTM, after fixing my comments below. > > On 20.02.25, Sergey Bronnikov wrote: >> sysprof and memprof Lua API functions return an error message >> "profiler misuse", when the corresponding profiler is disabled in >> the build. It is not possible to easily distinguish whether it is >> really misuse or if the profiler was not enabled in the build. The >> patch changes error messages, so when profiler is not enabled in >> the build, the message is the following:"profiler misuse: profiler is disabled". >> --- >> src/lib_misc.c | 25 ++++++++++++++-- >> src/lj_errmsg.h | 1 + >> .../misclib-memprof-lapi-disabled.test.lua | 22 ++++++++++++++ >> .../misclib-sysprof-lapi-disabled.test.lua | 29 +++++++++++++++++++ >> 4 files changed, 75 insertions(+), 2 deletions(-) >> create mode 100644 test/tarantool-tests/profilers/misclib-memprof-lapi-disabled.test.lua >> create mode 100644 test/tarantool-tests/profilers/misclib-sysprof-lapi-disabled.test.lua >> >> diff --git a/src/lib_misc.c b/src/lib_misc.c >> index 1fd06dd1..d98cf3f0 100644 >> --- a/src/lib_misc.c >> +++ b/src/lib_misc.c >> @@ -306,10 +306,15 @@ static int sysprof_error(lua_State *L, int status, const char *err_details) >> /* local res, err, errno = sysprof.start(options) */ >> LJLIB_CF(misc_sysprof_start) >> { > As we discussed ofline we may use 2 approaches here: > > 1) Use branching: > a) Main branch first. > | { > | if (LJ_HASSYSPROF) { > | /* ... */ > | } else { > | const char *err_details = // > | /* ... */ > | } > | } > > b) Early return first > | { > | if (!LJ_HASSYSPROF) { > | const char *err_details = // > | /* ... */ > | } else { > | /* ... */ > | } > | } > > 2) Use macros directives instead: > a) Main branch first. > | { > | #if LJ_HASSYSPROF > | /* ... */ > | #else > | /* ... */ > | } > | #endif > > b) Early return first > | { > | #if !LJ_HASSYSPROF > | /* ... */ > | #else > | /* ... */ > | } > | #endif > > We decided to use the second approach to avoid huge diff changes and > make code more readable. > It's up to you to use an approach a) or b). > This helps us to avoid warnings with `-Wdeclaration-after-statement` > enabled. Updated (approach b)): diff --git a/src/lib_misc.c b/src/lib_misc.c index 62d0597e..d5122665 100644 --- a/src/lib_misc.c +++ b/src/lib_misc.c @@ -304,15 +304,14 @@ static int sysprof_error(lua_State *L, int status, const char *err_details)  /* local res, err, errno = sysprof.start(options) */  LJLIB_CF(misc_sysprof_start)  { -  const char *err_details = NULL; +#if !LJ_HASSYSPROF +  const char *err_details = err2msg(LJ_ERR_PROF_DETAILS_DISABLED); +  return sysprof_error(L, PROFILE_ERRUSE, err_details); +#else    int status = PROFILE_SUCCESS;    struct luam_Sysprof_Options opt = {}; - -  if (!LJ_HASSYSPROF) { -    err_details = err2msg(LJ_ERR_PROF_DETAILS_DISABLED); -    return sysprof_error(L, PROFILE_ERRUSE, err_details); -  } +  const char *err_details = NULL;    status = parse_sysprof_opts(L, &opt, &err_details);    if (LJ_UNLIKELY(status != PROFILE_SUCCESS)) @@ -325,35 +324,36 @@ LJLIB_CF(misc_sysprof_start)    lua_pushboolean(L, 1);    return 1; +#endif /* !LJ_HASSYSPROF */  }  /* local res, err, errno = profile.sysprof_stop() */  LJLIB_CF(misc_sysprof_stop)  { +#if !LJ_HASSYSPROF +  const char *err_details = err2msg(LJ_ERR_PROF_DETAILS_DISABLED); +  return sysprof_error(L, PROFILE_ERRUSE, err_details); +#else    int status = luaM_sysprof_stop(L); -  if (!LJ_HASSYSPROF) { -    const char *err_details = err2msg(LJ_ERR_PROF_DETAILS_DISABLED); -    return sysprof_error(L, PROFILE_ERRUSE, err_details); -  }    if (LJ_UNLIKELY(status != PROFILE_SUCCESS))      return sysprof_error(L, status, NULL);    lua_pushboolean(L, 1);    return 1; +#endif /* !LJ_HASSYSPROF */  }  /* local counters, err, errno = sysprof.report() */  LJLIB_CF(misc_sysprof_report)  { +#if !LJ_HASSYSPROF +  const char *err_details = err2msg(LJ_ERR_PROF_DETAILS_DISABLED); +  return sysprof_error(L, PROFILE_ERRUSE, err_details); +#else    struct luam_Sysprof_Counters counters = {};    GCtab *data_tab = NULL;    GCtab *count_tab = NULL;    int status = luaM_sysprof_report(&counters); -  if (!LJ_HASSYSPROF) { -    const char *err_details = err2msg(LJ_ERR_PROF_DETAILS_DISABLED); -    return sysprof_error(L, PROFILE_ERRUSE, err_details); -  } -    if (status != PROFILE_SUCCESS)      return sysprof_error(L, status, NULL); @@ -379,6 +379,7 @@ LJLIB_CF(misc_sysprof_report)    lua_setfield(L, -2, "vmstate");    return 1; +#endif /* !LJ_HASSYSPROF */  }  /* ----- misc.memprof module ---------------------------------------------- */ @@ -388,14 +389,14 @@ LJLIB_CF(misc_sysprof_report)  /* local started, err, errno = misc.memprof.start(fname) */  LJLIB_CF(misc_memprof_start)  { +#if !LJ_HASMEMPROF +  const char *err_details = err2msg(LJ_ERR_PROF_DETAILS_DISABLED); +  return sysprof_error(L, PROFILE_ERRUSE, err_details); +#else    struct lj_memprof_options opt = {0};    const char *fname = strdata(lj_lib_checkstr(L, 1));    struct profile_ctx *ctx;    int memprof_status; -  if (!LJ_HASMEMPROF) { -    const char *err_details = err2msg(LJ_ERR_PROF_DETAILS_DISABLED); -    return sysprof_error(L, PROFILE_ERRUSE, err_details); -  }    /*    ** FIXME: more elegant solution with ctx. @@ -441,16 +442,17 @@ LJLIB_CF(misc_memprof_start)    }    lua_pushboolean(L, 1);    return 1; +#endif /* !LJ_HASMEMPROF */  }  /* local stopped, err, errno = misc.memprof.stop() */  LJLIB_CF(misc_memprof_stop)  { +#if !LJ_HASMEMPROF +  const char *err_details = err2msg(LJ_ERR_PROF_DETAILS_DISABLED); +  return sysprof_error(L, PROFILE_ERRUSE, err_details); +#else    int status = lj_memprof_stop(L); -  if (!LJ_HASMEMPROF) { -    const char *err_details = err2msg(LJ_ERR_PROF_DETAILS_DISABLED); -    return sysprof_error(L, PROFILE_ERRUSE, err_details); -  }    if (status != PROFILE_SUCCESS) {      switch (status) {      case PROFILE_ERRUSE: @@ -474,6 +476,7 @@ LJLIB_CF(misc_memprof_stop)    }    lua_pushboolean(L, 1);    return 1; +#endif /* !LJ_HASMEMPROF */  }  #endif /* !LJ_TARGET_WINDOWS */ > Here and below. > > Also, it helps to avoid an excess call to `lj_{sysprof,memprof}_stop()`. > >> + const char *err_details = NULL; >> int status = PROFILE_SUCCESS; >> >> struct luam_Sysprof_Options opt = {}; >> - const char *err_details = NULL; >> + >> + if (!LJ_HASSYSPROF) { >> + err_details = err2msg(LJ_ERR_PROF_DETAILS_DISABLED); >> + return sysprof_error(L, PROFILE_ERRUSE, err_details); >> + } >> >> status = parse_sysprof_opts(L, &opt, &err_details); >> if (LJ_UNLIKELY(status != PROFILE_SUCCESS)) >> @@ -328,6 +333,10 @@ LJLIB_CF(misc_sysprof_start) >> LJLIB_CF(misc_sysprof_stop) >> { >> int status = luaM_sysprof_stop(L); >> + if (!LJ_HASSYSPROF) { >> + const char *err_details = err2msg(LJ_ERR_PROF_DETAILS_DISABLED); >> + return sysprof_error(L, PROFILE_ERRUSE, err_details); >> + } >> if (LJ_UNLIKELY(status != PROFILE_SUCCESS)) >> return sysprof_error(L, status, NULL); >> >> @@ -341,8 +350,12 @@ LJLIB_CF(misc_sysprof_report) >> struct luam_Sysprof_Counters counters = {}; >> GCtab *data_tab = NULL; >> GCtab *count_tab = NULL; >> - >> int status = luaM_sysprof_report(&counters); >> + if (!LJ_HASSYSPROF) { >> + const char *err_details = err2msg(LJ_ERR_PROF_DETAILS_DISABLED); >> + return sysprof_error(L, PROFILE_ERRUSE, err_details); >> + } >> + >> if (status != PROFILE_SUCCESS) >> return sysprof_error(L, status, NULL); >> >> @@ -381,6 +394,10 @@ LJLIB_CF(misc_memprof_start) >> const char *fname = strdata(lj_lib_checkstr(L, 1)); >> struct profile_ctx *ctx; >> int memprof_status; >> + if (!LJ_HASMEMPROF) { >> + const char *err_details = err2msg(LJ_ERR_PROF_DETAILS_DISABLED); >> + return sysprof_error(L, PROFILE_ERRUSE, err_details); >> + } >> >> /* >> ** FIXME: more elegant solution with ctx. >> @@ -432,6 +449,10 @@ LJLIB_CF(misc_memprof_start) >> LJLIB_CF(misc_memprof_stop) >> { >> int status = lj_memprof_stop(L); >> + if (!LJ_HASMEMPROF) { >> + const char *err_details = err2msg(LJ_ERR_PROF_DETAILS_DISABLED); >> + return sysprof_error(L, PROFILE_ERRUSE, err_details); >> + } >> if (status != PROFILE_SUCCESS) { >> switch (status) { >> case PROFILE_ERRUSE: >> diff --git a/src/lj_errmsg.h b/src/lj_errmsg.h >> index b5c3a275..e26f5e38 100644 >> --- a/src/lj_errmsg.h >> +++ b/src/lj_errmsg.h >> @@ -193,6 +193,7 @@ ERRDEF(PROF_DETAILS_BADINTERVAL, "profiler interval must be greater than 1") >> ERRDEF(PROF_DETAILS_BADPATH, "profiler path does not exist") >> ERRDEF(PROF_DETAILS_BADTABLE, "profiler expects a table with parameters") >> >> +ERRDEF(PROF_DETAILS_DISABLED, "profiler is disabled") >> #undef ERRDEF >> >> /* Detecting unused error messages: >> diff --git a/test/tarantool-tests/profilers/misclib-memprof-lapi-disabled.test.lua b/test/tarantool-tests/profilers/misclib-memprof-lapi-disabled.test.lua >> new file mode 100644 >> index 00000000..de0aa136 >> --- /dev/null >> +++ b/test/tarantool-tests/profilers/misclib-memprof-lapi-disabled.test.lua >> @@ -0,0 +1,22 @@ >> +local tap = require('tap') >> +local test = tap.test('misclib-memprof-lapi-disabled'):skipcond({ >> + ['Memprof is enabled'] = not os.getenv('LUAJIT_DISABLE_MEMPROF'), >> +}) >> + >> +test:plan(6) >> + >> +-- Attempt to start memprof when it is disabled. >> +local res, err, errno = misc.memprof.start() >> +test:is(res, nil, 'result status on start when memprof is disabled') >> +test:ok(err:match('profiler is disabled'), >> + 'error on start when memprof is disabled') >> +test:ok(type(errno) == 'number', 'errno on start when memprof is disabled') >> + >> +-- Attempt to stop memprof when it is disabled. >> +res, err, errno = misc.memprof.stop() >> +test:is(res, nil, 'result status on stop when memprof is disabled') >> +test:ok(err:match('profiler is disabled'), >> + 'error on stop when memprof is disabled') >> +test:ok(type(errno) == 'number', 'errno on start when memprof is disabled') >> + >> +test:done(true) >> diff --git a/test/tarantool-tests/profilers/misclib-sysprof-lapi-disabled.test.lua b/test/tarantool-tests/profilers/misclib-sysprof-lapi-disabled.test.lua >> new file mode 100644 >> index 00000000..2a9ce796 >> --- /dev/null >> +++ b/test/tarantool-tests/profilers/misclib-sysprof-lapi-disabled.test.lua >> @@ -0,0 +1,29 @@ >> +local tap = require('tap') >> +local test = tap.test('misclib-sysprof-lapi-disabled'):skipcond({ >> + ['Sysprof is enabled'] = not os.getenv('LUAJIT_DISABLE_SYSPROF'), >> +}) >> + >> +test:plan(9) >> + >> +-- Attempt to start sysprof when sysprof is disabled. >> +local res, err, errno = misc.sysprof.start() >> +test:is(res, nil, 'result status on start when sysprof is disabled') >> +test:ok(err:match('profiler is disabled'), >> + 'error on start when sysprof is disabled') >> +test:ok(type(errno) == 'number', 'errno on start when sysprof is disabled') >> + >> +-- Attempt to stop sysprof when sysprof is disabled. >> +res, err, errno = misc.sysprof.stop() >> +test:is(res, nil, 'result status on stop when sysprof is disabled') >> +test:ok(err:match('profiler is disabled'), >> + 'error on stop when sysprof is disabled') >> +test:ok(type(errno) == 'number', 'errno on start when sysprof is disabled') >> + >> +-- Attempt to report when sysprof is disabled. >> +res, err, errno = misc.sysprof.report() >> +test:is(res, nil, 'result status on report when sysprof is disabled') >> +test:ok(err:match('profiler is disabled'), >> + 'error on stop when sysprof is disabled') >> +test:ok(type(errno) == 'number', 'errno on start when sysprof is disabled') >> + >> +test:done(true) >> -- >> 2.43.0 >> --------------gFOQcyeNrASQASiyh5jC76kY Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 8bit

Hi, Sergey!

thanks for review!

Updated and force-pushed.

Sergey

On 24.02.2025 14:28, Sergey Kaplun via Tarantool-patches wrote:
Hi, Sergey!
Thanks for the fixes!
LGTM, after fixing my comments below.

On 20.02.25, Sergey Bronnikov wrote:
sysprof and memprof Lua API functions return an error message
"profiler misuse", when the corresponding profiler is disabled in
the build. It is not possible to easily distinguish whether it is
really misuse or if the profiler was not enabled in the build. The
patch changes error messages, so when profiler is not enabled in
the build, the message is the following: "profiler misuse:
profiler is disabled".
---
 src/lib_misc.c                                | 25 ++++++++++++++--
 src/lj_errmsg.h                               |  1 +
 .../misclib-memprof-lapi-disabled.test.lua    | 22 ++++++++++++++
 .../misclib-sysprof-lapi-disabled.test.lua    | 29 +++++++++++++++++++
 4 files changed, 75 insertions(+), 2 deletions(-)
 create mode 100644 test/tarantool-tests/profilers/misclib-memprof-lapi-disabled.test.lua
 create mode 100644 test/tarantool-tests/profilers/misclib-sysprof-lapi-disabled.test.lua

diff --git a/src/lib_misc.c b/src/lib_misc.c
index 1fd06dd1..d98cf3f0 100644
--- a/src/lib_misc.c
+++ b/src/lib_misc.c
@@ -306,10 +306,15 @@ static int sysprof_error(lua_State *L, int status, const char *err_details)
 /* local res, err, errno = sysprof.start(options) */
 LJLIB_CF(misc_sysprof_start)
 {
As we discussed ofline we may use 2 approaches here:

1) Use branching:
a) Main branch first.
| {
|    if (LJ_HASSYSPROF) {
|      /* ... */
|    } else {
|      const char *err_details = //
|      /* ... */
|    }
| }

b) Early return first
| {
|    if (!LJ_HASSYSPROF) {
|      const char *err_details = //
|      /* ... */
|    } else {
|      /* ... */
|    }
| }

2) Use macros directives instead:
a) Main branch first.
| {
| #if LJ_HASSYSPROF
|      /* ... */
| #else
|      /* ... */
|    }
| #endif

b) Early return first
| {
| #if !LJ_HASSYSPROF
|      /* ... */
| #else
|      /* ... */
|    }
| #endif

We decided to use the second approach to avoid huge diff changes and
make code more readable.
It's up to you to use an approach a) or b).
This helps us to avoid warnings with `-Wdeclaration-after-statement`
enabled.

Updated (approach b)):

diff --git a/src/lib_misc.c b/src/lib_misc.c
index 62d0597e..d5122665 100644
--- a/src/lib_misc.c
+++ b/src/lib_misc.c
@@ -304,15 +304,14 @@ static int sysprof_error(lua_State *L, int status, const char *err_details)
 /* local res, err, errno = sysprof.start(options) */
 LJLIB_CF(misc_sysprof_start)
 {
-  const char *err_details = NULL;
+#if !LJ_HASSYSPROF
+  const char *err_details = err2msg(LJ_ERR_PROF_DETAILS_DISABLED);
+  return sysprof_error(L, PROFILE_ERRUSE, err_details);
+#else
   int status = PROFILE_SUCCESS;
 
   struct luam_Sysprof_Options opt = {};
-
-  if (!LJ_HASSYSPROF) {
-    err_details = err2msg(LJ_ERR_PROF_DETAILS_DISABLED);
-    return sysprof_error(L, PROFILE_ERRUSE, err_details);
-  }
+  const char *err_details = NULL;
 
   status = parse_sysprof_opts(L, &opt, &err_details);
   if (LJ_UNLIKELY(status != PROFILE_SUCCESS))
@@ -325,35 +324,36 @@ LJLIB_CF(misc_sysprof_start)
 
   lua_pushboolean(L, 1);
   return 1;
+#endif /* !LJ_HASSYSPROF */
 }
 
 /* local res, err, errno = profile.sysprof_stop() */
 LJLIB_CF(misc_sysprof_stop)
 {
+#if !LJ_HASSYSPROF
+  const char *err_details = err2msg(LJ_ERR_PROF_DETAILS_DISABLED);
+  return sysprof_error(L, PROFILE_ERRUSE, err_details);
+#else
   int status = luaM_sysprof_stop(L);
-  if (!LJ_HASSYSPROF) {
-    const char *err_details = err2msg(LJ_ERR_PROF_DETAILS_DISABLED);
-    return sysprof_error(L, PROFILE_ERRUSE, err_details);
-  }
   if (LJ_UNLIKELY(status != PROFILE_SUCCESS))
     return sysprof_error(L, status, NULL);
 
   lua_pushboolean(L, 1);
   return 1;
+#endif /* !LJ_HASSYSPROF */
 }
 
 /* local counters, err, errno = sysprof.report() */
 LJLIB_CF(misc_sysprof_report)
 {
+#if !LJ_HASSYSPROF
+  const char *err_details = err2msg(LJ_ERR_PROF_DETAILS_DISABLED);
+  return sysprof_error(L, PROFILE_ERRUSE, err_details);
+#else
   struct luam_Sysprof_Counters counters = {};
   GCtab *data_tab = NULL;
   GCtab *count_tab = NULL;
   int status = luaM_sysprof_report(&counters);
-  if (!LJ_HASSYSPROF) {
-    const char *err_details = err2msg(LJ_ERR_PROF_DETAILS_DISABLED);
-    return sysprof_error(L, PROFILE_ERRUSE, err_details);
-  }
-
   if (status != PROFILE_SUCCESS)
     return sysprof_error(L, status, NULL);
 
@@ -379,6 +379,7 @@ LJLIB_CF(misc_sysprof_report)
   lua_setfield(L, -2, "vmstate");
 
   return 1;
+#endif /* !LJ_HASSYSPROF */
 }
 
 /* ----- misc.memprof module ---------------------------------------------- */
@@ -388,14 +389,14 @@ LJLIB_CF(misc_sysprof_report)
 /* local started, err, errno = misc.memprof.start(fname) */
 LJLIB_CF(misc_memprof_start)
 {
+#if !LJ_HASMEMPROF
+  const char *err_details = err2msg(LJ_ERR_PROF_DETAILS_DISABLED);
+  return sysprof_error(L, PROFILE_ERRUSE, err_details);
+#else
   struct lj_memprof_options opt = {0};
   const char *fname = strdata(lj_lib_checkstr(L, 1));
   struct profile_ctx *ctx;
   int memprof_status;
-  if (!LJ_HASMEMPROF) {
-    const char *err_details = err2msg(LJ_ERR_PROF_DETAILS_DISABLED);
-    return sysprof_error(L, PROFILE_ERRUSE, err_details);
-  }
 
   /*
   ** FIXME: more elegant solution with ctx.
@@ -441,16 +442,17 @@ LJLIB_CF(misc_memprof_start)
   }
   lua_pushboolean(L, 1);
   return 1;
+#endif /* !LJ_HASMEMPROF */
 }
 
 /* local stopped, err, errno = misc.memprof.stop() */
 LJLIB_CF(misc_memprof_stop)
 {
+#if !LJ_HASMEMPROF
+  const char *err_details = err2msg(LJ_ERR_PROF_DETAILS_DISABLED);
+  return sysprof_error(L, PROFILE_ERRUSE, err_details);
+#else
   int status = lj_memprof_stop(L);
-  if (!LJ_HASMEMPROF) {
-    const char *err_details = err2msg(LJ_ERR_PROF_DETAILS_DISABLED);
-    return sysprof_error(L, PROFILE_ERRUSE, err_details);
-  }
   if (status != PROFILE_SUCCESS) {
     switch (status) {
     case PROFILE_ERRUSE:
@@ -474,6 +476,7 @@ LJLIB_CF(misc_memprof_stop)
   }
   lua_pushboolean(L, 1);
   return 1;
+#endif /* !LJ_HASMEMPROF */
 }
 #endif /* !LJ_TARGET_WINDOWS */
 

Here and below.

Also, it helps to avoid an excess call to `lj_{sysprof,memprof}_stop()`.

+  const char *err_details = NULL;
   int status = PROFILE_SUCCESS;
 
   struct luam_Sysprof_Options opt = {};
-  const char *err_details = NULL;
+
+  if (!LJ_HASSYSPROF) {
+    err_details = err2msg(LJ_ERR_PROF_DETAILS_DISABLED);
+    return sysprof_error(L, PROFILE_ERRUSE, err_details);
+  }
 
   status = parse_sysprof_opts(L, &opt, &err_details);
   if (LJ_UNLIKELY(status != PROFILE_SUCCESS))
@@ -328,6 +333,10 @@ LJLIB_CF(misc_sysprof_start)
 LJLIB_CF(misc_sysprof_stop)
 {
   int status = luaM_sysprof_stop(L);
+  if (!LJ_HASSYSPROF) {
+    const char *err_details = err2msg(LJ_ERR_PROF_DETAILS_DISABLED);
+    return sysprof_error(L, PROFILE_ERRUSE, err_details);
+  }
   if (LJ_UNLIKELY(status != PROFILE_SUCCESS))
     return sysprof_error(L, status, NULL);
 
@@ -341,8 +350,12 @@ LJLIB_CF(misc_sysprof_report)
   struct luam_Sysprof_Counters counters = {};
   GCtab *data_tab = NULL;
   GCtab *count_tab = NULL;
-
   int status = luaM_sysprof_report(&counters);
+  if (!LJ_HASSYSPROF) {
+    const char *err_details = err2msg(LJ_ERR_PROF_DETAILS_DISABLED);
+    return sysprof_error(L, PROFILE_ERRUSE, err_details);
+  }
+
   if (status != PROFILE_SUCCESS)
     return sysprof_error(L, status, NULL);
 
@@ -381,6 +394,10 @@ LJLIB_CF(misc_memprof_start)
   const char *fname = strdata(lj_lib_checkstr(L, 1));
   struct profile_ctx *ctx;
   int memprof_status;
+  if (!LJ_HASMEMPROF) {
+    const char *err_details = err2msg(LJ_ERR_PROF_DETAILS_DISABLED);
+    return sysprof_error(L, PROFILE_ERRUSE, err_details);
+  }
 
   /*
   ** FIXME: more elegant solution with ctx.
@@ -432,6 +449,10 @@ LJLIB_CF(misc_memprof_start)
 LJLIB_CF(misc_memprof_stop)
 {
   int status = lj_memprof_stop(L);
+  if (!LJ_HASMEMPROF) {
+    const char *err_details = err2msg(LJ_ERR_PROF_DETAILS_DISABLED);
+    return sysprof_error(L, PROFILE_ERRUSE, err_details);
+  }
   if (status != PROFILE_SUCCESS) {
     switch (status) {
     case PROFILE_ERRUSE:
diff --git a/src/lj_errmsg.h b/src/lj_errmsg.h
index b5c3a275..e26f5e38 100644
--- a/src/lj_errmsg.h
+++ b/src/lj_errmsg.h
@@ -193,6 +193,7 @@ ERRDEF(PROF_DETAILS_BADINTERVAL, "profiler interval must be greater than 1")
 ERRDEF(PROF_DETAILS_BADPATH, "profiler path does not exist")
 ERRDEF(PROF_DETAILS_BADTABLE, "profiler expects a table with parameters")
 
+ERRDEF(PROF_DETAILS_DISABLED, "profiler is disabled")
 #undef ERRDEF
 
 /* Detecting unused error messages:
diff --git a/test/tarantool-tests/profilers/misclib-memprof-lapi-disabled.test.lua b/test/tarantool-tests/profilers/misclib-memprof-lapi-disabled.test.lua
new file mode 100644
index 00000000..de0aa136
--- /dev/null
+++ b/test/tarantool-tests/profilers/misclib-memprof-lapi-disabled.test.lua
@@ -0,0 +1,22 @@
+local tap = require('tap')
+local test = tap.test('misclib-memprof-lapi-disabled'):skipcond({
+  ['Memprof is enabled'] = not os.getenv('LUAJIT_DISABLE_MEMPROF'),
+})
+
+test:plan(6)
+
+-- Attempt to start memprof when it is disabled.
+local res, err, errno = misc.memprof.start()
+test:is(res, nil, 'result status on start when memprof is disabled')
+test:ok(err:match('profiler is disabled'),
+        'error on start when memprof is disabled')
+test:ok(type(errno) == 'number', 'errno on start when memprof is disabled')
+
+-- Attempt to stop memprof when it is disabled.
+res, err, errno = misc.memprof.stop()
+test:is(res, nil, 'result status on stop when memprof is disabled')
+test:ok(err:match('profiler is disabled'),
+        'error on stop when memprof is disabled')
+test:ok(type(errno) == 'number', 'errno on start when memprof is disabled')
+
+test:done(true)
diff --git a/test/tarantool-tests/profilers/misclib-sysprof-lapi-disabled.test.lua b/test/tarantool-tests/profilers/misclib-sysprof-lapi-disabled.test.lua
new file mode 100644
index 00000000..2a9ce796
--- /dev/null
+++ b/test/tarantool-tests/profilers/misclib-sysprof-lapi-disabled.test.lua
@@ -0,0 +1,29 @@
+local tap = require('tap')
+local test = tap.test('misclib-sysprof-lapi-disabled'):skipcond({
+  ['Sysprof is enabled'] = not os.getenv('LUAJIT_DISABLE_SYSPROF'),
+})
+
+test:plan(9)
+
+-- Attempt to start sysprof when sysprof is disabled.
+local res, err, errno = misc.sysprof.start()
+test:is(res, nil, 'result status on start when sysprof is disabled')
+test:ok(err:match('profiler is disabled'),
+        'error on start when sysprof is disabled')
+test:ok(type(errno) == 'number', 'errno on start when sysprof is disabled')
+
+-- Attempt to stop sysprof when sysprof is disabled.
+res, err, errno = misc.sysprof.stop()
+test:is(res, nil, 'result status on stop when sysprof is disabled')
+test:ok(err:match('profiler is disabled'),
+        'error on stop when sysprof is disabled')
+test:ok(type(errno) == 'number', 'errno on start when sysprof is disabled')
+
+-- Attempt to report when sysprof is disabled.
+res, err, errno = misc.sysprof.report()
+test:is(res, nil, 'result status on report when sysprof is disabled')
+test:ok(err:match('profiler is disabled'),
+        'error on stop when sysprof is disabled')
+test:ok(type(errno) == 'number', 'errno on start when sysprof is disabled')
+
+test:done(true)
-- 
2.43.0


    
--------------gFOQcyeNrASQASiyh5jC76kY--