Got my pointers in a twist - Segmentation fault: 11

amazing! I’ll defo check that out, thanks for the response.

It’s been a while since I debugged on a Mac. I thought they had some fake gdb to translate. But if you have to use lldb it’s ok. I always build my rack and then do plugins there, and running rack under a debugger is just make debug.

Also, that json stuff is weird. I think json-t is a ref counted pointer.

1 Like

I notice that most people are storing strings to JSON direct from their Module struct, I couldn’t find an example of how to do it from a widget. Yeah, been looking on the github comments for the GDB patch for OSX 10.14 and loads of people are having issues, so that might take a while to sort.

It’s not recommended to do it from the widget. It used to be done like that, but as the api has changed, it’s now recommended to do it all from the module.

1 Like

Thanks David. Ok I see, I assumed that was the case and that’s what I’ve been attempting to do. So I’ve been trying to shared between the (drag and drop) TransparentWidget the (Display SVG image) SvgWidget and the actual Module using pointers and that’s where I’ve gotten messed up. I can share the path between the widgets and that part works, it’s just getting the same location saved to JSON that’s confusing me

Put one pointer in the module. Then either widget can update it, and the module can save it.

Don’t try to do anything with it if the module isn’t there, but you won’t be dragging and dropping to the version in the browser, so that shouldn’t be a problem.

You won’t need to access that pointer from the module’s process method, so there shouldn’t be any threading issues.

1 Like

Ok, having a bit more luck. This is how I have the pointers setup now…

	// make NEWPATH, svgPath and jsonSavePath point to the same memory location
	CP->NEWPATH = &DND->svgPath;
	
	if (module)
	{
		module->jsonSavePath = *CP->NEWPATH;
		std::cout << module->jsonSavePath << "\n";
	}

the drag and drop works and there’s no longer a seg fault, however the jsonSavePath is not updating to the new NEWPATH. The console.log just shows the initial NEWPATH and not the current one set after dragging and dropping, so i have no persistence. I feel like i’m missing a trick here? There’s got to be an easier way of doing this

I’m not really clear what you are trying to do. But why is NEWPATH a pointer to a std::string rather than a std::string?

1 Like
	#include "plugin.hpp"
	#include <iostream>
	
	struct _4hp : Module
	{
		enum ParamId
		{
			PARAMS_LEN
		};
		enum InputId
		{
			INPUTS_LEN
		};
		enum OutputId
		{
			OUTPUTS_LEN
		};
		enum LightId
		{
			LIGHTS_LEN
		};
	
		_4hp()
		{
			config(PARAMS_LEN, INPUTS_LEN, OUTPUTS_LEN, LIGHTS_LEN);
		}
	
		std::string jsonSavePath; // storage for SVG image file path
	
		// save and load filepath to JSON file
	
		json_t *dataToJson() override 
		{
			json_t *rootJ = json_object();
			json_object_set_new(rootJ, "sPATH", json_string(jsonSavePath.c_str()));	
			return rootJ;
		}
	
		void dataFromJson(json_t *rootJ) override
		{
			json_t *savedPATHJ = json_object_get(rootJ, "sPATH");
			jsonSavePath = json_string_value(savedPATHJ);
		}
	};
	
	struct customPanel : SvgWidget
	{
		std::string *NEWPATH; // incoming SVG file path
		std::string PATH; // current SVG file path
	
		customPanel()
		{
			setSvg(Svg::load(asset::plugin(pluginInstance, PATH))); // set SVG file on creation of customPanel
		}
	
		void draw(const DrawArgs& args) override
		{
			if(*NEWPATH != PATH) // check if SVG file path has changed
			{
				setSvg(Svg::load(asset::plugin(pluginInstance, *NEWPATH))); // set new file path
				PATH = *NEWPATH; // asign new path to current path variable
			}
	
			SvgWidget::draw(args); // continue to run the rest of the default draw function
		}
	};
	
	struct dnd : TransparentWidget
	{
		std::string filePath; // path of dropped file
		std::string svgPath = asset::plugin(pluginInstance, "res/test.svg"); // path with SVG extension
	
		void onPathDrop(const PathDropEvent &e) override
		{
			filePath = e.paths.front(); // get first path in array, all other paths are ignored
	
			if(filePath.substr(filePath.find_last_of(".") + 1) == "svg") // check for SVG extension
			{
				svgPath = filePath; // store path
			}
	
			else
			{
				std::cout << "Invalid file extension: try *.svg" << "\n";
			}
		}
	};
	
	struct _4hpWidget : ModuleWidget
	{
		_4hpWidget(_4hp *module)
		{
			setModule(module);
			setPanel(createPanel(asset::plugin(pluginInstance, "res/4hp.svg")));
	
			// maunally add widgets to allow for pointer references
	
			dnd *DND = new dnd();
			DND->box.pos = Vec(0, 0);
			DND->box.size = Vec(RACK_GRID_WIDTH * 4, RACK_GRID_HEIGHT);
			addChild(DND);
	
			customPanel *CP = new customPanel();
			CP->box.pos = Vec(0, 0);
			CP->box.size = Vec(RACK_GRID_WIDTH * 4, RACK_GRID_HEIGHT);
			addChild(CP);
	
			// make NEWPATH, svgPath and jsonSavePath point to the same memory location
			CP->NEWPATH = &DND->svgPath;
			
			if (module)
			{
				module->jsonSavePath = *CP->NEWPATH;
				std::cout << module->jsonSavePath << "\n";
			}
		}
	};
	
	Model* model_4hp = createModel<_4hp, _4hpWidget>("4hp");

NEWPATH is not in the Module it’s in the SvgWidget, JsonSavePath is in the main Module

But why is newpath defined as a pointer?

1 Like

Good question! I’m not sure, will change it and see if that works…

I’m not sure why you need it at all. Is there more code that you have not posted?

No that’s everything, it should be short and sweet…drag and drop SVG file onto TransparentWidget, check it’s an SVG, then pass path to SvgWidget and draw image, then pass the currently displayed image path to the Module so it can save and load it from JSON

As far as i can see, you are only updating the svgSavePath once, and that is when your module is created. You aren’t updating it after the drop event

Yeah, that’s why I was using pointers, so it should all point to the same memloc, so dragging and dropping should trigger everything when it updates the SvgPath

Ok. I think the problem then, is that your module->jsonSavePath is NOT a pointer, so you are not getting them all to point to the same memloc. When you assign to the jsonSavePath in your constructor, you are just assigning the string value at the time.

1 Like

Lol, changed jsonSavePath back to a pointer and now the seg fault is back…oh my days, I’ve made a right pigs ear of this! :rofl:

Are you definitely guarding all the places where widgets might try to access that pointer when there no module?

I think so…but then I’m new to all this so I’ve probably missed something obvious…

	#include "plugin.hpp"
		#include <iostream>
		
		struct _4hp : Module
		{
			enum ParamId
			{
				PARAMS_LEN
			};
			enum InputId
			{
				INPUTS_LEN
			};
			enum OutputId
			{
				OUTPUTS_LEN
			};
			enum LightId
			{
				LIGHTS_LEN
			};
		
			_4hp()
			{
				config(PARAMS_LEN, INPUTS_LEN, OUTPUTS_LEN, LIGHTS_LEN);
			}
		
			std::string jsonSavePath; // storage for SVG image file path
		
			// save and load filepath to JSON file
		
			json_t *dataToJson() override 
			{
				json_t *rootJ = json_object();
				json_object_set_new(rootJ, "sPATH", json_string(jsonSavePath.c_str()));	
				return rootJ;
			}
		
			void dataFromJson(json_t *rootJ) override
			{
				json_t *savedPATHJ = json_object_get(rootJ, "sPATH");
				jsonSavePath = json_string_value(savedPATHJ);
			}
		};
		
		struct customPanel : SvgWidget
		{
			std::string *NEWPATH; // incoming SVG file path
			std::string PATH; // current SVG file path
		
			customPanel()
			{
				setSvg(Svg::load(asset::plugin(pluginInstance, PATH))); // set SVG file on creation of customPanel
			}
		
			void draw(const DrawArgs& args) override
			{
				if(*NEWPATH != PATH) // check if SVG file path has changed
				{
					setSvg(Svg::load(asset::plugin(pluginInstance, *NEWPATH))); // set new file path
					PATH = *NEWPATH; // asign new path to current path variable
				}
		
				SvgWidget::draw(args); // continue to run the rest of the default draw function
			}
		};
		
		struct dnd : TransparentWidget
		{
			std::string filePath; // path of dropped file
			std::string svgPath = asset::plugin(pluginInstance, "res/test.svg"); // path with SVG extension
		
			void onPathDrop(const PathDropEvent &e) override
			{
				filePath = e.paths.front(); // get first path in array, all other paths are ignored
		
				if(filePath.substr(filePath.find_last_of(".") + 1) == "svg") // check for SVG extension
				{
					svgPath = filePath; // store path
				}
		
				else
				{
					std::cout << "Invalid file extension: try *.svg" << "\n";
				}
			}
		};
		
		struct _4hpWidget : ModuleWidget
		{
			_4hpWidget(_4hp *module)
			{
				setModule(module);
				setPanel(createPanel(asset::plugin(pluginInstance, "res/4hp.svg")));
		
				// maunally add widgets to allow for pointer references
		
				dnd *DND = new dnd();
				DND->box.pos = Vec(0, 0);
				DND->box.size = Vec(RACK_GRID_WIDTH * 4, RACK_GRID_HEIGHT);
				addChild(DND);
		
				customPanel *CP = new customPanel();
				CP->box.pos = Vec(0, 0);
				CP->box.size = Vec(RACK_GRID_WIDTH * 4, RACK_GRID_HEIGHT);
				addChild(CP);
		
				// make NEWPATH, svgPath and jsonSavePath point to the same memory location
				CP->NEWPATH = &DND->svgPath;
				
				if (module)
				{
					module->jsonSavePath = *CP->NEWPATH;
				}
			}
		};
		
		Model* model_4hp = createModel<_4hp, _4hpWidget>("4hp");