Js-ctypes char readString() makes Mozilla crash - jsctypes

I am using js-sctypes to connect to a shared library in Linux from Firefox.
I am declaring a function from the library as follows:
var read_memory = libc.declare("read_memory", ctypes.default_abi, ctypes.int,
ctypes.uint32_t, ctypes.char.ptr, ctypes.int, ctypes.int);
In C++ library this function is declared as follows:
read_memory(unsigned int address, char *buf, int unit_size, int unit_count)
I am calling the read_memory function in the following way:
var my = new ctypes.char().address();
read_memory(0, my, 4, 1);
st = st + my.readString();
And it works fine, but when I am calling the function with greater unit_size and unit_count, for example read_memory(0, my, 4, 10), the Firefox crashes.
Is it because ctypes.char is limited in size, or there is another reason for this fault?
Any help on this matter would be appreciated.
Thank you.

I had the same problem and the problem is because of character encoding. In my problem I need to convert them from windows-1250 to utf-8.
I used code below:
result = myFunctionToInvoke();
var util = priv.Load("LibToConvert.dll");
var wi12502utf8 = util.declare("win12502utf8", ctypes.default_abi, ctypes.char.ptr, ctypes.char.ptr);
var val = wi12502utf8(result);
result = val.readString();
In this code I created my own lib (LibToConvert.dll) in C++ to convert characters.

Related

node.js c++ addon - afraid of memory leak

first of all I admit I'm a newbie in C++ addons for node.js.
I'm writing my first addon and I reached a good result: the addon does what I want. I copied from various examples I found in internet to exchange complex data between the two languages, but I understood almost nothing of what I wrote.
The first thing scaring me is that I wrote nothing that seems to free some memory; another thing which is seriously worrying me is that I don't know if what I wrote may helps or creating confusion for the V8 garbage collector; by the way I don't know if there are better ways to do what I did (iterating over js Object keys in C++, creating js Objects in C++, creating Strings in C++ to be used as properties of js Objects and what else wrong you can find in my code).
So, before going on with my job writing the real math of my addon, I would like to share with the community the nan and V8 part of it to ask if you see something wrong or that can be done in a better way.
Thank you everybody for your help,
iCC
#include <map>
#include <nan.h>
using v8::Array;
using v8::Function;
using v8::FunctionTemplate;
using v8::Local;
using v8::Number;
using v8::Object;
using v8::Value;
using v8::String;
using Nan::AsyncQueueWorker;
using Nan::AsyncWorker;
using Nan::Callback;
using Nan::GetFunction;
using Nan::HandleScope;
using Nan::New;
using Nan::Null;
using Nan::Set;
using Nan::To;
using namespace std;
class Data {
public:
int dt1;
int dt2;
int dt3;
int dt4;
};
class Result {
public:
int x1;
int x2;
};
class Stats {
public:
int stat1;
int stat2;
};
typedef map<int, Data> DataSet;
typedef map<int, DataSet> DataMap;
typedef map<float, Result> ResultSet;
typedef map<int, ResultSet> ResultMap;
class MyAddOn: public AsyncWorker {
private:
DataMap *datas;
ResultMap results;
Stats stats;
public:
MyAddOn(Callback *callback, DataMap *set): AsyncWorker(callback), datas(set) {}
~MyAddOn() { delete datas; }
void Execute () {
for(DataMap::iterator i = datas->begin(); i != datas->end(); ++i) {
int res = i->first;
DataSet *datas = &i->second;
for(DataSet::iterator l = datas->begin(); l != datas->end(); ++l) {
int dt4 = l->first;
Data *data = &l->second;
// TODO: real population of stats and result
}
// test result population
results[res][res].x1 = res;
results[res][res].x2 = res;
}
// test stats population
stats.stat1 = 23;
stats.stat2 = 42;
}
void HandleOKCallback () {
Local<Object> obj;
Local<Object> res = New<Object>();
Local<Array> rslt = New<Array>();
Local<Object> sts = New<Object>();
Local<String> x1K = New<String>("x1").ToLocalChecked();
Local<String> x2K = New<String>("x2").ToLocalChecked();
uint32_t idx = 0;
for(ResultMap::iterator i = results.begin(); i != results.end(); ++i) {
ResultSet *set = &i->second;
for(ResultSet::iterator l = set->begin(); l != set->end(); ++l) {
Result *result = &l->second;
// is it ok to declare obj just once outside the cycles?
obj = New<Object>();
// is it ok to use same x1K and x2K instances for all objects?
Set(obj, x1K, New<Number>(result->x1));
Set(obj, x2K, New<Number>(result->x2));
Set(rslt, idx++, obj);
}
}
Set(sts, New<String>("stat1").ToLocalChecked(), New<Number>(stats.stat1));
Set(sts, New<String>("stat2").ToLocalChecked(), New<Number>(stats.stat2));
Set(res, New<String>("result").ToLocalChecked(), rslt);
Set(res, New<String>("stats" ).ToLocalChecked(), sts);
Local<Value> argv[] = { Null(), res };
callback->Call(2, argv);
}
};
NAN_METHOD(AddOn) {
Local<Object> datas = info[0].As<Object>();
Callback *callback = new Callback(info[1].As<Function>());
Local<Array> props = datas->GetOwnPropertyNames();
Local<String> dt1K = Nan::New("dt1").ToLocalChecked();
Local<String> dt2K = Nan::New("dt2").ToLocalChecked();
Local<String> dt3K = Nan::New("dt3").ToLocalChecked();
Local<Array> props2;
Local<Value> key;
Local<Object> value;
Local<Object> data;
DataMap *set = new DataMap();
int res;
int dt4;
DataSet *dts;
Data *dt;
for(uint32_t i = 0; i < props->Length(); i++) {
// is it ok to declare key, value, props2 and res just once outside the cycle?
key = props->Get(i);
value = datas->Get(key)->ToObject();
props2 = value->GetOwnPropertyNames();
res = To<int>(key).FromJust();
dts = &((*set)[res]);
for(uint32_t l = 0; l < props2->Length(); l++) {
// is it ok to declare key, data and dt4 just once outside the cycles?
key = props2->Get(l);
data = value->Get(key)->ToObject();
dt4 = To<int>(key).FromJust();
dt = &((*dts)[dt4]);
int dt1 = To<int>(data->Get(dt1K)).FromJust();
int dt2 = To<int>(data->Get(dt2K)).FromJust();
int dt3 = To<int>(data->Get(dt3K)).FromJust();
dt->dt1 = dt1;
dt->dt2 = dt2;
dt->dt3 = dt3;
dt->dt4 = dt4;
}
}
AsyncQueueWorker(new MyAddOn(callback, set));
}
NAN_MODULE_INIT(Init) {
Set(target, New<String>("myaddon").ToLocalChecked(), GetFunction(New<FunctionTemplate>(AddOn)).ToLocalChecked());
}
NODE_MODULE(myaddon, Init)
One year and half later...
If somebody is interested, my server is up and running since my question and the amount of memory it requires is stable.
I can't say if the code I wrote really does not has some memory leak or if lost memory is freed at each thread execution end, but if you are afraid as I was, I can say that using same structure and calls does not cause any real problem.
You do actually free up some of the memory you use, with the line of code:
~MyAddOn() { delete datas; }
In essence, C++ memory management boils down to always calling delete for every object created by new. There are also many additional architecture-specific and legacy 'C' memory management functions, but it is not strictly necessary to use these when you do not require the performance benefits.
As an example of what could potentially be a memory leak: You're passing the object held in the *callback pointer to the function AsyncQueueWorker. Yet nowhere in your code is this pointer freed, so unless the Queue worker frees it for you, there is a memory leak here.
You can use a memory tool such as valgrind to test your program further. It will spot most memory problems for you and comes highly recommended.
One thing I've observed is that you often ask (paraphrased):
Is it okay to declare X outside my loop?
To which the answer actually is that declaring variables inside of your loops is better, whenever you can do it. Declare variables as deep inside as you can, unless you have to re-use them. Variables are restricted in scope to the outermost set of {} brackets. You can read more about this in this question.
is it ok to use same x1K and x2K instances for all objects?
In essence, when you do this, if one of these objects modifies its 'x1K' string, then it will change for all of them. The advantage is that you free up memory. If the string is the same for all these objects anyway, instead of having to store say 1,000,000 copies of it, your computer will only keep a single one in memory and have 1,000,000 pointers to it instead. If the string is 9 ASCII characters long or longer under amd64, then that amounts to significant memory savings.
By the way, if you don't intend to modify a variable after its declaration, you can declare it as const, a keyword short for constant which forces the compiler to check that your variable is not modified after declaration. You may have to deal with quite a few compiler errors about functions accepting only non-const versions of things they don't modify, some of which may not be your own code, in which case you're out of luck. Being as conservative as possible with non-const variables can help spot problems.

BITMAPV5HEADER Size?

I'm trying to use BITMAPV5HEADER with CreateDIBSection to get a uint8[] in form of RGBA. I am doing this from ctypes but this isn't a ctypes question but I'll post the code so you can see it. The ctypes guys won't know whats up here it's a winapi thing.
I double checked my struct, function, and type declares but I keep getting GetLastError of 87 which is invalid parameter after calling CreateDIBSection. If I set the bv5Size to the size of BITMAPINFOHEADER which is 40 it works but is treated as BITMAPINFO header and the red,blue,green,alpha masks dont affect it, as I still get BGRA.
So I was wondering what is the size supposed to be for BITMAPV5HEADER on 32bit and 64bit please. For me I'm getting 124:
"ostypes.TYPE.BITMAPINFOHEADER.size:" 40
"ostypes.TYPE.BITMAPV5HEADER.size:" 124
This is my ctypes code just to show that everything is correct:
var bmi = ostypes.TYPE.BITMAPV5HEADER();
bmi.bV5Size = ostypes.TYPE.BITMAPV5HEADER.size;
bmi.bV5Width = nWidth; //w;
bmi.bV5Height = -1 * nHeight; //-1 * h; // top-down
bmi.bV5Planes = 1;
bmi.bV5BitCount = nBPP; //32;
bmi.bV5Compression = ostypes.CONST.BI_BITFIELDS;
bmi.bV5RedMask = ostypes.TYPE.DWORD('0x00FF0000');
bmi.bV5GreenMask = ostypes.TYPE.DWORD('0x0000FF00');
bmi.bV5BlueMask = ostypes.TYPE.DWORD('0x000000FF');
bmi.bV5AlphaMask = ostypes.TYPE.DWORD('0xFF000000'); // 0x00000000 for opaque, otherwise 0xff000000
var cBmi = ctypes.cast(bmi.address(), ostypes.TYPE.BITMAPINFO.ptr); // cBmi is now a pointer so no need to pass cBmi.address() to CreateDIBSection
var pixelBuffer = ostypes.TYPE.BYTE.ptr();
var hbmp = ostypes.API('CreateDIBSection')(hdcMemoryDC, cBmi, ostypes.CONST.DIB_RGB_COLORS, pixelBuffer.address(), null, 0);
This is ctypes so I don't have to memset bmi after creation as by default it is initialized memset 0.
Thanks

Referencing a Value

I want to reference a alue in a header file to use in my cpp file. The value name of the value is currentaddress. Here is the code...
HOSTENT *pHostEnt2;
int **ppaddr2;
SOCKADDR_IN sockAddr2;
char* addr2;
pHostEnt2 = gethostbyname(NewLogURL.c_str());
ppaddr2 = (int**)pHostEnt2->h_addr_list;
sockAddr2.sin_addr.s_addr = **ppaddr2;
addr2 = inet_ntoa(sockAddr2.sin_addr);
printf("\n Current Website IP:%s", addr2);
I tried this...
char getcurradd(char addr2)
{
return addr2;
}
But it say that I have the wrong value for the function. Any help is appreciated. Thnak you.
I would call it like this...
char CA = getcurradd(*addr2);
OK this was really simple! I just placed it as a global variable and walla! I can now access it.

Matlab MEX File: Program Crashes in the second run: Access Violation in Read

I have a C++ code that I am trying to interface with Matlab. My mex file runs fine in the first run but crashes in the second run. However, if I clear all the variables in the Matlab before execution (using clear all) program never crashes. So I have a question in this:
1. Can mex function takes variables from the Matlab workspace without using some special functions? Am I doing it somehow in my code, unintentionally?
I have a posted the mex function that I wrote. It has a one dimensional vector called "block" that is read inside the C++ function called sphere_detector. For the present problem the block size is 1x1920 and it is read in the chunk of 16 elements inside the sphere_detector. Program crashed when I read the SECOND chunk of 16 elements. The first element that I read in the chunk will throw this error:
First-chance exception at 0x000007fefac7206f (sphere_decoder.mexw64) in MATLAB.exe: 0xC0000005: Access violation reading location 0xffffffffffffffff.
MATLAB.exe has triggered a breakpoint
I checked my block vector, it should have all the values initialized and it has that. So, I am little confused as to why I am facing this problem.
I am using Matlab 2010a and Visual Studio 2010 Professional.
Here is the mex function:
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
double *mod_scheme, *Mt, *Mr, *block_length, *SNR;
mod_scheme = mxGetPr(prhs[0]);
Mt = mxGetPr(prhs[1]);
Mr = mxGetPr(prhs[2]);
block_length = mxGetPr(prhs[3]);
SNR = mxGetPr(prhs[4]);
/* Now take the input block. This is an encoded block and sphere detector will do the transmission too -- I can change it later */
double *block = mxGetPr(prhs[5]);
double *LIST_SIZE = mxGetPr(prhs[6]);
double **cand_sym;
int a = *mod_scheme;
int b = *Mt;
int c = *Mr;
int d = *block_length;
int e = *SNR;
int f = *LIST_SIZE;
int bitSize = (int)(log10(1.0*a)/log10(2.0));
for(int i=0; i<(int)*block_length; ++i)
{
printf("%d\n", (int)block[i]);
}
printf("Hello world %d %d %d %d %d!\n", (int)*mod_scheme, (int)*Mt, (int)*Mr, (int)*block_length, (int)*SNR);
/* Inputs are read correctly now set the outputs */
double *llr, *cand_dist;
/* for llrs */
plhs[0] = mxCreateDoubleMatrix(1, d, mxREAL);
llr = mxGetPr(plhs[0]);
/* for cand_dist */
int no_mimo_sym = d/(b*bitSize);
plhs[1] = mxCreateDoubleMatrix(1, f*no_mimo_sym, mxREAL);
cand_dist = mxGetPr(plhs[1]);
/* for cand_syms */
plhs[2] = mxCreateDoubleMatrix(b*bitSize*no_mimo_sym, f,mxREAL); //transposed version
double *candi;
candi = mxGetPr(plhs[2]);
cand_sym = (double**)mxMalloc(f*sizeof(double*));
if(cand_sym != NULL)
{
for(int i=0;i<f; ++i)
{
cand_sym[i] = candi + i*b*bitSize*no_mimo_sym;
}
}
sphere_decoder(a,b,c,d,e,block,f,llr,cand_dist,cand_sym);
// mxFree(cand_sym);
}
The portion inside the sphere decoder code where I get read exception looks like this:
for(int _block_length=0;_block_length<block_length; _block_length+=Mt*bitSize)
{
printf("Transmitting MIMO Symbol: %d\n", _block_length/(Mt*bitSize));
for(int _antenna = 0; _antenna < Mt; ++_antenna)
for(int _tx_part=0;_tx_part<bitSize; _tx_part++)
{
// PROGRAM CRASHES EXECUTING THIS LINE
bitstream[_antenna][_tx_part] = (int)block_data[_block_length + _antenna*bitSize + _tx_part];
}
............................REST OF THE CODE..................
}
Any help would be appreciated.
With regards,
Newbie
Well I finally managed to solve the problem. It was a very stupid mistake that I made. I had a pointer to a pointer(double *a;) of data type double and by mistake I assigned it memory of integer (I ran a find and replace command where I changed lots of int to double but this one left). Hence heap was getting corrupted. Also I changed my Mex function where I created dynamic variables using calloc and passed them to the C++ function. Once C++ function returned I copied there values to matlab variables and freed them usind free().

GetOpenFileName fails in 64 bit, but works in 32Bit?

I have the following code, I use to Open a File Open Dialog using Win32 API. It works fine in 32bit, but fails when I use in a 64bit (In a DLL). What am I doing wrong?
char Filestring[256];
Filter = "OBJ files\0*.obj\0\0";
char* returnstring = NULL;
OPENFILENAME opf;
opf.hwndOwner = mainHWND;
opf.lpstrFilter = Filter;
opf.lpstrCustomFilter = 0;
opf.nMaxCustFilter = 0L;
opf.nFilterIndex = 1L;
opf.lpstrFile = Filestring;
opf.lpstrFile[0] = '\0';
opf.nMaxFile = 256;
opf.lpstrFileTitle = 0;
opf.nMaxFileTitle=50;
opf.lpstrInitialDir = Path;
opf.lpstrTitle = "Open Obj File";
opf.nFileOffset = 0;
opf.nFileExtension = 0;
opf.lpstrDefExt = "*.*";
opf.lpfnHook = NULL;
opf.lCustData = 0;
opf.Flags = (OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT) & ~OFN_ALLOWMULTISELECT;
opf.lStructSize = sizeof(OPENFILENAME);
if(GetOpenFileName(&opf))
{
returnstring = opf.lpstrFile;
if (returnstring) {
result = returnstring;
}
}
EDIT: By failing, I meant that the Open File Dialog doesn't show up. The code still returns zero without any errors.
EDIT 2: I have called CommDlgExtendedError() and it returned 1. From the MSDN reference, does it mean the dialog has invalid lStructSize? I have checked the sizeof(OPENFILENAME) and it returned 140 bytes.
UPDATE: In my Project Settings, Under Code Generation the "Struct Member Alignment" is set to 4 Bytes(/Zp4). I changed this to default and it magically worked. Look for the answers and their comments below for more information.
You aren't initialising lpTemplateName and so it contains random stack noise. This in turn will lead to 'hInstance` being references which also contains stack noise.
When calling a function like this you should first of all zero out the struct and only fill in the fields that are non-zero. Something like this:
OPENFILENAME opf={0};
opf.lStructSize = sizeof(OPENFILENAME);
opf.hwndOwner = mainHWND;
opf.lpstrFilter = Filter;
opf.nFilterIndex = 1L;
opf.lpstrFile = Filestring;
opf.lpstrFile[0] = '\0';
opf.nMaxFile = 256;
opf.lpstrInitialDir = Path;
opf.lpstrTitle = "Open Obj File";
opf.lpstrDefExt = "*.*";
opf.Flags = OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT;
There was no need to exclude OFN_ALLOWMULTISELECT explicitly since you were not including it in the first place!
EDIT
You state in a comment that this doesn't work. Calling CommDlgExtendedError is a good idea and should tell you why it fails.
You could also try to run the minimal possible GetOpenFileName which is this:
char Filestring[MAX_PATH] = "\0";
OPENFILENAME opf={0};
opf.lStructSize = sizeof(OPENFILENAME);
opf.lpstrFile = Filestring;
opf.nMaxFile = MAX_PATH;
GetOpenFileName(&opf);
I have the very same problem and a partial solution :
+ the simple following simple example (proposed abobe) was not working in x64 mode.
+ I changed the complie option "struct Member Alignment" from 1byte /Zp1 to default which solved this problem (by introducing others !!!)
char Filestring[MAX_PATH] = "\0";
OPENFILENAME opf={0};
opf.lStructSize = sizeof(OPENFILENAME);
opf.lpstrFile = Filestring;
opf.nMaxFile = MAX_PATH;
GetOpenFileName(&opf);
To find out more you should call CommDlgExtendedError to get the error code what went wrong. Besides this I would initialize all member of the struct to 0 with
ZeroMemory(&opf, sizeof(opf));
Since the file open dialog is in reality a COM component it could be worth to check out if your thread apartment state is different under 64 bit.
if( RPC_E_CHANGED_MODE == CoInitialize(NULL) )
ASSERT(FALSE); // MTA Apartment found
CoUnitialize()
Yours,
Alois Kraus
As a note in Microsoft Office 2010 64-bit we gave up and used the internal wrappers as the structure turned into 140 bytes and we were not sure how to change alignment.
Application.GetOpenFilename(FileFilter, FilterIndex, Title, ButtonText, MultiSelect)
and Application.GetSaveAsFilename(InitialFilename, FileFilter, FilterIndex, Title, ButtonText)
http://msdn.microsoft.com/en-us/library/ff834966.aspx
http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel._application.getopenfilename.aspx
Needless to say we think all individuals with fairly heavy applications in Excel should start considering other options as maintaining future versions across multiple clients and platforms may just be... insane!
I managed to get around this problem by setting the packing appropriately before including the header file. That way, for the purpose of this one function, we were using the 'default' 16 byte alignment, but did not have to change the packing alignment for the rest of our program:
#ifdef _WIN64
#pragma pack( push )
#pragma pack( 16 )
#include "Commdlg.h"
#pragma pack( pop )
#else
#include "Commdlg.h"
#endif // _WIN64

Resources