He estado molestando a TJ en node-canvas sobre un código de velocidad en el que estoy trabajando en una bifurcación de un módulo de nodo que él creó y mantiene.nodejs nativo C++ npm error de memoria del módulo, cairo procesamiento de imágenes
Encontré que Canvas.toBuffer() estaba matando nuestros recursos de canalización y creamos una alternativa que simplemente convertiría Canvas en una Imagen sin pasar por un búfer png/media url. El problema es que El Cairo es una bestia misteriosa, y hay un nivel adicional de preocupación acerca de la memoria asignada dentro de los módulos de nodos, ya que no se puede obtener por GC v madre. He agregado los HandleScopes adecuados a todas las funciones requeridas que acceden a los datos de V8.
Pude probar el método Canvas.loadImage (imagen) miles de veces en la configuración de mac (6.18), así como pruebas independientes en nuestros servidores ubuntu/producción que ejecutan la misma versión de nodo. Pero cuando el código se ejecuta como un proceso/servidor en segundo plano y coordinado por Gearman, estoy obteniendo algunos "segmentos" de memoria/segmentos "interesantes".
Además, tengo problemas para llamar a cualquiera de los métodos de clases definidos en node-canvas que no están en línea dentro de los archivos de encabezado. Como pregunta complementaria ¿Cuál es la mejor manera de crear paquetes de código fuente nativos comunes en los que otros módulos de nodo puedan contar?
He intentado volver a crear el problema y ejecutarlo con gdb, node_g y todos los módulos de nodo construidos con símbolos y marcadores de depuración. Pero el error aparece en una lib fuera del origen para el que puedo obtener un seguimiento de la pila.
como referencia aquí es donde llamo loadImageData y mientras se ejecuta localmente bajo una variedad de condiciones, en nuestro entorno de producción cuando cuidadosamente escondido dentro de un servidor de marcos parece estar causando segfaults (pasó el día de ayer intentando gdb node_g nuestro código del servidor, pero los servidores de bastidor se iniciaron por gearman ... TL; DR no conseguir una traza de la raíz causa pila)
https://github.com/victusfate/node-canvas/blob/master/src/Canvas.cc#L497
Handle<Value>
Canvas::LoadImage(const Arguments &args) {
HandleScope scope;
LogStream mout(LOG_DEBUG,"node-canvas.paint.ccode.Canvas.LoadImage");
mout << "Canvas::LoadImage top " << LogStream::endl;
Canvas *canvas = ObjectWrap::Unwrap<Canvas>(args.This());
if (args.Length() < 1) {
mout << "Canvas::LoadImage Error requires one argument of Image type " << LogStream::endl;
return ThrowException(Exception::TypeError(String::New("Canvas::LoadImage requires one argument of Image type")));
}
Local<Object> obj = args[0]->ToObject();
Image *img = ObjectWrap::Unwrap<Image>(obj);
canvas->loadImageData(img);
return Undefined();
}
void Canvas::loadImageData(Image *img) {
LogStream mout(LOG_DEBUG,"node-canvas.paint.ccode.Canvas.loadImageData");
if (this->isPDF()) {
mout << "Canvas::loadImageData pdf canvas type " << LogStream::endl;
cairo_surface_finish(this->surface());
closure_t *closure = (closure_t *) this->closure();
int w = cairo_image_surface_get_width(this->surface());
int h = cairo_image_surface_get_height(this->surface());
img->loadFromDataBuffer(closure->data,w,h);
mout << "Canvas::loadImageData pdf type, finished loading image" << LogStream::endl;
}
else {
mout << "Canvas::loadImageData data canvas type " << LogStream::endl;
cairo_surface_flush(this->surface());
int w = cairo_image_surface_get_width(this->surface());
int h = cairo_image_surface_get_height(this->surface());
img->loadFromDataBuffer(cairo_image_surface_get_data(this->surface()),w,h);
mout << "Canvas::loadImageData image type, finished loading image" << LogStream::endl;
}
}
y esto es lo que el método actual en imagen se ve como (Eliminé alguna información de registro comentada) https://github.com/victusfate/node-canvas/blob/master/src/Image.cc#L240
/*
* load from data buffer width*height*4 bytes
*/
cairo_status_t
Image::loadFromDataBuffer(uint8_t *buf, int width, int height) {
this->clearData();
int stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, width); // 4*width + ?
this->_surface = cairo_image_surface_create_for_data(buf,CAIRO_FORMAT_ARGB32,width,height,stride);
this->data_mode = DATA_IMAGE;
this->loaded();
cairo_status_t status = cairo_surface_status(_surface);
if (status) return status;
return CAIRO_STATUS_SUCCESS;
}
Cualquier ayuda, sería apreciado pro consejos, ayuda o palabras de aliento.
Originalmente desde google groups
Estamos utilizando también node-canvas en producción y tenemos procesos independientes que son eliminados y reiniciados después de renderizar ~ 200 imágenes (debido a fugas de memoria y fragmentación). Verifique sus extensiones nativas con Valgrind para sobrepasar la memoria: http://valgrind.org/docs/manual/QuickStart.html Esta herramienta debería revelar el motivo de las violaciones de segmentación que ya están en la prueba env. –
gracias teemu, derribamos y construimos entre lotes de imágenes ~ 24-> 100 más o menos. –
@TeemuIkonen Tuve problemas para usar valgrind el día de hoy tanto en osx side como en linux, cualquier consejo para dar sentido a los resultados (congelado inmediatamente en os x, tomé algunas llamadas para mencionar un error en linux) –