The general point you're making is reasonable, and something like Thread::GetStopDescription is not clear which the correct behavior should be.
But I think we can all agree that Process::ReadCStringFromMemory() returning a None object when there is an empty c-string is incorrect. People are writing code calling Process::ReadCStringFromMemory(), checking the SBError object if it was successful, and then treating the return value as if it were a string, which is reasonable to do. I'll check in the fix tomorrow, and update the TestMiniDumpNew.py test, thanks. J > On Nov 15, 2017, at 6:56 PM, Zachary Turner <ztur...@google.com> wrote: > > I don't really feel strongly about how you fix it. I'm sure there was a good > reason for making it do that, but at this point I don't remember what it is > and I don't think undoing it will cause a problem. > > That said, part of the difficulty of having an API such as this is that > Hyrum's Law [http://www.hyrumslaw.com/] is going to continue to bite you. > The reason this broke is because there was no test guaranteeing that this > behavior that people were relying on did not change. > > As a general rule, it's impossible to guarantee that no observable behavior > of an API will ever change, so unless there was a test for the original > behavior (which is documentation that this is behavior people are allowed to > rely on), I don't really consider it broken. > > Even if we are in the business of guaranteeing that the API itself won't > change, we really can't be in the business of guaranteeing that no observable > behavior of the API will ever change. That's going to be an endless > maintenance nightmare. > > On Wed, Nov 15, 2017 at 6:47 PM Jason Molenda <jmole...@apple.com> wrote: > Hi Zachary, reviving a problem I initially found a year ago -- in r253487 > where a swig typemap was changed for string reading methods. > > The problem we're seeing with this change is that > SBProcess::ReadCStringFromMemory() now returns a None object when you try to > read a zero-length string, and this is breaking a couple of groups' python > scripts here at Apple. (it was a low priority thing for me to fix, until > some behavior changed recently and it started biting the groups a lot more > frequently). > > SBProcess::ReadCStringFromMemory() takes an SBError object and returns a > string. We have three cases: > > > 1 Non-zero length string read. SBError says it was successful, string should > be returned. > > 2 Zero-length / empty string read. SBError says it was successful, string > should be returned (Python None object is returned right now) > > 3 Memory read error. SBError says it is an error, ideally None object should > be returned. > > > For instance, > > #include <stdlib.h> > int main () > { > const char *empty_string = ""; > const char *one_letter_string = "1"; > const char *invalid_memory_string = (char*)0x100; // lower 4k is always > PAGEZERO & unreadable on darwin > return empty_string[0] + one_letter_string[0]; // breakpoint here > } > > we'll see: > > (lldb) br s -p breakpoint > (lldb) r > (lldb) p empty_string > (const char *) $0 = 0x0000000100000fae "" > (lldb) p one_letter_string > (const char *) $1 = 0x0000000100000faf "1" > (lldb) p invalid_memory_string > (const char *) $2 = 0x0000000000000100 "" > (lldb) scri > >>> err = lldb.SBError() > > >>> print lldb.process.ReadCStringFromMemory(0x0000000100000fae, 2048, err) > None > >>> print err > success > > >>> print lldb.process.ReadCStringFromMemory(0x0000000100000faf, 2048, err) > 1 > >>> print err > success > > >>> print lldb.process.ReadCStringFromMemory(0x0000000000000100, 2048, err) > None > >>> print err > error: memory read failed for 0x0 > >>> print err.Success() > False > >>> > > > Before r253487, the read of a zero-length string and the read of an invalid > address would both return a zero length python string (and the latter would > set the SBError). After the change, both of these return a python None > object (and the latter sets the SBError). > > > I haven't worked with the typemaps before -- I can restore the previous > behavior where an empty Python string is returned for both the zero-length > string and for the unreadable address. I don't see how I can access the > SBError object used earlier in these methods. > > > diff --git i/scripts/Python/python-typemaps.swig > w/scripts/Python/python-typemaps.swig > index df16a6d27b3..29e5d9b156d 100644 > --- i/scripts/Python/python-typemaps.swig > +++ w/scripts/Python/python-typemaps.swig > @@ -102,7 +102,8 @@ > %typemap(argout) (char *dst, size_t dst_len) { > Py_XDECREF($result); /* Blow away any previous result */ > if (result == 0) { > - $result = Py_None; > + lldb_private::PythonString string(""); > + $result = string.release(); > Py_INCREF($result); > } else { > llvm::StringRef ref(static_cast<const char*>($1), result); > > > > This does cause one test in the testsuite to fail -- > > ====================================================================== > FAIL: test_snapshot_minidump (TestMiniDumpNew.MiniDumpNewTestCase) > Test that if we load a snapshot minidump file (meaning the process > ---------------------------------------------------------------------- > Traceback (most recent call last): > File > "/Volumes/newwork/github/stable/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/TestMiniDumpNew.py", > line 88, in test_snapshot_minidump > self.assertEqual(stop_description, None) > AssertionError: '' != None > Config=x86_64-/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang > ---------------------------------------------------------------------- > > > which is doing > > > thread = self.process.GetThreadAtIndex(0) > self.assertEqual(thread.GetStopReason(), lldb.eStopReasonNone) > stop_description = thread.GetStopDescription(256) > self.assertEqual(stop_description, None) > > > SBThread::GetStopDescription doesn't have an SBError object to indicate that > there is no stop description for eStopReasonNone. I don't think this will be > a problem if eStopReasonNone is returning an empty python string for the > StopDescription. > > > I'm not wedded to my current patch, but we do have to come up with something > that can return a zero length python string for a method like > SBProcess::ReadCStringFromMemory. _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits