I only use CLion to work with JUCE and I didn’t find any information about this in more general CLion resources so I’m giving it a shot here in case anyone has seen this.
I’ve been debugging some issues I have with saving the state of a plugin I’m working on, so I added some DBG’s, for example, this is to save the contents of a TextEditor in a ValueTree:
const juce::ScopedLock sl (notesTreeLock);
const auto i = side == "left" ? 0 : 1;
trackNotes[i] = notes;
notesTree = notesTree.setProperty(side, notes, nullptr);
DBG("updateTrackNotes, new notesTree: " + notesTree.getType());
DBG(notesTree.toXmlString().toStdString()); // no difference if I don't use toStdString
DBG("updateTrackNotes, trackNotes.hasProperty(" + side + "): " + std::to_string(notesTree.hasProperty(side)));
DBG("updateTrackNotes, new trackNotes for " + side + " channel:");
DBG(trackNotes[i]);
[gs]etStateInformation then use notesTree but that’s not the main thing. Thing is in CLion, whether I debug the standalone build or VST3 with Reaper I get:
updateTrackNotes, new notesTree: NotesTree
updateTrackNotes, trackNotes.hasProperty(left): 1
updateTrackNotes, new trackNotes for left channel:
foo
Eventually I tried running Reaper from terminal and without any changes to the code I get:
updateTrackNotes, new notesTree: NotesTree
<?xml version="1.0" encoding="UTF-8"?>
<NotesTree left="foobar"/>
updateTrackNotes, trackNotes.hasProperty(left): 1
updateTrackNotes, new trackNotes for left channel:
foobar
It certainly is strange that some of the debug logging is working, whereas one would expect it either have no logging or logging would all work.
If I was looking into this, I would use the debugger to look at the issue. Under the hood DBG makes a temp juce::String and passes it off to Logger::outputDebugString. So you could examine it there to verify the string is correct, and then you could shift your focus to outputDebugString. Which, since you have the JUCE code, you could also step into to further try and verify where the failure is happening. While the exercise may not solve the problem, it will help verify what isn’t the problem. 
Yeah that’s not a bad idea. I have a feeling I’ll hit a wall because the indication is that the run window in CLion has a problem with the XML-formatted strings, given that iTerm spits them out just fine, and that’s not something the root cause of which I can even begin to imagine
but who knows, if no one chimes in with a CLion setting or somesuch that could be causing this, I’ll give this a go and report back
Yep, very likely this doesn’t reveal anything. Another quick test, based on the idea that it is the XML string handling in CLion. Send a hardcoded XML string to DBG. Another interesting piece of data is that are four empty lines in the CLion output where the text should be, almost like it did print something. Maybe try this as an experiments:
DBG("some text" + notesTree.toXmlString() + "more text");
Per a few searches it doesn’t look like there have been any other XML specific reports. One recommendation is to and std::endl to the string.
Best of luck!
1 Like
Maybe specifically this:
DBG("<![CDATA[" + notesTree.toXmlString() + "]]>");
The CDATA might convince CLion to not interpret the XML as XML. 
interesting, in both cases it just showed the last string
DBG("setStateInformation: notesTree is:");
DBG("<![CDATA[" + notesTree.toXmlString() + "]]>");
results in this
setStateInformation: notesTree is:
]]>
similarly
DBG("setStateInformation: notesTree is:");
DBG("foobar " + notesTree.toXmlString() + "spamham");
outputs
setStateInformation: notesTree is:
spamham
it’s not the end of the world but it’d sure be nice to be able to debug straight from CLion. I’ll keep trying stuff in the mean time
DBG("<![CDATA[" + notesTree.toXmlString().replace("\n", "") + "]]>");
setStateInformation: notesTree is:
]]>
so before it seems like it does keep the newlines as the number of blank lines matches the lines output in iTerm, but it swallows the other characters
You might need to escape the XML, i.e. turn all < into < and > into > or something like that. (In which case DBG(“<”) should print <).

2026-05-02 13:19:55.085 REAPER[93328:55460516] swell-cocoa: creating metal device context for 0x13e82b800 Apple M1 Pro
JUCE v8.0.11
<
but
DBG("<PluginState>");
prints
JUCE v8.0.11
<PluginState>
strange!
if I add newlines beween the extra strings and the XML it does print the first one as well, so I’m wondering if maybe it’s the " in the XML that it’s not linking
DBG("<![CDATA[\n" + notesTree.toXmlString() + "\n]]>");
<![CDATA[
]]>
edit:
adding notesTree.toXmlString().replace("\"", "") doesn’t change anything.
I’ll dig into format and see if that helps
String toXmlString (const XmlElement::TextFormat& format = {}) const;
it ain’t much, but it’s honest work 
auto format = juce::XmlElement::TextFormat();
DBG(notesTree.toXmlString(format.singleLine()));
JUCE v8.0.11
<?xml version="1.0" encoding="UTF-8"?> <NotesTree left="foobar!! spamham"/>
I fixed the issue I was having with my plugin state and I hope I won’t have to do this too often so this’ll do
This makes CLion output the same as iTerm (ie. output normal XML)
auto format = juce::XmlElement::TextFormat();
format.newLineChars = "\n";
DBG(notesTree.toXmlString(format));
So I looked for other people having issue with carriage returns (\r\n is the default newline character as per the TextFormat docs) and found a solution to turn off using PuTTY as the default console. I will monitor to make sure this doesn’t cause any other issues and will report back here if it does
Help | Find Action | Registry... =>
run.processes.with.pty [ ] <- uncheck
In your run configuration, ensure “Emulate terminal in the output console” is checked.
nice, yes that did it, cheers