I am attempting to do some error checking to detect if a javascript callback function called from C++ generates any errors. This code crashes on the v8::String::Utf8Value constructor and I'm at a loss to figure out why.
v8::Locker locker;
v8::HandleScope scope;
v8::TryCatch tryCatch;
v8::Persistent<v8::Function> func = static_cast<PieMenu*> (info.Packet->Control)->m_callback_functions[info.Packet->Integer];
v8::Handle<v8::Value> v = func->Call ((func), 0, NULL);
if (tryCatch.HasCaught()) {
v8::String::Utf8Value exception_str(tryCatch.Exception());
if (exception_str.length() > 0) {
wxLogVerbose(std::string(*exception_str).c_str());
}
}
The error is "Access violation reading location 0x0000000000000027". This leads me to suspect a bad pointer in the exception object, but I'm not sure where else to look. Here is the stack trace:
v8.dll!v8::internal::Execution::ToString(v8::internal::Handle<v8::internal::Object> obj={...}, bool * exc=0x00000000027be8a0)
v8.dll!v8::Value::ToString()
v8.dll!v8::String::Utf8Value::Utf8Value(v8::Handle<v8::Value> obj={...})
I'm using Visual Studio 2008 and the latest trunk v8 code.
From the memory address, it very much looks like as if tries to read an attribute from an object which points to NULL.
I think your Call call is wrong. I remember that I had similar problems when passing NULL as the third parameter, even when you pass 0 arguments. Try this:
v8::Handle<v8::Value> argv;
func->Call ((func), 0, &argv);
Related
I have a structure in C and I called that structure in my go program. If that structure throws any error it terminates my go program like below
orderbook.h
-------------
#ifndef _ORDERBOOK_H
#define _ORDERBOOK_H
typedef struct order order;
struct order {
int tradeid;
int side;
int symbol;
double amount;
double price;
};
orderbook.c
--------------
include "orderbook.h"
order* order_place(char *side,double amount,double price,char symbol[19])
{
struct order *tradeorder= calloc(1000000,sizeof(struct order));//Initlize the structure
//My internal code which place an order
clob_ord_t o=unxs_order(c, (clob_ord_t){CLOB_TYPE_LMT,parsed_side, amount, .lmt =price, .usr = (uintptr_t)out},NANPX);
if (o.qty.dis + o.qty.hid > 0.dd) {
/* put remainder of order into book */
i = clob_add(c, o);
//printf("orderid..%lu\n", i.usr);
printf("orderid..%s\n", i.usr);
insertMap(hashTable, i.usr, i);
// printMap(hashTable);
flag=true;
tradeorder[0].orderstatus=1;
tradeorder[0].orderid=offerid;
tradeorder[0].side=sid;
tradeorder[0].symbol=atoi(symbol);
tradeorder[0].amount=(double)o.qty.dis;
tradeorder[0].price=price;
}
return tradeorder; //return the structure
}
main.go
---------
o:=C.order_place(C.CString("ASK"),C.double(12.0),C.double(1.0),C.CString("1")) //this line may get an exception If some wrong parameter to pass otherwise returns correct value
If I put correct parameter to order_pace function from go there is no issue, If I pass some incorrect parameter then In get an exception an it terminates the go server. Now I need to handle that exception so that my server remain running irrespective of an exception.
You can't catch the fatal fault, and it isn't safe to continue after your C code throws a fault (unlike Go). The running program is in an undefined potentially dangerous state. The safest thing to do is shutdown the program and/or let it crash.
You must check for errors within C.order_place and return an error on failure. Eg, return NULL.
A few other recommendations:
Allocate struct order via Go to rely on the garbage collector to simplify memory management.
var order C.struct_order
C.order_place(&order, side, ...)
Always free strings allocated via C.CString once they are no longer needed.
cstr := C.CString("test")
C.free(unsafe.Pointer(cstr))
Depending on your platform, you can simplify debugging with improved stack traces by importing cgosymbolizer. This adds support for C stack traces.
import _ "github.com/ianlancetaylor/cgosymbolizer"
You probably should use char *symbol instead of char symbol[19] in your example since C.CString returns a pointer to an arbitrarily long C string, not a pointer to an array of 19 chars.
I’m developing a system for our application to get data from an external device. As soon as I send it a specific message, it sends back short messages to us 10x/second (so about 1 message per 100 milliseconds). I’m using Boost for this communication.
The process is rather simple: I create the socket, send the message, giving it a handler for the message receive:
// Header file:
...
std::unique_ptr<boost::asio::io_service> _theIOService;
std::unique_ptr<boost::asio::ip::tcp::socket> _theSocket;
int size_of_the_data = 100;
std::vector<char> _raw_buffer = std::vector<char>(size_of_the_data);
boost::asio::mutable_buffers_1 _data_buffer = boost::asio::buffer(_raw_buffer, size_of_the_data);
...
// Implementation file:
...
void DeviceDataListener::initiateTransfer() {
// create and connect the socket up here
...
// send the message
boost::system::error_code error;
boost::asio::write(*_theSocket,
boost::asio::buffer(beginMessage),
boost::asio::transfer_all(), error);
// start the receive
auto handler = boost::bind(&SCUDataListener::dataHandler, this, _1, _2);
_theSocket->async_receive( _data_buffer, handler );
std::thread run_thread([&]{ _theIOService->run(); });
...
}
void DeviceDataListener::dataHandler (
const boost::system::error_code& error, // Result of operation.
std::size_t bytes_transferred // Number of bytes received.
) {
int foo = bytes_transferred;
// this line crashes application
char* pData = static_cast<char*>(_data_buffer.data());
}
It works, my handler gets called immediately, as it should. The problem is, I can’t get the data out of _data_buffer. This:
auto it = _data_buffer.begin();
causes a crash, even though _data_buffer is valid. This:
const char* pData = static_cast<char*>(_data_buffer.data());
won’t compile. The error is “Method 'data' could not be resolved”. The mutable_buffer_1 API says data() is a completely valid method that returns the beginning of the memory range.
Inspecting via a debugger, I can see that there is no error and I can see data as a member of _data_buffer and the memory address it contains does contain the data we’re expecting. The thing is, I can’t get to it via code. Does anyone know how to get to the data in a Boost mutable_buffers_1?
We’re using Eclipse CDT, C++11 and gcc running on Linux.
“Method 'data' could not be resolved”.
this error may be true, but it depends on what version of Boost you use. data() is member of mutable_buffer since >= 1.66 version. Because mutable_buffer is the base class for mutable_buffers_1 your code should compile if you use at least 1.66 version of Boost.
If your version is < 1.66 you should use
char* p1 = boost::asio::buffer_cast<char*>(_data_buffer);
to get the pointer to data in the buffer.
_data_buffer.begin();
you should not use begin() method, it returns pointer to mutable_buffer_1 itself. This method is used by internal functions of asio-boost library, for instance to copy sequence of buffers, then begin() points the particular buffer to be copied.
I'm writing an Windows phone application with C++/CX. The function tries to copy input array to output array asynchronously:
IAsyncAction CopyAsync(const Platform::Array<byte, 1>^ input, Platform::WriteOnlyArray<byte, 1>^ output)
{
byte *inputData = input->Data;
byte *outputData = output->Data;
int byteCount = input->Length;
// if I put it here, there is no error
//memcpy_s(outputData, byteCount, inputData, byteCount);
return concurrency::create_async([&]() -> void {
memcpy_s(outputData, byteCount, inputData, byteCount); // access violation exception
return;
});
}
This function compiles but cannot run correctly and produces an "Access violation exception". How can I modify values in the output array?
This is Undefined Behaviour: by the time you use your 3 captured (by reference) variables inputData/outputData/byteCount in the lambda, you already returned from CopyAsync and the stack has been trashed.
It's really the same issue as if you returned a reference to a local variable from a function (which we know is evil), except that here the references are hidden inside the lambda so it's a bit harder to see at first glance.
If you are sure that input and output won't change and will still be reachable between the moment you call CopyAsync and the moment you run the asynchronous action, you can capture your variables by value instead of by reference:
return concurrency::create_async([=]() -> void {
// ^ here
memcpy_s(outputData, byteCount, inputData, byteCount);
return;
});
Since they're only pointers (and an int), you won't be copying the pointed-to data, only the pointers themselves.
Or you could just capture input and output by value: since they're garbage-collected pointers this will at least make sure the objects are still reachable by the time you run the lambda:
return concurrency::create_async([=]() -> void {
memcpy_s(output->Data, input->Length, input->Data, input->Length);
return;
});
I for one prefer this second solution, it provides more guarantees (namely, object reachability) than the first one.
I have loaded an "arial.ttf" file (taken from my /Windows/Fonts folder) into memory, however passing this into FT_New_Memory_Face crashes (somewhere in FT_Open_Face). I am not able to debug this, any clues as to what I might be doing wrong?
unsigned char *fontBuffer = LoadFile("arial.ttf");
zip_uint64_t fSize = GetFileSize("arial.ttf");
FT_Library library; /* handle to library */
FT_Face face;
int error = FT_Init_FreeType( &library );
if( error != 0 )
printf("FT_Init_FreeType failed");
error = FT_New_Memory_Face( library,
(FT_Byte*)fontBuffer,
fSize,
0,
&face );
It turns out the problem was on my end, particularly, the LoadFile method was returning memory from the stack, rather than the heap. The library works fine. Thanks!
I searched for the answer for 1 day. The problem was in note section.
https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_New_Memory_Face
You must not deallocate the memory before calling FT_Done_Face.
FreeType don't copying buffer and uses pointer that you send to FT_New_Memory_Face
In Win32 in order to paste data into the clipboard I have to call GlobalAlloc(), then GlobalLock() to obtain a pointer, then copy data, then call GlobalUnlock() and SetClipboardData().
If the code is in C++ an exception might be thrown between calls to GlobalLock() and GlobalUnlock() and if I don't take care of this GlobalUnlock() will not be called.
It this a problem? What exactly happens if I call GlobalLock() and for whatever reason skip a pairing GlobalUnlock() call?
The Question is not only about if or if not you call GlobalUnlock(). You must call GlobalUnlock() and GlobalFree(). Both must be called in order to release the memory you allocated:
HGLOBAL hdl = NULL;
void *ptr = NULL
try {
hdl = GlobalAlloc();
ptr = GlobalLock(hdl);
// etc...
GlobalUnlock(hdl);
ptr = NULL;
SetClipboardData(..., hdl );
}
catch (...) {
if(ptr)
GlobalUnlock(hdl);
if(hdl)
GlobalFree(hdl);
throw;
}
The leak would be application wide. When you exit a windows application, all allocated private memory is released automatically