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

Invalid subscribe message #266

Closed
gnikol opened this issue Sep 8, 2021 · 6 comments
Closed

Invalid subscribe message #266

gnikol opened this issue Sep 8, 2021 · 6 comments

Comments

@gnikol
Copy link

gnikol commented Sep 8, 2021

Hi,

I have written a library that instantiates a subscriber and calls psubscribe on a simple pattern. My library is dynamically loaded by one application and everything works as expected.

The problem is that I have another application that loads the same library but when I call subscriber.consume() I get an "Invalid subscribe message" error. On the redis server side the PSUBSCRIBE patterns look identical (as observed with MONITOR).

Both applications are using the same .so binary and the library code is completely independent from the rest of the application logic i.e. it should not matter that the two calling applications are different because the library basically creates a separate thread, and it does not interact with any other threads. My library is statically linked to hiredis and redis-plus-plus.

Any ideas what could cause a difference in behavior?

@sewenew
Copy link
Owner

sewenew commented Sep 8, 2021

The error message means that Redis sever returns some invalid reply for subscribe command, i.e. a non-array reply or the array reply size is less than 1. That should not happen.

Can you show me the code that can reproduce the problem, e.g. how your calls redis-plus-plus related code in your library? Also what's your version of Redis, redis-plus-plus and hiredis?

Regards

@gnikol
Copy link
Author

gnikol commented Sep 8, 2021

I'm doing something along these lines:

db_ = std::make_unique<sw::redis::Redis>(db_address);
db_->command("config", "set", "notify-keyspace-events", "KEA");
auto subscriber = db_->subscriber();
subscriber.on_pmessage(
        [this](std::string pattern, std::string channel, std::string message) {
          ProcessMessage(channel, message);
        });
std::string pattern = "__keyevent@0__:*";
subscriber.psubscribe(pattern);

while (true) {
  try {
    subscriber.consume();
  } catch (const sw::redis::TimeoutError& e) {
    continue;
  }
}

One of the executables runs this code just fine and the other throws the "Invalid subscribe message" error.

I am running redis-plus-plus 1.2.1-6-g1010a2b (ref:1010a2bdac1e) and hiredis v1.0.0-36-g297ecbe (ref:297ecbecb716) on Debian 10, and compiling with gcc 8.3.

Thanks

@gnikol
Copy link
Author

gnikol commented Sep 8, 2021

The issue appears with redis-plus-plus 1.3.1 and hiredis 1.0.0 as well.

@gnikol
Copy link
Author

gnikol commented Sep 8, 2021

Doing a bit more digging, I found out that the calling executable that shows the buggy behavior loads a dynamic version of hiredis (v0.14). This calling application is a large open source project, which I cannot change. Within this application there is a facility to dynamically load libraries (with dl) and that's how my library is loaded. Is there a chance that something similar to #140 happens, i.e. the shared library the application is linked to somehow shadows the static linking of my library to hiredis?

@sewenew
Copy link
Owner

sewenew commented Sep 9, 2021

Your application code looks good to me. I think the problem is that you have two versions of hiredis. As I mentioned in the doc, if you installed two versions of hiredis, you'll get some wired problems.

I suggest you dynamically linking hiredis and redis-plus-plus by, and also keep hiredis the same version as that large open source project.

Regards

@gnikol
Copy link
Author

gnikol commented Sep 9, 2021

You are right, the issue is caused by the fact that the external application also links to (a different version of) hiredis, those symbols shadow the ones from my statically linked ones and that causes undefined behavior. The fix is to either use the same version as the external project or (which is what is better for my application) to hide the statically linked symbols with -Wl,--exclude-libs,ALL (or -Wl,--exclude-libs,redis++ just for redis++).

@gnikol gnikol closed this as completed Sep 9, 2021
@sewenew sewenew mentioned this issue Sep 10, 2021
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

No branches or pull requests

2 participants