Skip to content

Remove Global/Static variables in path.c to make it thread safe #5148

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

Open
wants to merge 6 commits into
base: dev
Choose a base branch
from

Conversation

ahmed-kamal2004
Copy link
Member

Your checklist for this pull request

  • I've read the guidelines for contributing to this repository.
  • I made sure to follow the project's coding style.
  • I've documented every RZ_API function and struct this PR changes.
  • I've added tests that prove my changes are effective (required for changes to RZ_API).
  • I've updated the Rizin book with the relevant information (if needed).

Detailed description

Remove global/static variables in util/path.c, so removed the following:

  • portable_prefix
  • portable_prefix_searched
  • portable_prefix_mutex
    and merged all of them to a struct RzPathPortable in include/rz_util.h

Copy link

codecov bot commented May 13, 2025

Codecov Report

Attention: Patch coverage is 74.28571% with 9 lines in your changes missing coverage. Please review.

Project coverage is 44.88%. Comparing base (144b47d) to head (a86059f).

Files with missing lines Patch % Lines
librz/util/path.c 77.27% 3 Missing and 2 partials ⚠️
librz/main/rizin.c 55.55% 4 Missing ⚠️
Additional details and impacted files
Files with missing lines Coverage Δ
librz/core/cconfig.c 81.73% <100.00%> (ø)
librz/core/core.c 59.43% <100.00%> (+0.05%) ⬆️
librz/egg/egg_lang.c 37.58% <100.00%> (ø)
librz/main/rizin.c 49.89% <55.55%> (ø)
librz/util/path.c 57.89% <77.27%> (+4.66%) ⬆️

... and 10 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 144b47d...a86059f. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

static char *portable_prefix = NULL;
static bool portable_prefix_searched = false;
static RzThreadLock *portable_prefix_mutex = NULL;
RzPathPortable *rz_portable;
Copy link
Member

Choose a reason for hiding this comment

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

Remove this global variable and add the struct to RzCore.

Remove constructor/destructor and it's header file and just initialize/finalize RzPath within RzCore init/fini function

@@ -92,15 +88,16 @@ static char *set_portable_prefix(void) {
*/
RZ_API void rz_path_set_prefix(RZ_NONNULL const char *path) {
Copy link
Member

Choose a reason for hiding this comment

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

Add RzPath as argument of this function

char *prefix;
bool prefix_searched;
RzThreadLock *prefix_mutex;
} RzPathPortable;
Copy link
Member

Choose a reason for hiding this comment

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

Call this just RzPath and make it a private structure. (see how RzDiff is defined)

}
p->prefix = NULL;
p->prefix_searched = false;
p->prefix_mutex = rz_th_lock_new(recursive);
Copy link
Member

Choose a reason for hiding this comment

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

Pass false instead of an argument like you did.

* \brief Return new RzPathPortable
* \return New RzPathPortable
*/
RZ_API RZ_OWN RzPathPortable *rz_path_portable_new(bool recursive) {
Copy link
Member

Choose a reason for hiding this comment

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

Remove the argument

return NULL;
}
RZ_FREE(p->prefix);
p->prefix_searched = false;
Copy link
Member

Choose a reason for hiding this comment

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

No need, remove this line

if (!p) {
return NULL;
}
RZ_FREE(p->prefix);
Copy link
Member

Choose a reason for hiding this comment

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

Call free. Use RZ_FREE/RZ_FREE_CUSTOM only if you intend to reuse the variables immediately afterward.

If the structure is then freed, there is no need to waste time setting them to NULL like these macros do

* \brief Deallocate memory associated with a RzPathPortable object
* \return NULL
*/
RZ_API RZ_OWN RzPathPortable *rz_path_portable_free(RzPathPortable *p) {
Copy link
Member

Choose a reason for hiding this comment

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

Return void

p->prefix_searched = false;
RZ_FREE_CUSTOM(p->prefix_mutex, rz_th_lock_free);
free(p);
return NULL;
Copy link
Member

Choose a reason for hiding this comment

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

Remove this.

@ahmed-kamal2004
Copy link
Member Author

Not Ready for merging yet

Copy link
Member

@wargio wargio left a comment

Choose a reason for hiding this comment

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

Good progress

Copy link
Member

Choose a reason for hiding this comment

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

For this file, just create it's own path struct within RzEgg like you did for RzCore


#ifdef RZ_API

RZ_API void rz_path_set_prefix(RzPath *sys_path, RZ_NONNULL const char *path);
Copy link
Member

Choose a reason for hiding this comment

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

add RZ_NONNULL like for path and check the pointer in the assert (rz_return_if_fail) with the function.

#ifdef RZ_API

RZ_API void rz_path_set_prefix(RzPath *sys_path, RZ_NONNULL const char *path);
RZ_API RZ_OWN char *rz_path_prefix(RzPath *sys_path, RZ_NULLABLE const char *path);
Copy link
Member

Choose a reason for hiding this comment

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

Same here.

@@ -30,6 +39,11 @@ RZ_API RZ_OWN char *rz_path_home_expand(RZ_NULLABLE const char *path);

RZ_API RZ_OWN char *rz_path_realpath(RZ_NULLABLE const char *path);

RZ_API RZ_OWN RzPath *rz_path_new(void);
RZ_API void rz_path_free(RzPath *p);
Copy link
Member

Choose a reason for hiding this comment

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

Here add RZ_NULLABLE but you don't need to add any assert

@@ -12,28 +12,6 @@
#include <rz_constructor.h>
Copy link
Member

Choose a reason for hiding this comment

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

Remove this also

* \param path Path to put in the install prefix context or NULL to just get the install prefix
* \return \p path prefixed by the Rizin install prefix or just the install prefix
*/
RZ_API RZ_OWN char *rz_path_prefix(RZ_NULLABLE const char *path) {
RZ_API RZ_OWN char *rz_path_prefix(RzPath *sys_path, RZ_NULLABLE const char *path) {
Copy link
Member

Choose a reason for hiding this comment

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

Same here

@@ -135,28 +115,28 @@ RZ_API RZ_OWN char *rz_path_prefix(RZ_NULLABLE const char *path) {
* \brief Return the directory where include files are placed
*/
RZ_API RZ_OWN char *rz_path_incdir(void) {
Copy link
Member

Choose a reason for hiding this comment

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

These functions needs RzPath as argument.

Copy link
Member Author

Choose a reason for hiding this comment

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

Well, I am doing iterations in the process, still need to do a lot of work for rz_path_system also

*/
RZ_API RZ_OWN char *rz_path_system_rc(void) {
return rz_path_prefix(RZ_GLOBAL_RC);
RZ_API RZ_OWN char *rz_path_system_rc(RzPath *sys_path) {
Copy link
Member

Choose a reason for hiding this comment

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

RZ_NONNULL

* \brief Deallocate memory associated with a RzPath pointer
* \return NULL
*/
RZ_API void rz_path_free(RzPath *p) {
Copy link
Member

Choose a reason for hiding this comment

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

RZ_NULLABLE

* \return NULL
*/
RZ_API void rz_path_free(RzPath *p) {
if (p) {
Copy link
Member

Choose a reason for hiding this comment

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

Invert the if.

if (!p) { return; }

Copy link
Member Author

Choose a reason for hiding this comment

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

Ok, for code readability?

Copy link
Member

Choose a reason for hiding this comment

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

Yes

@@ -192,7 +192,7 @@ int rz_test_main(int argc, const char **argv) {
int ret = 0;
char *cwd = NULL;
RzTestState state = { 0 };

RzPath *sys_path = rz_path_new();
Copy link
Member

Choose a reason for hiding this comment

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

Check for null.

@@ -503,7 +503,7 @@ static int __watch_points_cb(void *user);
static int __references_cb(void *user);
static int __help_cb(void *user);
static int __fortune_cb(void *user);
static int __version_cb(void *user);
static int __version_cb(RzPath *sys_path, void *user);
Copy link
Member

Choose a reason for hiding this comment

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

I think that user is RzCore.

Copy link
Member

@Rot127 Rot127 left a comment

Choose a reason for hiding this comment

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

I would advice to add a test already for the changes made. The more edits you make without tests, the harder it will be to handle the complexity later.
Also, Coverity will be happy :)

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

Successfully merging this pull request may close these issues.

3 participants