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

hiredis core on redisReaderFree #583

Closed
wsrunquickly opened this issue Mar 30, 2018 · 2 comments
Closed

hiredis core on redisReaderFree #583

wsrunquickly opened this issue Mar 30, 2018 · 2 comments

Comments

@wsrunquickly
Copy link

wsrunquickly commented Mar 30, 2018

my program got corruption when called redisFree after i send command failed,If so, please deliver me out of this maze and show me the way,here is my call-stack and code:
——————————————————————————————————————————
#0 0x0000003275832925 in raise () from /lib64/libc.so.6
#1 0x0000003275834105 in abort () from /lib64/libc.so.6
#2 0x0000003275870837 in __libc_message () from /lib64/libc.so.6
#3 0x0000003275876166 in malloc_printerr () from /lib64/libc.so.6
#4 0x00000000006d5a48 in redisReaderFree () at read.c:440
#5 0x00000000006cfcae in redisFree ()
#6 0x00000000006b9f4b in bfd::codis::CodisClient::RedisCommand(std::vector<std::basic_string<char, std::char_traits, std::allocator >, std::allocator<std::basic_string<char, std::char_traits, std::allocator > > > const&, int) () at src/CodisClient.cpp:1022
#7 0x00000000006ba396 in bfd::codis::CodisClient::RedisCommand(bfd::codis::Command&, int) ()
at src/CodisClient.cpp:1037
#8 0x00000000006bb56e in bfd::codis::CodisClient::get(std::basic_string<char, std::char_traits, std::allocator >, std::basic_string<char, std::char_traits, std::allocator >&, int) ()
at src/CodisClient.cpp:158
#9 0x00000000006b5045 in bfd::codis::BfdCodis::get(std::basic_string<char, std::char_traits, std::allocator >, std::basic_string<char, std::char_traits, std::allocator >&, int) ()
at src/BfdCodis.cpp:70
#10 0x000000000052d16a in FunctionCache::GetCacheResponse(int, char*, int, char*&, int&) ()
#11 0x000000000055530f in TransferThread(void*) ()
#12 0x0000003275c079d1 in start_thread () from /lib64/libpthread.so.0
#13 0x00000032758e8b6d in clone () from /lib64/libc.so.6

——————————————————————————————————————————————

reply = (redisReply*)redisCommandArgv(redis, argv.size(), &argv[0], &arglen[0]);
    //
    if (!reply)
    {
        bool result = m_ConnPool->Reconnect(redis);
        if (result)
        {
            redisSetTimeout(redis,tv);
            reply = (redisReply*)redisCommandArgv(redis, argv.size(), &argv[0], &arglen[0]);
        }
        else
        {
            redis = NULL;
            LogUtil::writeErrorMsg("[Codis_client] reconnect faild!");
            Reply reply;
            reply.SetErrorMessage("[Codis_client] reconnect faild!");
            reply.SetType(Reply::CONNECTERROR);
            pthread_rwlock_unlock(&p_rwlock);
            return reply;
        }
    }

    //
    if (!reply)
    {
        redisFree(redis); //    HERE I GOT THE corruption
        redis = NULL;
        LogUtil::writeInfoMsg("[Codis_client] Do Command faild");
        Reply reply;
        reply.SetErrorMessage("Do Command faild.");
        pthread_rwlock_unlock(&p_rwlock);
        return reply;
    }
@wsrunquickly
Copy link
Author

wsrunquickly commented Mar 30, 2018

ps: here is the m_ConnPool->Reconnect

bool RedisClientPool::Reconnect(redisContext* rc)
{
	ScopedLock lock(unUsedMutex_);
	Destroy(rc);
	try
	{
		rc = redisConnect(address_.c_str(), port_);
        if (rc == NULL)
        {
            LogUtil::writeErrorMsg("[Codis_client] reconnect Error with no return!");

            return false;
        }

        LogUtil::writeErrorMsg("[Codis_client] connect redisContext->err: %d", rc->err);
        

		if (rc != NULL && rc->err != 0)
		{
            LogUtil::writeErrorMsg("[Codis_client] reconnect Error:  %s", rc->errstr);
			
			redisFree(rc);
			return false;
		}

	} catch (std::exception &e)
	{
        LogUtil::writeErrorMsg("[Codis_client] reconnect server faild!!");

		return false;
	}
	return true;
}

@michael-grunder
Copy link
Collaborator

Hi,

It's not going to be easy for anyone to help track down your problem from the code you posted, as the corruption could be happening anywhere.

From your first issue, I see that you're using hiredis in a multithreaded context, so my instinct is always to suspect that as a potential cause of troubles (data races, synchronization, etc).

This jumps out at me:

bool RedisClientPool::Reconnect(redisContext* rc)

You're passing a redisContext * into that function and then setting it like so:

		rc = redisConnect(address_.c_str(), port_);

Unless there is some missing context here, this seems wrong. In order to use that pointer outside of the function, you would have to pass in a redisContext **, in order for the change in location to survive the local function.

That being said, have you tried running your program under valgrind to see what errors are reported? It should at least point you in the right direction.

Cheers!
Mike

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