Skip to content

Commit cea300d

Browse files
author
Minggang Wang
committed
Fix double-free when using typed array
This patch enables to transfer the ownership of ArrayBuffer to v8 when deserializing the messages, which has type of TypedArray. This will avoid double-free when the v8 executes gc. Fix #673
1 parent 158aad0 commit cea300d

File tree

2 files changed

+8
-5
lines changed

2 files changed

+8
-5
lines changed

rosidl_gen/templates/message.dot

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ class {{=objectWrapper}} {
460460
if (refObject.{{=field.name}}.size != 0) {
461461
{{=getWrapperNameByType(field.type)}}.ArrayType.freeArray(refObject.{{=field.name}});
462462
if ({{=getWrapperNameByType(field.type)}}.ArrayType.useTypedArray) {
463-
deallocator.delayFreeStructMember(refObject.{{=field.name}}, {{=getWrapperNameByType(field.type)}}.refObjectArrayType, 'data');
463+
// Do nothing, the v8 will take the ownership of the ArrayBuffer used by the typed array.
464464
} else {
465465
deallocator.freeStructMember(refObject.{{=field.name}}, {{=getWrapperNameByType(field.type)}}.refObjectArrayType, 'data');
466466
}

src/rcl_bindings.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1318,12 +1318,15 @@ NAN_METHOD(FreeMemeoryAtOffset) {
13181318
}
13191319

13201320
NAN_METHOD(CreateArrayBufferFromAddress) {
1321-
auto address = GetBufAddr(info[0]);
1321+
char* addr = GetBufAddr(info[0]);
13221322
int32_t length = Nan::To<int32_t>(info[1]).FromJust();
13231323

1324-
auto array_buffer =
1325-
v8::ArrayBuffer::New(v8::Isolate::GetCurrent(), address, length,
1326-
v8::ArrayBufferCreationMode::kExternalized);
1324+
// We will create an ArrayBuffer with mode of
1325+
// ArrayBufferCreationMode::kInternalized and copy data starting from |addr|,
1326+
// thus the memory block will be collected by the garbage collector.
1327+
v8::Local<v8::ArrayBuffer> array_buffer =
1328+
v8::ArrayBuffer::New(v8::Isolate::GetCurrent(), addr, length,
1329+
v8::ArrayBufferCreationMode::kInternalized);
13271330

13281331
info.GetReturnValue().Set(array_buffer);
13291332
}

0 commit comments

Comments
 (0)