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
Minor memory-safety fixes (Valgrind-identified problems, debug bounds checks) #5068
Conversation
I thought the REX.W prefix bug was fixed and pulled. If there's another one, please let me know where. |
Yes, thanks. But you need to bootstrap through DMD head to take advantage of the fix. There are cases when you don't want to do that (e.g. Digger would need to compile DMD a third time when bootstrapping just to work around this), I hope no one objects to a few small patches in the DMD code. |
In that case, I'd like to see the workaround wrapped in a |
OK, will do. This pull request is still in early stages though (right now I want to use the autotester to check if a condition is ever triggered). Off the top of your head, do you know if calling |
Since it is implemented:
I don't think so. Use |
I'm asking because some DMD code is doing it. I added an assert, and the test suite passes with the assert, so it has to be a bug. It looks like |
8d2493a
to
5d4ee37
Compare
5d4ee37
to
d537ec8
Compare
I've cleaned up this PR and changed the Valgrind workarounds accordingly. It should be ready to review/merge. This doesn't fix issue 15019, but the changes here helped make the failure deterministic and reduce the test case, and are useful on their own. |
e.e2 = new IntegerExp(e.loc, e.e2.toInteger(), Type.tint64); | ||
if (e.e2.op == TOKfloat64) | ||
{ | ||
version (all) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there some way we could make this static if (version < firstFixedVersion)
so that it's immediately clear when it can be removed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ping on this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have a specific suggestion I can add?
In principle, this can only be safely removed once DMD is no longer compilable with DMD 2.068 or earlier, which probably won't be for a while.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean that is should either be checking __VERSION__
instead of using version(all)
, or at least have a comment saying that it can be removed once 2.068 is no longer supported. The bugzilla link and description are great but having the version number explicitly there as well makes it obvious.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, added a comment.
But I should note that these patches are not comprehensive, and are only what I needed to fix in order to be able to debug issue 15019. I would like to run the DMD test suite under Valgrind some day (I know it'll take days to complete, probably), but not now.
Also, IMHO, this seems like quite a bit of bureaucracy for such a simple change (extracting a few expressions to variables).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like adding dead code, and I've put quite a lot of effort into removing it. I have no problem with the change, and I've done similar things myself, my problem is with the dead code Walter asked for.
If we're going to see dozens of similar changes then it might be better to look at other options (like patching the binaries to replace the prefix with a nop).
Does anyone know what's with these test failures? |
d537ec8
to
381e65f
Compare
Removed CyberShadow@d537ec8 because it is superseded by #5074 |
@@ -2310,6 +2310,7 @@ void MachObj::addrel(int seg, targ_size_t offset, symbol *targsym, | |||
unsigned targseg, int rtype, int val) | |||
{ | |||
Relocation rel; | |||
memset(&rel, 0, sizeof(rel)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All the fields of rel are assigned values here. Adding a memset() is completely redundant, and makes it slower.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Relocation
has padding bytes, which would otherwise be filled with garbage and written to disk. Garbage bytes in output make it difficult to compare created objects and prohibit bit-identical builds. This is definitely not "completely redundant" and Valgrind is right to complain about it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't believe this struct is ever written to disk. It's for use by machobj.c only. Your point about holes is valid. But because this is a performance critical issue for this type, I suggest reorganizing the Relocation struct so that there are no holes. I.e.:
struct Relocation
{
symbol *funcsym;
symbol *targsym;
unsigned offset;
unsigned targseg;
unsigned rtype;
int val;
}
should do it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't believe this struct is ever written to disk.
Um, what's this line doing at the bottom of this very function then?
pseg->SDrel->write(&rel, sizeof(rel));
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SDrel is being used as a variable length array.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, OK, I see what's going on. I added validation to Outbuffer
so that I can see in the stack trace when garbage is written to Outbuffer
, not when Outbuffer
writes said garbage to a file. This results in false positives when Outbuffer
is not being used to buffer things later written to disk. You were right, sorry.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's still reasonable to memset in debug mode.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The right fix is to reorganize the type as I suggested.
381e65f
to
097cc23
Compare
Wrapped the |
097cc23
to
d7091d5
Compare
Auto-merge toggled on |
Minor memory-safety fixes (Valgrind-identified problems, debug bounds checks)
@@ -2310,6 +2310,9 @@ void MachObj::addrel(int seg, targ_size_t offset, symbol *targsym, | |||
unsigned targseg, int rtype, int val) | |||
{ | |||
Relocation rel; | |||
#ifdef DEBUG | |||
memset(&rel, 0, sizeof(rel)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can be Relocation rel = {};
Currently some debug code to run against the autotester to help debug issue 15019:
https://issues.dlang.org/show_bug.cgi?id=15019