Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move debug dump constants to quickjs.h #770

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

mrmbernardi
Copy link

Addresses #769

Copy link
Collaborator

@chqrlie chqrlie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not quite meet the goal:

  • the debug flags are only defined for debug builds (#ifndef NDEBUG) and all of them get defined in this case.
  • the original design did not have the debug_flags tested by check_dump_flag and the debug code was only compiled and tested if the corresponding flags DUMP_XXX was defined. (I prefer this one, but we should check that the unused code is indeed removed).

The goal seems to be that external code can call the API JS_SetDumpFlags to select the appropriate debugging dumps using named flags instead of explicit hex values, provided the library was compiled with all of the defined.

Yet with this patch, the constants will only be defined and available for the external code if such code is itself compiled in debug mode, which may not be desirable.

An alternative seems advisable: define the JS_DUMP_XXX contants unconditionally and either:

  • use a different constant to select conditional compilation of the dump code and tests.
  • expand check_dump_flag to (0) in non debug builds and rely on the compiler / optimizer to omit the debugging code that becomes unreachable as if will only be referenced by if ((0)) blocks. This latter approach makes the code less clunky as the redundant #ifdef JS_DUMP_XXX / check_dump_flag(rt, JS_DUMP_XXX) get simplified.

In any case, either all debug handlers and dump code will be compiled or none of them. The granularity was finer before but this does not seem to be a problem as it was only useful because there was no way to control the output via a command line option or an API.

We should also make these changes:

  • make JS_SetDumpFlags return a boolean true in debug builds and false in regular builds
  • add another API JS_GetDumpFlags so temporary changes can be undone.

@saghul
Copy link
Contributor

saghul commented Dec 25, 2024

I agree we should likely define them unconditionally.

Then we can change the checks in the code to only run in not NDEBUG mode.

@mrmbernardi
Copy link
Author

mrmbernardi commented Dec 25, 2024

How about this:

  • Always define all JS_DUMP_XXX constants in quickjs.h
  • Change all #ifdef JS_DUMP_XXX in quickjs.c to #ifndef ENABLE_DUMPS or something.
  • By default debug builds set ENABLE_DUMPS

Maybe also only compile JS_SetDumpFlags with ENABLE_DUMPS so you'll get a linker error if you try to use it on an unsupported build?

@saghul
Copy link
Contributor

saghul commented Dec 25, 2024

That ENABLE_DUMPS is really NDEBUG negated

@chqrlie
Copy link
Collaborator

chqrlie commented Dec 25, 2024

Maybe also only compile JS_SetDumpFlags with ENABLE_DUMPS so you'll get a linker error if you try to use it on an unsupported build?

I don't like this option because it prevents linking to a dynamic non-debug library, thus prevents other tests too

@mrmbernardi mrmbernardi force-pushed the fix-769 branch 4 times, most recently from 628032b to a5a1d47 Compare December 27, 2024 05:20
@mrmbernardi
Copy link
Author

I made an option called ENABLE_DUMPS which is on by default on a debug build. All of the #ifdef statements now check ENABLE_DUMPS and I've given them comments to show which variables they were originally checking so its now easy to tell what dump feature they're servicing. I also made JS_SetDumpFlags return an int, -1 when ENABLE_DUMPS was not set on compilation, and 0 otherwise. This way you can get some feedback on whether dumping is supported when dynamically linking.

Comment on lines -14829 to -14836
#if defined(DUMP_BYTECODE_FINAL) || \
defined(DUMP_BYTECODE_PASS2) || \
defined(DUMP_BYTECODE_PASS1) || \
defined(DUMP_BYTECODE_STACK) || \
defined(DUMP_BYTECODE_STEP) || \
defined(DUMP_READ_OBJECT)
#define DUMP_BYTECODE
#endif
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI I also found this section wasn't needed.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, no longer needed, but somewhat confusing. It was used to trigger compilation of the bytecode dump utilities when one of the flags that needed it was defined. JS_DUMP_BYTECODE is no longer defined anywhere so the tests #ifdef ENABLE_DUMPS // JS_DUMP_BYTECODE may be misleading.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was something I considered. I figured readers would be able to work out what's going on.

I changed the comments to JS_DUMP_BYTECODE_* to give a bit more of a hint.

quickjs.c Outdated
Comment on lines 1896 to 1903
int JS_SetDumpFlags(JSRuntime *rt, uint64_t flags)
{
#ifdef ENABLE_DUMPS
return 0;
rt->dump_flags = flags;
#else
return -1;
#endif
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems broken: the function returns before setting the flags

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops. Thanks for catching that

Comment on lines -14829 to -14836
#if defined(DUMP_BYTECODE_FINAL) || \
defined(DUMP_BYTECODE_PASS2) || \
defined(DUMP_BYTECODE_PASS1) || \
defined(DUMP_BYTECODE_STACK) || \
defined(DUMP_BYTECODE_STEP) || \
defined(DUMP_READ_OBJECT)
#define DUMP_BYTECODE
#endif
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, no longer needed, but somewhat confusing. It was used to trigger compilation of the bytecode dump utilities when one of the flags that needed it was defined. JS_DUMP_BYTECODE is no longer defined anywhere so the tests #ifdef ENABLE_DUMPS // JS_DUMP_BYTECODE may be misleading.

quickjs.h Outdated
Comment on lines 352 to 355
JS_EXTERN void JS_SetMemoryLimit(JSRuntime *rt, size_t limit);
JS_EXTERN void JS_SetDumpFlags(JSRuntime *rt, uint64_t flags);
JS_EXTERN int JS_SetDumpFlags(JSRuntime *rt, uint64_t flags);
JS_EXTERN size_t JS_GetGCThreshold(JSRuntime *rt);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you also add an API to get the current set of dump flags?

JS_EXTERN uint64_t JS_GetDumpFlags(JSRuntime *rt);

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added. However it seems the types are incorrect. Is it correct that the API sets and gets a uint64_t while the underlying variable is defined to be a 24 bit bit-field?

Maybe this is future proofing. The original library authors also seem to do this with JS_NewInt32 taking a context parameter when it's unused.

CMakeLists.txt Outdated
@@ -120,6 +120,11 @@ xoption(CONFIG_ASAN "Enable AddressSanitizer (ASan)" OFF)
xoption(CONFIG_MSAN "Enable MemorySanitizer (MSan)" OFF)
xoption(CONFIG_TSAN "Enable ThreadSanitizer (TSan)" OFF)
xoption(CONFIG_UBSAN "Enable UndefinedBehaviorSanitizer (UBSan)" OFF)
if(CMAKE_BUILD_TYPE MATCHES "Debug")
xoption(ENABLE_DUMPS "Enable Dumps" ON)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather not add a new definition NDEBUG is already a thing.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The intent is to allow dumps in release builds or create debug builds without the dump code. IMO this can be quite valuable when debugging issues relating to the dump code. The defaults handle the typical case.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's a separate change from what this PR started as. We can take one step at a time.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay I reverted this change

quickjs.h Outdated
@@ -327,7 +350,8 @@ JS_EXTERN JSRuntime *JS_NewRuntime(void);
JS_EXTERN void JS_SetRuntimeInfo(JSRuntime *rt, const char *info);
/* use 0 to disable memory limit */
JS_EXTERN void JS_SetMemoryLimit(JSRuntime *rt, size_t limit);
JS_EXTERN void JS_SetDumpFlags(JSRuntime *rt, uint64_t flags);
JS_EXTERN int JS_SetDumpFlags(JSRuntime *rt, uint64_t flags);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could leave it as it was and make it a noop in release buids.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should users be able to tell if they've linked to a build that supports dumping?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, due to the very specific nature of it, the user knows for sure.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to noop

@mrmbernardi mrmbernardi force-pushed the fix-769 branch 2 times, most recently from 1d8bfca to 7189236 Compare December 29, 2024 07:07
Comment on lines -79 to -82

#ifndef NDEBUG
#define DUMP_BYTECODE_FINAL 0x01 /* dump pass 3 final byte code */
#define DUMP_BYTECODE_PASS2 0x02 /* dump pass 2 code */
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using a specific define ENABLE_DUMPS was fine and preferreable over using #ifndef NDEBUG everywhere.
I suppose saghul did not want it defined in the CMakefile.txt. You should define here this way:

#ifndef NDEBUG
#define ENABLE_DUMPS
#endif

This allows temporary definition to investigate problems in the release build.

Sorry for the confusion and the extra work.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No worries. I was on break for a bit but got it sorted now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants