镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

v8::internal::JSReceiver::DefineOwnProperty exception cause a crash #14335

Closed

Description

@kisondu
  • Version: node-v6.10.2
  • Platform: CentOS 7.1

my issue details :

  • stack info:
(gdb) bt
#0  0x0000000000d577ca in operator* (this=<optimized out>) at ../deps/v8/src/handles.h:50
#1  operator* (this=<optimized out>) at ../deps/v8/src/handles.h:114
#2  operator-> (this=<optimized out>) at ../deps/v8/src/handles.h:110
#3  v8::internal::JSArray::DefineOwnProperty (isolate=0x3c0acf0, o=..., name=..., desc=0x7fffc1a5ae60, should_throw=v8::internal::Object::THROW_ON_ERROR) at ../deps/v8/src/objects.cc:6877
#4  0x0000000000d57a1d in v8::internal::JSReceiver::DefineOwnProperty (isolate=isolate@entry=0x3c0acf0, object=..., object@entry=..., key=..., key@entry=..., desc=desc@entry=0x7fffc1a5ae60, 
    should_throw=should_throw@entry=v8::internal::Object::THROW_ON_ERROR) at ../deps/v8/src/objects.cc:6444
#5  0x0000000000d57b34 in v8::internal::JSReceiver::DefineProperty (isolate=isolate@entry=0x3c0acf0, object=object@entry=..., key=..., key@entry=..., attributes=..., attributes@entry=...)
    at ../deps/v8/src/objects.cc:6348
#6  0x0000000000e6a83a in __RT_impl_Runtime_ObjectDefineProperty (isolate=0x3c0acf0, args=...) at ../deps/v8/src/runtime/runtime-object.cc:1239
#7  v8::internal::Runtime_ObjectDefineProperty (args_length=<optimized out>, args_object=0x7fffc1a5afa8, isolate=0x3c0acf0) at ../deps/v8/src/runtime/runtime-object.cc:1233
  • v8/src/objects.cc :
Maybe<bool> JSArray::DefineOwnProperty(Isolate* isolate, Handle<JSArray> o,
                                       Handle<Object> name,
                                       PropertyDescriptor* desc,
                                       ShouldThrow should_throw) {
  // 1. Assert: IsPropertyKey(P) is true. ("P" is |name|.)
  // 2. If P is "length", then:
  // TODO(jkummerow): Check if we need slow string comparison.
  if (*name == isolate->heap()->length_string()) {
    // 2a. Return ArraySetLength(A, Desc).
    return ArraySetLength(isolate, o, desc, should_throw);
  }
  // 3. Else if P is an array index, then:
  uint32_t index = 0;
  if (PropertyKeyToArrayIndex(name, &index)) {
    // 3a. Let oldLenDesc be OrdinaryGetOwnProperty(A, "length").
    PropertyDescriptor old_len_desc;
    Maybe<bool> success = GetOwnPropertyDescriptor(
        isolate, o, isolate->factory()->length_string(), &old_len_desc);
    // 3b. (Assert)
    DCHECK(success.FromJust());
    USE(success);
    // 3c. Let oldLen be oldLenDesc.[[Value]].
    uint32_t old_len = 0;
    **CHECK(old_len_desc.value()->ToArrayLength(&old_len));**

The crash reason: old_len_desc.value() is null.
The macro ASSIGN_RETURN_ON_EXCEPTION condition is true in the Object :: GetPropertyWithAccessor
, returns an empty object, why?

Activity

  1. TimothyGu commented on Jul 18, 2017

    @TimothyGu
    Member

    Can you provide a reproducible test case?

  2. kisondu commented on Jul 18, 2017

    @kisondu
    Author

    @TimothyGu
    The probability of 50% appears. I suspect that isolate usage is problematic,trouble to help me check the following code,thanks

    void AsyncDBWrap::PushQuery(const v8::FunctionCallbackInfo<v8::Value>& args)
    {
    	Isolate* isolate = args.GetIsolate();
    	
        AsyncDBWrap* db_wrap = ObjectWrap::Unwrap<AsyncDBWrap>(args.This());
        if (!db_wrap || !db_wrap->m_db)
        {
    		isolate->ThrowException(Exception::TypeError(String::NewFromUtf8(isolate, "err parameters for NewRouter")));
    		args.GetReturnValue().Set(Number::New(isolate, -1));
    		return;
        }
    
        if (!args[0]->IsString())
        {
    		isolate->ThrowException(Exception::TypeError(String::NewFromUtf8(isolate, "push query parameters error")));
    		args.GetReturnValue().Set(Number::New(isolate, -2));
    		return;
        }
    
        std::string sql = std::string(*String::Utf8Value(args[0]->ToString()));
        bool cb_able = true;
        ResHandler cb = nullptr;
        
        if (args.Length() >= 2)
        { 
            uint32_t cbId = ++m_cbOriId;
            Persistent<Function> *f = nullptr;
            if (args[1]->IsFunction())
            {
    			f = new Persistent<Function>(isolate, Local<Function>::Cast(args[1]));
            }
            else if (args[1]->IsBoolean() && args[2]->IsFunction())
            {
                cb_able = args[1]->BooleanValue();
    			f = new Persistent<Function>(isolate, Local<Function>::Cast(args[2]));
            }
            else
            {
    			isolate->ThrowException(Exception::TypeError(String::NewFromUtf8(isolate, "push query parameters error")));
    			args.GetReturnValue().Set(Number::New(isolate, -3));
    			return;
            }
    
            m_cbs.insert(std::make_pair(cbId, f));
    
    
            cb = [cbId](const std::string& err, ResultSetPtr& resPtr, uint64_t count, uint64_t time) -> void
            {
    			Isolate* isolate = Isolate::GetCurrent();
    			EscapableHandleScope handler_scope(isolate);
    
    
                //Local<Object> context = Context::GetCurrent()->Global();
    			Local<Object> context = isolate->GetCurrentContext()->Global();
                const int argc = 4;
                Local<Array> arr = Array::New(isolate, resPtr->rowsCount());
                bool ret = GetV8Res(resPtr, arr);
                if (ret)
                {
                    Handle<Value> argv[argc] = { String::NewFromUtf8(isolate, err.c_str()), handler_scope.Escape(arr), Number::New(isolate,count), Number::New(isolate, time) };
    				Local<Function>::New(isolate, *m_cbs[cbId])->Call(context, argc, argv);
                }
                else
                {
                    Handle<Value> argv[argc] = { String::NewFromUtf8(isolate, "get result error!"), Null(isolate), Null(isolate), Null(isolate) };
    				Local<Function>::New(isolate, *m_cbs[cbId])->Call(context, argc, argv);
                }
    
    			m_cbs[cbId]->Reset();
    			delete m_cbs[cbId];
                m_cbs.erase(cbId);
    
            };
        }
    
    	args.GetReturnValue().Set(Number::New(isolate, db_wrap->m_db->PushQuery(sql, cb, cb_able)));
    }
    
    void AsyncDBWrap::Tick(const v8::FunctionCallbackInfo<v8::Value>& args)
    {
    	Isolate *isolate = args.GetIsolate();
    	bool hasErr = false;
    
        AsyncDBWrap* db_wrap = ObjectWrap::Unwrap<AsyncDBWrap>(args.This());
        if (!db_wrap || !db_wrap->m_db)
        {
    		isolate->ThrowException(Exception::TypeError(String::NewFromUtf8(isolate, "Tick error")));		
    		args.GetReturnValue().Set(Boolean::New(isolate, !hasErr));
    		return;
        }
    
        uint32_t ec = db_wrap->m_db->OnTickResult();
        std::string ec_what;
    
        if (ec == MySqlServerGoneAway)
        {
            ec_what = "MySql server has gone away, reconnect soon.";
            hasErr = true;
        }
        else if (ec)
        {
            ec_what = "db error: " + std::to_string(ec);
            hasErr = true;
        }
    
        if (hasErr)
        {
            if (args[0]->IsFunction())
            {
                const int argc = 1;
                Handle<Value> argv[argc] = { String::NewFromUtf8(isolate, ec_what.c_str()) };
                Handle<Function>::Cast(args[0])->Call(isolate->GetCurrentContext()->Global(), argc, argv);
            }
            else
            {
    			isolate->ThrowException(Exception::TypeError(String::NewFromUtf8(isolate, "Tick error")));
    			args.GetReturnValue().Set(Boolean::New(isolate, !hasErr));
    			return;
            }
        }
    
        //db_wrap->m_dbTask.tick();
    	args.GetReturnValue().Set(Boolean::New(isolate, !hasErr));
    	return;
    }
  3. bnoordhuis commented on Jul 18, 2017

    @bnoordhuis
    Member

    Please move this over to https://github.com/nodejs/help/issues. This bug tracker is for reporting bugs in node.js, not general support.

  4. added
    invalidIssues and PRs that are invalid.
    questionIssues asking questions about Node.js.
    on Jul 18, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    invalidIssues and PRs that are invalid.questionIssues asking questions about Node.js.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions