New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
nxagentAdjustRandRXinerama uses freed memory #293
Comments
While developing this I had the problem that the original xrandr code was missing a free() call. So I had to work around that somehow. The missing free() has been backported IIRC. So it could be that the workaround is wrong now. |
It does look like something needs fixing. FreeResource is a free() call, and the code that calls it doesn't decrement pScrPriv->numOutputs, so that entry is still in the array, and pointing to freed memory. It would seem the logical thing to do is to either compact the array after deletion, or to set the entry to NULL to mark it as unused. I've not yet looked at what is the right thing to do there, and may be busy with other things tomorrow, so it would be good if somebody else could take a look at it. |
To me it seems we should / could simply drop the above code fraction. |
Oh hang on... wrong section removed, I just realized. However, that above passage does not make sense either, does it? Where should non-NX Outputs come from? |
more noise... the above passage was the correct code block to be removed... |
@sunweaver Hrmm. This is confusing. Let's see if I understand. That chunk of code removes unneeded outputs. Note that there's another one right after it, so if you're going to remove something, it's probably both. The code iterates from the end of the list, because RROutputDestroy actually compacts the pScrPriv->outputs array. Lower down, the problem happens with "RRCrtcSet(pScrPriv->crtcs[i], ...", because RRCrtcSet ends up calling RROutputChanged on a freed RROutput. Also note this:
So the assumption there seems to be that pScrPriv->outputs and pScrPriv->crtcs have a 1 to 1 relationship, but that seems to be false, because when we delete from "outputs" in RROutputDestroy we are not touching crtcs. Then there's that a RROutput has both a .crtc member and a .crtcs array. So far I see:
Ok, now I'm confused about what is the hierarchy of this and who owns what. Are pScrPriv->outputs and pScrPriv->crtcs supposed to go in sync? Should deleting a RROutput reach into RRCrtcs and remove any references it holds to the deleted object? |
Well, concerning the NX outputs this 1:1 relationship is true, IIRC. If an output on the real xserver is not visible inside NX it gets switched off by removing the crtc. You can comment some of the cleanup routines and check what the servers knows using the xrandr binary. Maybe it gets clearer what's going on. I need to look deeper into this but I am lacking time currently, sorry. |
Maybe the spec helps for better understanding of the output<->crtc relationship: https://cgit.freedesktop.org/xorg/proto/randrproto/tree/randrproto.txt (graphical representation around line 80) The 1:1 relationship is true in NX as long as noone is adding additional outputs using the RAND extension. Which is something that should be prevented anyway, I'd say. |
Just stumbled across this as well testing 3.5.99.3 |
…t's original RandR implementation. Fixes ArcticaProject#293.
…in RandR extension internally since backport of RandR 1.5 to nxagent's Xserver code. Fixes ArcticaProject#293.
it looks like pScrPriv->outputs should be compacted to remove the deleted entries, or the entry should be marked as unused. After looking through the code I think this remark is correct. Update:
If everything goes right RROutputDestroyResource() should be called automatically since it is used as the deleteFunc for the Output resource type:
So in theory the postulated compaction of the output array is already done. |
I have confirmed that RROutputDestroyResource() gets executed when FreeResource() is called for an output. So the output array gets compacted if necessary. Update: we could have saved all this as RROutputDestroyResource happens to occur in the valgrind output above... |
Now, this is interesting:
If I interpret valgrind's output correctly this tells me that nxagentAdjustRandRXinerama() calls FreeResource() which in turn calls RROutputDestroyResource(). So we can conclude that FreeResource() is used here to free an Output resource. However, the code contains only one FreeResource() call, and that one is freeing a mode, not an Output!
So the question is: why do we end up in RROutputDestroyResource() when freeing a mode resource? |
…NTERFACE. CRTC and OUTPUT setup happens in nxagent's Screen.c file. Fixes ArcticaProject#293.
Update2: ignore this comment, it's nonsense. See further comments. Well, while your commit seems to make the behaviour disappear I think I have taken a step towards the real cause: During writing Xinerama stuff I have added nxagentRandRCrtcSet() (in Extensions.c). This simply calls RRCrtcNotify(). I remember that this was the easiest approach to get the desired behaviour though I had been unsure about it. Not without a reason, it seems... RRCrtcNotify has this comment:
We have not changed the mode here but the number of outputs (by destroying one). So it is probably not the right function to call. I think nxagentRandRCrtcSet() should be reimplemented to do the right thing itself. (Proof of concept: changing nxagentRandRCrtcSet to just return TRUE makes the issue disappear. Must check if xinerama is still working, though) Update: http://xorg-devel.x.narkive.com/KpOwRcMX/patch-xvfb-add-randr-support also calls RRCrtcNotify here. Hmm... |
Hi Uli,
On Mo 06 Feb 2017 23:26:34 CET, Ulrich Sibiller wrote:
Well, while your commit seems to make the behaviour disappear I
think I have taken a step towards the real cause. During writing
Xinerama stuff I have added nxagentRandRCrtcSet() (in Extensions.c).
This simply calls RRCrtcNotify(). I remember that this was the
easiest approach to get the desired behaviour though I had been
unsure about it. It seems by feelings back then were right.
I think nxagentRandRCrtcSet() should be reimplemented to do the
right thing itself.
What exactly to you be by "to do the right thing"?
Mike
--
DAS-NETZWERKTEAM
mike gabriel, herweg 7, 24357 fleckeby
mobile: +49 (1520) 1976 148
landline: +49 (4354) 8390 139
GnuPG Fingerprint: 9BFB AEE8 6C0A A5FF BF22 0782 9AF4 6B30 2577 1B31
mail: mike.gabriel@das-netzwerkteam.de, http://das-netzwerkteam.de
|
I think "the right thing" is to do what RRCrtcNotify() does but without touch old stuff. The real problem is that the old output (that has been destroyed just before) is still referenced in the crtc struct and RRNotify() will try to set the "changed" flag on it. It could also be that calling RROutputDestroy() it not sufficient and some more work is needed after it. I need to investigate but I am lacking time... |
The real reason is identified: The "delete superfluous non-NX outputs" loop adjusts the number of outputs to the number of crtcs; both should match the number of outputs of the real server. It does that by calling RROutputDestroy() for all the outputs in the outputs array whose index exceeds the required number. But it does not check if any of these outputs is still in use by a crtc. So a crtc can have reference to a destroyed output. And on RRCrtcNotify() that output reference is found and the output is marked as changed by setting the output's "changed" flag. As the output has already been destroyed and its memory has been freed valgrind complains (which is of course correct). What does the proper fix look like? I am not sure. Maybe first try to identify unused outputs and first destroy them. But what to do if they are not enough? Can that happen at all? Currently the outputs are deleted from the highest index to the lowest index in the outputs array. Simply reversing the order will probably help for exactly this situation where a seeing here but it feels wrong as a fix. This memory access happens first for the "default" output. |
While debugging another issue, I stumbled across this one:
It looks like pScrPriv->outputs should be compacted to remove the deleted entries, or the entry should be marked as unused.
Issue found in cb8af80
Valgrind output:
The text was updated successfully, but these errors were encountered: