Print() giving assertion when printing an object from a custom function - firefox

Ok so i have this function in the engine
static bool
myTestFunction(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
int length = args.length();
if (length==2)
{
if (args.get(1).isObject())
{
RootedObject obj4(cx,&args.get(1).toObject());
args.rval().setObject(*obj4);
}
}
return true;
}
and this statement in the js script
var obj = {ss:"qq"};
var handler = {tt:"vv"};
var prox1 = myTestFunction(obj,handler);
print(prox1);
So the problem is in the last line basically i am just trying to return the second argument but when i print the variable it is giving me this assertion failure
Assertion failure: mStatementDone != reinterpret_cast<bool*>(uintptr_t(-1)), at ../../../dist/include/mozilla/GuardObjects.h:95
Segmentation fault (core dumped)
Now i am really new to SpiderMonkey Engine and have checked everything but haven't been able to figure out what's wrong here. Any help would be really appreciated.

Related

Crashes after parsing the equation

The application want to parse a string equation to mathematics and return the data to user. for this purpose the library is used is exprtk
for easy analysis I have shared minimum working code
minimum working code
when application parses the string to code back to back [multithreaded but locked]
void reset()
{
// Why? because msvc doesn't support swap properly.
//stack_ = std::stack<std::pair<char,std::size_t> >();
/**
it was crashing on destructor on ~deque()
stating memory reallocation
so I change it to pop so for now this has been resolved
*/
while(stack_.size()) stack_.pop();
state_ = true;
error_token_.clear();
}
now the code always crashes on
static inline void destroy(control_block*& cntrl_blck)
{
if (cntrl_blck)
{
/**now crashes on this condition check*/
if ( (0 != cntrl_blck->ref_count) && (0 == --cntrl_blck->ref_count) )
{
delete cntrl_blck;
}
cntrl_blck = 0;
}
}
UPDATE
pastebin code updated new code with main has been added with main and minimum working code.
all the shared_ptr has been removed. now they are normal objects.
as for exprtk reset function has been changed to original one
void reset()
{
// Why? because msvc doesn't support swap properly.
stack_ = std::stack<std::pair<char,std::size_t> >();
state_ = true;
error_token_.clear();
}
and backtrace of gdb has been added backtrace

nodejs native addon : how to modify the value of c++ object's member contained in another native addon

First some context, i got two nodejs native addon. The first one contains a static c++ object "Conn" exposed using an v8 object internal field as described in the embedder's guide
NAN_METHOD(cobject) {
auto isolate = Isolate::GetCurrent();
Conn* p = &ConnHolder::connection;
Local<ObjectTemplate> conn_templ = ObjectTemplate::New(isolate);
conn_templ->SetInternalFieldCount(1);
Local<Object> obj = conn_templ->NewInstance();
obj->SetInternalField(0, External::New(isolate, p));
info.GetReturnValue().Set(obj);
}
In my other native addon, i'm loading the first one using c++ code and i expose a function called test containing two calls on the Conn object "callToDummyFunction()" and "callToFunctionWithMemberAccess()"
// persistent handle for the main addon
static Persistent<Object> node_main;
void Init(v8::Local<v8::Object> exports, v8::Local<v8::Object> module) {
Isolate* isolate = Isolate::GetCurrent();
HandleScope scope(isolate);
// get `require` function
Local<Function> require = module->Get(String::NewFromUtf8(isolate, "require")).As<Function>();
Local<Value> args[] = { String::NewFromUtf8(isolate, "path_to_my_addon\\addon.node") };
Local<Object> main = require->Call(module, 1, args).As<Object>();
node_main.Reset(isolate, main);
NAN_EXPORT(exports, test);
}
NAN_METHOD(test) {
Isolate* isolate = Isolate::GetCurrent();
HandleScope scope(isolate);
// get local handle from persistent
Local<Object> main = Local<Object>::New(isolate, node_main);
// get `cobject` function to get pointer from internal field
Local<Function> createdMain = main->Get(String::NewFromUtf8(isolate, "cobject")).As<Function>();
Local<Object> callResult = createdMain->Call(main, 0, nullptr).As<Object>();
Local<Object> self = info.Holder();
Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
void* ptr = wrap->Value();
// from there i get a pointer to my Conn object
Conn* con = static_cast<Conn*>(ptr);
conn->callToDummyFunction();
conn->callToFunctionWithMemberAccess();
info.GetReturnValue().Set(10);
}
Then i'm launching a nodejs session using "node", i load the first and second addon using two require calls and finally i'm calling the method test on the second addon.
The method test is executed, the call to "callToDummyFunction" is executed successfully but the call to "callToFunctionWithMemberAccess" crash and also kill the node session.
Ok, so what is the difference between "callToDummyFunction" and "callToFunctionWithMemberAccess" ?
bool Conn::callToDummyFunction()
{
cout << "callToDummyFunction" << endl;
return true;
}
bool Conn::callToFunctionWithMemberAccess()
{
cout << "callToFunctionWithMemberAccess " << someIntMember << endl;
return true;
}
So, it seems accessing a member of the Conn object generate an error and crash the node session. The node session does not output any message before crashing.
Can someone tell me why?
And/Or
How to get an error message ?
I'm answering my own question. In fact, i'm stupid but at least my stupidity made me learn some strange cpp things.
So, first of all the stupid answer. Instead of using my returned object i'm using a totaly unrelated object :(
Local<Object> callResult = createdMain->Call(main, 0, nullptr).As<Object>();
Local<Object> self = info.Holder();
Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
Why using
Local self = info.Holder();
instead of callResult. The right code would be
Local<Object> callResult = createdMain->Call(main, 0, nullptr).As<Object>();
Local<External> wrap = Local<External>::Cast(callResult->GetInternalField(0));
What did i learn from this stupid mistake:
read your code carefully (obvious)
executing member function on nullptr actualy works if there isn't any member access in the function (maybe it's obvious for an experienced cpp dev)
Native Addons live in their own vm, static fields aren't shared between vms.

Basic programming sample of OpenCL from Apple fails to run on GPU

I started learning some basics about OpenCL a while ago and decided to give the "Basic programming sample" from Apple a go. I runs OK on CPU, but when I select GPU as the target device I get err = -45 from
err = gclExecKernelAPPLE(k, ndrange, &kargs);
This error code translates to CL_INVALID_PROGRAM_EXECUTABLE. Any idea how can I correct the sample code?
Automatically generated kernel.cl.c code looks like this (+ includes on top):
static void initBlocks(void);
// Initialize static data structures
static block_kernel_pair pair_map[1] = {
{ NULL, NULL }
};
static block_kernel_map bmap = { 0, 1, initBlocks, pair_map };
// Block function
void (^square_kernel)(const cl_ndrange *ndrange, cl_float* input, cl_float* output) =
^(const cl_ndrange *ndrange, cl_float* input, cl_float* output) {
int err = 0;
cl_kernel k = bmap.map[0].kernel;
if (!k) {
initBlocks();
k = bmap.map[0].kernel;
}
if (!k)
gcl_log_fatal("kernel square does not exist for device");
kargs_struct kargs;
gclCreateArgsAPPLE(k, &kargs);
err |= gclSetKernelArgMemAPPLE(k, 0, input, &kargs);
err |= gclSetKernelArgMemAPPLE(k, 1, output, &kargs);
gcl_log_cl_fatal(err, "setting argument for square failed");
err = gclExecKernelAPPLE(k, ndrange, &kargs);
gcl_log_cl_fatal(err, "Executing square failed");
gclDeleteArgsAPPLE(k, &kargs);
};
// Initialization functions
static void initBlocks(void) {
const char* build_opts = " -cl-std=CL1.1";
static dispatch_once_t once;
dispatch_once(&once,
^{ int err = gclBuildProgramBinaryAPPLE("OpenCL/kernel.cl", "", &bmap, build_opts);
if (!err) {
assert(bmap.map[0].block_ptr == square_kernel && "mismatch block");
bmap.map[0].kernel = clCreateKernel(bmap.program, "square", &err);
}
});
}
__attribute__((constructor))
static void RegisterMap(void) {
gclRegisterBlockKernelMap(&bmap);
bmap.map[0].block_ptr = square_kernel;
}
I saw this same problem when running under 10.7.3, while a machine on 10.7.5 worked fine. I noticed the CVMCompiler process was crashing after each invocation of my app.
Inspecting the stack trace, I noticed it was crashing when trying to parse the bitcode for compilation into native code. Since the parsing of the bitcode failed failed, there was no resulting compiled program for gclExecKernelAPPLE() to execute, hence the error.
Try upgrading to 10.7.5, or indeed 10.8 and the problem should go away. (I just tested this and it does indeed fix the problem.)

Safari plugin crashes on NPN_GetValue

My plugin code crashes when I call the NPN_GetValue. Basically I created a scriptable object which has a 'getDevice' method that can return a device array to JavaScript. Below is the code snippet.
static bool mainNPObjectInvoke(NPObject *obj, NPIdentifier identifier, const NPVariant *args, uint32_t argCount, NPVariant *result)
{
printf("create main object");
MainNPObject *mainObject = (MainNPObject *)obj;
if (identifier == methodIdentifiers[METHOD_ID_GET_DEVICES])
{
NPObject *windowObj = NULL;
browser->getvalue(mainObject->npp, NPNVWindowNPObject, &windowObj);
// it crashed here
....
}
}
I created the MainNPObject instance with below method.
NPObject *createMainNPObject(NPP npp)
{
MainNPObject *object = (MainNPObject *)browser->createobject(npp, &mainNPClass);
object->npp = npp;
theMainObject = object;
return (NPObject *)object;
}
The createMainNPObject is called in the plugin function I provided to browser.
NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value)
{
PluginObject *obj = instance->pdata;
switch (variable) {
case NPPVpluginCoreAnimationLayer:
if (!obj->rootLayer)
setupLayerHierarchy(obj);
*(CALayer **)value = obj->rootLayer;
return NPERR_NO_ERROR;
case NPPVpluginScriptableNPObject:
if (!obj->mainObject)
{
obj->mainObject = createMainNPObject(instance);
}
....
}
And the allocate function is as below.
static NPObject *mainNPObjectAllocate(NPP npp, NPClass *class)
{
initializeIdentifiers();
MainNPObject *mainObject = malloc(sizeof(MainNPObject));
mainObject->deviceManager = [[DeviceManager alloc] init];
return (NPObject *)mainObject;
}
Definition of MainNPObject:
typedef struct
{
NPObject *npobject;
NPP npp;
DeviceManager *deviceManager;
} MainNPObject;
By debugging the code, I found that the system raised an EXC_BAD_ACCESS when calling the browser->getValue and it looks like the npp pointer is invalid.
0x00007fff83f82dab <+0019> je 0x7fff83f82db9 <_ZN6WebKit14NetscapePlugin7fromNPPEP4_NPP+33>
0x00007fff83f82dad <+0021> incl 0x8(%rax)
Can someone help me out?
Thanks!
Hmm; not seeing anything obvious. Try adding another parameter (an int?) to your structure and set it during allocate or immediately afterwords, then later on check to see if it's still the value you set before you call getvalue. See if your struct is somehow getting corrupt. That happened to me once when I was casting the NPObject funny in a non-obvious way.

Substituting `find_if` function

I wrote a class method using STL find_if. The code is the following:
void
Simulator::CommunicateEvent (pEvent e)
{
pwEvent we (e);
std::list<pEvent> l;
for (uint32_t i = 0; i < m_simulatorObjects.size (); i++)
{
l = m_simulatorObjects[i]->ProcessEvent (we);
// no action needed if list is empty
if (l.empty ())
continue;
// sorting needed if list comprises 2+ events
if (l.size () != 1)
l.sort (Event::Compare);
std::list<pEvent>::iterator it = m_eventList.begin ();
std::list<pEvent>::iterator jt;
for (std::list<pEvent>::iterator returnedElementIt = l.begin ();
returnedElementIt != l.end ();
returnedElementIt++)
{
// loop through the array until you find an element whose time is just
// greater than the time of the element we want to insert
Simulator::m_eventTime = (*returnedElementIt)->GetTime ();
jt = find_if (it,
m_eventList.end (),
IsJustGreater);
m_eventList.insert (jt, *returnedElementIt);
it = jt;
}
}
}
Unfortunately, I later discovered that the machine that will run the code is equipped with the libstdc++ library version 4.1.1-21, which apparently is lacking find_if. Needless to say, I cannot upgrade the library, nor can I ask someone to do it.
When compiling, the error I get is:
simulator.cc: In member function ‘void sim::Simulator::CommunicateEvent(sim::pEvent)’:
simulator.cc:168: error: no matching function for call to ‘find_if(std::_List_iterator<boost::shared_ptr<sim::Event> >&, std::_List_iterator<boost::shared_ptr<sim::Event> >, sim::Simulator::<anonymous struct>&)’
simulator.cc: In static member function ‘static void sim::Simulator::InsertEvent(sim::pEvent)’:
simulator.cc:191: error: no matching function for call to ‘find_if(std::_List_iterator<boost::shared_ptr<sim::Event> >&, std::_List_iterator<boost::shared_ptr<sim::Event> >, sim::Simulator::<anonymous struct>&)’
make: *** [simulator.o] Error 1
How can I solve the problem?
I thought I could define a find_if function as described here. However, I have some concerns:
What about performance? The function that makes use of find_if needs to be as efficient as possible.
How can I do conditional compilation? I couldn't find a macro telling the version of the libstdc++ installed.
What are your thoughts about it?
TIA,
Jir
References
Source files: simulator.h and simulator.cc
Solution
Defined IsJustGreater outside the Simulator class and declared IsJustGreater_s friend of Simulator:
struct IsJustGreater_s : public std::unary_function<const pEvent, bool> {
inline bool operator() (const pEvent e1) {return (e1->GetTime () > Simulator::m_eventTime);}
} IsJustGreater;
Called IsJustGreater in find_if this way:
jt = find_if (it, m_eventList.end (), sim::IsJustGreater);
From the error, it appears that you're attempting to use an anonymous type as the argument. I do not believe anonymous types are allowed to be template arguments.
From the error, I believe you have something like this:
class Simulator {
struct {
bool operator(const pEvent& p) { ... } ;
} IsJustGreater;
}
what you want is to give it a name and then change the find_if to instantiate the class (see below)
class Simulator {
// class is now an inner named-class
struct IsJustGreater {
bool operator(const pEvent& p) { ... } ;
};
}
// This is how you use the class
jt = std::find_if(it, m_eventList.end(), IsJustGreater() );
I see that you're using the std:: qualifier before std::list but not std::find_if. Try putting the std:: in front so that the compiler can find it within the namespace.

Resources