Got my pointers in a twist - Segmentation fault: 11

Greetings all,

I’m having trouble working out how to share a file path between widgets whilst saving said path to JSON file. I’ve got a module with a TransparentWidget and a SvgWidget, when an SVG image is dropped onto the TransparentWidget it updates a variable that’s referenced via pointer in the SvgWidget. Basically it’s a drag and drop decorative blank panel. This functionality seems to work fine, I’m just having trouble then saving the current file path to the JSON file so that the image persists on save/load and duplicate. The following code throws a nice seg fault…

	#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;
			CP->NEWPATH = &module->jsonSavePath;
		}
	};

	Model* model_4hp = createModel<_4hp, _4hpWidget>("4hp");

…Any assistance would be most appreciated.

To get rid of the segmentation fault, I can comment out the following line:

	CP->NEWPATH = &module->jsonSavePath;

so that might have something to do with it, but I’m not sure to be honest, I could be going about it all the wrong way.

Yep, still banging my head against this one, so if anyone has a solution for saving the file path to JSON file, i’d really appreciate some help. Thanks!

Crash it in the debugger to get more info. In gdb if you crash you get a prompt and if you type “bt” it will show you what it was doing.

1 Like

Thank you very much for the response Squinky. So it looks like i’m going about it the right way? I’m totally new to C++ and VCV development, so is GBD is the debugger of choice for this kind of thing? I had to google GBD to find out what it was.

Also, I’m on Mac and apparently " Beginning with Mavericks (macOS 10.9) Xcode stopped supporting the gdb debugger" Do you recommend I install in from some other source? Or do I just use an online GBD debugger?

Shouldn’t this be module->jsonSavePath?

The variable module is already a pointer and with the expression &module you try to obtain the address of the pointer address, which doesn’t work and leads to a segfault. With &module you construct some kind of a double pointer dereferencing situation.

1 Like

ahh, looks like an online debugger is out of the question as it would need all the included files. I guess I just need to find a patched version for Mac 10.14

Thanks for the response Silvio!

your suggestion throws the following error…

src/4hp.cpp:110:25: error: assigning to 'std::string *' (aka 'basic_string<char,
      char_traits<char>, allocator<char> > *') from incompatible type
      'std::string' (aka 'basic_string<char, char_traits<char>, allocator<char>
      >'); take the address with &
                CP->NEWPATH = module->jsonSavePath;
                              ~~~~~~~~^~~~~~~~~~~~
                              &
1 error generated.
make: *** [build/src/4hp.cpp.o] Error 1

Ok, found this version of your recommended debugger that apparently works with my system, just attempting to install it now, will report back when I’ve had a chance to try it…

OK I see, you could try it then this way - CP->NEWPATH = &(module->jsonSavePath);

I hope you know what you are doing, to me the code looks rather strange.

1 Like

lol, i have no idea! i’m probably doing it all wrong, if anyone has suggestions about how to go about it properly I’m all ears!

CP->NEWPATH = &(module->jsonSavePath);

also throws a seg fault 11

Right now I’m up to my eyeballs in patching GBD, installing Xcode command line tools for 11.3.1 and creating and Installing a Self-Signed Code-Signing Certificate… this debugger is proving to be fickle to install!

Just out of curiosity, what are you doing when the segfault occurs? If you are adding your module via the browser, module is null. I haven’t looked deep enough in your code to see if this suggestion makes sense.

1 Like

Thanks for the response :slight_smile: Really appreciate all the suggestions. The seg fault occurs when I try to open the module browser to add a module

Always check module pointers for null before using in a widget.

1 Like

Then it must be guarded like this

if (module)
{
    CP->NEWPATH = &(module->jsonSavePath);
}
1 Like

is there another debugger that will work for this that’s more Mac compatible? I’m having loads of issues trying to install, patch and generate a keychain certificate that works. Currently my system is failing to find the keychain entry I’ve just added…

codesign --entitlements /Users/jim/Desktop/gdb-entitlement.xml -fs gdb-cert $(which gdb)

error: The specified item could not be found in the keychain.

You don’t need a debugger for this problem. The previous comments are correct.

module will always be null in the browser. So don’t try to save the path if module is null

1 Like

Thanks all for the help, this has got rid of the seg fault, now I’ve lost functionality, so I’ll just have to work out why there’s no path being passed to the widgets and hopefully it will work properly. Will report back when I have some progress…

lldb is the clang debugger - it’s actually a bit nicer to use than gdb, and it should already be installed on your Mac.

1 Like