cpp_redis icon indicating copy to clipboard operation
cpp_redis copied to clipboard

cpp_redis::client causes program to crash

Open cblauvelt opened this issue 7 years ago • 7 comments

I'm attempting to run a variation of your example program and I cannot seem to get it to run without crashing.

I am running the program below:

#include <iostream>
#include <cpp_redis/cpp_redis>

using namespace std;
int main() {
    cpp_redis::client client;
    cpp_redis::active_logger = make_unique<cpp_redis::logger>(cpp_redis::logger::log_level::debug);
    
    client.connect("127.0.0.1", 6379, [&](const std::string& host, std::size_t port, cpp_redis::client::connect_state status) {
        if (status == cpp_redis::client::connect_state::dropped) {
        cout << "client disconnected from " <<  host << ":" << port << endl;
        } else if (status == cpp_redis::client::connect_state::ok) {
            cout << "client connected to " <<  host << ":" << port << endl;
        }
    });

    // same as client.send({ "SET", "hello", "42" }, ...)
    client.set("hello", "42", [](cpp_redis::reply& reply) {
        std::cout << "set hello 42: " << reply << std::endl;
        // if (reply.is_string())
        //   do_something_with_string(reply.as_string())
    });

    // same as client.send({ "GET", "hello" }, ...)
    client.get("hello", [](cpp_redis::reply& reply) {
        std::cout << "get hello: " << reply << std::endl;
        // if (reply.is_string())
        //   do_something_with_string(reply.as_string())
    });

    // synchronous commit, no timeout
    client.sync_commit();

    // same as client.send({ "DECRBY", "hello", 12 }, ...)
    client.decrby("hello", 12, [](cpp_redis::reply& reply) {
        std::cout << "decrby hello 12: " << reply << std::endl;
        // if (reply.is_integer())
        //   do_something_with_integer(reply.as_integer())
    });

    // same as client.send({ "GET", "hello" }, ...)
    client.get("hello", [](cpp_redis::reply& reply) {
        std::cout << "get hello: " << reply << std::endl;
        // if (reply.is_string())
        //   do_something_with_string(reply.as_string())
    });

    // commands are pipelined and only sent when client.commit() is called
    // client.commit();

    // synchronous commit, no timeout
    client.sync_commit();

    // synchronous commit, timeout
    // client.sync_commit(std::chrono::milliseconds(100));
}
and my output is:
[DEBUG][cpp_redis][/opt/projects/src/sources/core/client.cpp:93] cpp_redis::client attempts to connect
[DEBUG][cpp_redis][/opt/projects/src/sources/network/redis_connection.cpp:59] cpp_redis::network::redis_connection attempts to connect
[DEBUG][cpp_redis][/opt/projects/src/sources/network/redis_connection.cpp:69] cpp_redis::network::redis_connection connected
[INFO ][cpp_redis][/opt/projects/src/sources/core/client.cpp:111] cpp_redis::client connected
client connected to 127.0.0.1:6379
[INFO ][cpp_redis][/opt/projects/src/sources/core/client.cpp:171] cpp_redis::client attemps to store new command in the send buffer
[DEBUG][cpp_redis][/opt/projects/src/sources/network/redis_connection.cpp:113] cpp_redis::network::redis_connection stored new command in the send buffer
[INFO ][cpp_redis][/opt/projects/src/sources/core/client.cpp:173] cpp_redis::client stored new command in the send buffer
[INFO ][cpp_redis][/opt/projects/src/sources/core/client.cpp:171] cpp_redis::client attemps to store new command in the send buffer
[DEBUG][cpp_redis][/opt/projects/src/sources/network/redis_connection.cpp:113] cpp_redis::network::redis_connection stored new command in the send buffer
[INFO ][cpp_redis][/opt/projects/src/sources/core/client.cpp:173] cpp_redis::client stored new command in the send buffer
[DEBUG][cpp_redis][/opt/projects/src/sources/core/client.cpp:214] cpp_redis::client attempts to send pipelined commands
[DEBUG][cpp_redis][/opt/projects/src/sources/network/redis_connection.cpp:124] cpp_redis::network::redis_connection attempts to send pipelined commands
[DEBUG][cpp_redis][/opt/projects/src/sources/network/redis_connection.cpp:136] cpp_redis::network::redis_connection sent pipelined commands
[INFO ][cpp_redis][/opt/projects/src/sources/core/client.cpp:216] cpp_redis::client sent pipelined commands
[DEBUG][cpp_redis][/opt/projects/src/sources/core/client.cpp:205] cpp_redis::client waiting for callbacks to complete
The terminal process terminated with exit code: 1

I am compiling this with: -DCMAKE_BUILD_TYPE=Release -DLOGGING_ENABLED=1

As you can see from the output, it's crashing while waiting for the call_backs to complete. This also occurs if all the code within the callbacks is commented out.

Please let me know if you need any additional information.

cblauvelt avatar Jan 28 '18 22:01 cblauvelt

I took out all the set and get requests and only left the client.sync_commit();

The output now gets to disconnecting the connection but it fails during the disconnect. This may imply it's a tacopie issue.

Output is below:

[INFO ][cpp_redis][/opt/projects/src/sources/core/client.cpp:216] cpp_redis::client sent pipelined commands
[DEBUG][cpp_redis][/opt/projects/src/sources/core/client.cpp:205] cpp_redis::client waiting for callbacks to complete
[DEBUG][cpp_redis][/opt/projects/src/sources/core/client.cpp:207] cpp_redis::client finished waiting for callback completion
[DEBUG][cpp_redis][/opt/projects/src/sources/network/redis_connection.cpp:82] cpp_redis::network::redis_connection attempts to disconnect
The terminal process terminated with exit code: 1

The code executed after this line is:

//! close connection
  m_client->disconnect(wait_for_removal);

  //! clear buffer
  m_buffer.clear();

  __CPP_REDIS_LOG(debug, "cpp_redis::network::redis_connection disconnected");

cblauvelt avatar Jan 29 '18 02:01 cblauvelt

Hi @cblauvelt ,

Sorry to hear you encountered an issue while using cpp_redis.

I tried your example on my side using the same flags, except that I compiled in C++11 (seems you compiled in C++14 in order to use std::make_unique?). On my side, the program runs fine and returns the right output.

May I know which version of cpp_redis are you using? Are you using the tacopie version that comes with the library or a different version? What is your programming environment (system / compiler / any other relevant information)?

Thanks

Cylix avatar Jan 29 '18 07:01 Cylix

Thank you for the quick reply.

I created a docker image that should allow you to see the error. I am actually using C++17.

I compiled the cpp_redis source using the following commands:

git clone https://github.com/Cylix/cpp_redis.git
cd cpp_redis
git submodule init && git submodule update
docker container run -i --rm --name builder -v ${PWD}:/opt/projects/src:ro -v build:/opt/projects/build cblauvelt/cpp17dev ./cmakeit -DCMAKE_BUILD_TYPE=debugfull -DLOGGING_ENABLED=1

Then from my directory in 'c:\projects\playground\cpp-redis\client' I executed the following:

docker container run -i --rm --name builder -v c:\projects\playground\cpp-redis\client:/opt/projects/src:ro -v c:\projects\playground\cpp-redis\client/build:/opt/projects/build -v /C/projects/cpp_redis/includes/cpp_redis:/usr/include/cpp_redis:ro -v /C/projects/tacopie/includes/tacopie:/usr/include/tacopie:ro -v /C/projects/cpp_redis/build/lib:/usr/lib/cpp_redis:ro cblauvelt/cpp17dev-ubuntu ./cmakeit -DCMAKE_BUILD_TYPE=debugfull

Start redis:

docker container run -d --rm --name redis -p 6379:6379 redis:4.0-alpine

Run client program:

docker container run -i --rm -v c:\projects\playground\cpp-redis\client/build/:/opt/projects/build --name cpp-redis-client --net=host pygmy/alpine-tini:latest /opt/projects/build/cpp-redis-client

Below is my CMakeLists.txt file for your reference:

cmake_minimum_required(VERSION 3.9)
project(cpp-redis-client)

# define project variables
set(TARGET_NAME ${PROJECT_NAME})

if(${UNIX})
    message("Setting up for Unix Environment")

    set( THREAD_CXX_FLAGS "-pthread")

    set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")

    set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${THREAD_CXX_FLAGS}" )

    find_library(CPP_REDIS_LIB_PATH NAMES "cpp_redis" PATHS "/usr/lib/cpp_redis")
    find_library(TACOPIE_LIB_PATH NAMES "tacopie" PATHS "/usr/lib/cpp_redis")

    add_definitions( "-DASIO_STANDALONE" )

    include_directories("vendor" ${CMAKE_SOURCE_DIR})

    # Set optimization strategy
    if(${OPTIMIZE_FOR_SIZE})
        message("Optimizing for size.")
        set( OPTIMIZE_FLAGS "-Os")
    else(${OPTIMIZE_FOR_SIZE})
        message("Optimizing for speed.")
        set( OPTIMIZE_FLAGS "-O3")
    endif(${OPTIMIZE_FOR_SIZE})

    set(CMAKE_EXE_LINKER_FLAGS "-static")

else(${UNIX})
    message( FATAL_ERROR "Non-unix build is not supported. Feel free to add one.")

endif(${UNIX})

set(SOURCE_FILES
    main.cpp
)

include_directories( "${CMAKE_SOURCE_DIR}/vendor" )

add_executable(${TARGET_NAME} ${SOURCE_FILES})

link_directories(${CPP_REDIS_LIB_PATH})

target_link_libraries(${TARGET_NAME} ${CPP_REDIS_LIB_PATH} ${TACOPIE_LIB_PATH})

cblauvelt avatar Feb 03 '18 23:02 cblauvelt

Awesome, I'll try that ASAP and let you know when I got fresh news about this issue!

Cylix avatar Feb 04 '18 19:02 Cylix

Just note to myself: someone reported me by email an issue on tacopie due to concurrency if the tcp client is disconnected while reading or writing (connection closed by remote server). In such case, the client is disconnected without waiting for io_service callback cleanup and the reading or writing callback might executed right after the client is destroyed. This may be related and possibly fix by the incoming tacopie fix.

Cylix avatar Feb 09 '18 07:02 Cylix

hi, are you still getting on with this issue?

lvpidadiao avatar Mar 19 '18 06:03 lvpidadiao

Yes. I cannot figure out what the problem is.

On Mon, Mar 19, 2018 at 2:52 AM, lvpidadiao [email protected] wrote:

hi, are you still getting on with this issue?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/Cylix/cpp_redis/issues/156#issuecomment-374116726, or mute the thread https://github.com/notifications/unsubscribe-auth/AB-LqqrOcWZNS143WwXl1sKJAstTuwAxks5tf1WjgaJpZM4Rv4qm .

cblauvelt avatar Mar 19 '18 12:03 cblauvelt