I tried out the refcount checker on gdb today. I'm using git head as of a few minutes ago, with a newly-updated F15 system gcc.
I hacked cpychecker.py:
diff --git a/cpychecker.py b/cpychecker.py index e120c53..4c24e3f 100644 --- a/cpychecker.py +++ b/cpychecker.py @@ -16,4 +16,4 @@ # http://www.gnu.org/licenses/.
from libcpychecker import main -main() +main(verify_refcounting = True)
(Note that this patch causes test suite failures -- but I think that can't be very important.)
I wrote this little script to run 'make' with the right options:
#!/bin/sh
here=/home/tromey/Space/Trunk/gcc-python-plugin/ make CFLAGS="-gdwarf-4 -g3 -fplugin=$here/python.so -fplugin-arg-python-script=$here/cpychecker.py" "$@"
Then I ran it on gdb like:
/tmp/Makeit -k -C ~/gnu/archer/build/gdb -j2
I get many failures like this:
../../archer/gdb/armbsd-tdep.c: In function ‘armbsd_regset_from_core_section’: ../../archer/gdb/armbsd-tdep.c:127:3: error: Unhandled Python exception raised calling 'execute' method Traceback (most recent call last): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/__init__.py", line 49, in execute self.show_possible_null_derefs) File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/refcounts.py", line 2020, in check_refcounts limits=Limits(maxtrans=1024)) File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1821, in iter_traces f_new = facet_cls(curstate, fun=fun) File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/refcounts.py", line 224, in __init__ self.exception_rvalue = ConcreteValue(get_PyObjectPtr(), File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/types.py", line 60, in get_PyObjectPtr return get_global_typedef('PyObject').pointer AttributeError: 'NoneType' object has no attribute 'pointer' ../../archer/gdb/armbsd-tdep.c: In function ‘armbsd_regset_from_core_section’: ../../archer/gdb/armbsd-tdep.c:127:3: error: Unhandled Python exception raised calling 'execute' method Traceback (most recent call last): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/__init__.py", line 49, in execute self.show_possible_null_derefs) File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/refcounts.py", line 2020, in check_refcounts limits=Limits(maxtrans=1024)) File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1821, in iter_traces f_new = facet_cls(curstate, fun=fun) File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/refcounts.py", line 224, in __init__ self.exception_rvalue = ConcreteValue(get_PyObjectPtr(), File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/types.py", line 60, in get_PyObjectPtr return get_global_typedef('PyObject').pointer AttributeError: 'NoneType' object has no attribute 'pointer'
The problem here is that some files, like this one, do not use Python at all, and don't include the Python headers. In this situation the plugin dies when it fails to look up a Python type.
Tom
On Wed, 2011-10-12 at 13:02 -0600, Tom Tromey wrote:
I tried out the refcount checker on gdb today. I'm using git head as of a few minutes ago, with a newly-updated F15 system gcc.
Excellent! I'm still ironing out the bugs on compiling the plugin with "itself" (i.e. with the checker). Getting the refcount-checker to handle compiling gdb will be a worthwhile milestone.
I hacked cpychecker.py:
diff --git a/cpychecker.py b/cpychecker.py index e120c53..4c24e3f 100644 --- a/cpychecker.py +++ b/cpychecker.py @@ -16,4 +16,4 @@ # <http://www.gnu.org/licenses/>. from libcpychecker import main -main() +main(verify_refcounting = True)
(Note that this patch causes test suite failures -- but I think that can't be very important.)
I've been doing that too when working on the refcount checker, and I run into those failures as well. Some of the test cases enable the checker, and some don't; by hacking up cpychecker like that it's likely to break some of the ones that don't.
I wrote this little script to run 'make' with the right options:
#!/bin/sh here=/home/tromey/Space/Trunk/gcc-python-plugin/ make CFLAGS="-gdwarf-4 -g3 -fplugin=$here/python.so -fplugin-arg-python-script=$here/cpychecker.py" "$@"
Looks reasonable. I tend to use the "gcc-with-cpychecker" script: $ make CC=../some-build-of-the-plugin/gcc-with-cpychecker having hacked up that other build to force verify_refcounting to be enabled.
Then I ran it on gdb like:
/tmp/Makeit -k -C ~/gnu/archer/build/gdb -j2
I get many failures like this:
../../archer/gdb/armbsd-tdep.c: In function ‘armbsd_regset_from_core_section’: ../../archer/gdb/armbsd-tdep.c:127:3: error: Unhandled Python exception raised calling 'execute' method Traceback (most recent call last): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/__init__.py", line 49, in execute self.show_possible_null_derefs) File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/refcounts.py", line 2020, in check_refcounts limits=Limits(maxtrans=1024)) File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1821, in iter_traces f_new = facet_cls(curstate, fun=fun) File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/refcounts.py", line 224, in __init__ self.exception_rvalue = ConcreteValue(get_PyObjectPtr(), File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/types.py", line 60, in get_PyObjectPtr return get_global_typedef('PyObject').pointer AttributeError: 'NoneType' object has no attribute 'pointer' ../../archer/gdb/armbsd-tdep.c: In function ‘armbsd_regset_from_core_section’: ../../archer/gdb/armbsd-tdep.c:127:3: error: Unhandled Python exception raised calling 'execute' method Traceback (most recent call last): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/__init__.py", line 49, in execute self.show_possible_null_derefs) File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/refcounts.py", line 2020, in check_refcounts limits=Limits(maxtrans=1024)) File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1821, in iter_traces f_new = facet_cls(curstate, fun=fun) File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/refcounts.py", line 224, in __init__ self.exception_rvalue = ConcreteValue(get_PyObjectPtr(), File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/types.py", line 60, in get_PyObjectPtr return get_global_typedef('PyObject').pointer AttributeError: 'NoneType' object has no attribute 'pointer'
The problem here is that some files, like this one, do not use Python at all, and don't include the Python headers. In this situation the plugin dies when it fails to look up a Python type.
This makes a good test for the "facet"-based state handling: to only use the CPython code where necessary.
I hope I've fixed this in 269f8f3f5237c892554b3e07398edc73470d433e: http://git.fedorahosted.org/git/?p=gcc-python-plugin.git;a=commitdiff;h=269f...
Dave
Dave> I hope I've fixed this in 269f8f3f5237c892554b3e07398edc73470d433e: Dave> http://git.fedorahosted.org/git/?p=gcc-python-plugin.git;a=commitdiff;h=269f...
Ok, this did help that problem. This revealed a new one:
../../archer/gdb/arm-linux-tdep.c: In function ‘arm_linux_init_abi’: ../../archer/gdb/arm-linux-tdep.c:1152:25: error: Unhandled Python exception raised calling 'execute' method Traceback (most recent call last): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/__init__.py", line 49, in execute self.show_possible_null_derefs) File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/refcounts.py", line 2030, in check_refcounts limits=Limits(maxtrans=1024)) File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1884, in iter_traces for trace in iter_traces(fun, facets, newprefix, limits): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1852, in iter_traces transitions = curstate.get_transitions() File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1121, in get_transitions return self._get_transitions_for_stmt(stmt) File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1147, in _get_transitions_for_stmt return self._get_transitions_for_GimpleAssign(stmt) File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1518, in _get_transitions_for_GimpleAssign value = self.eval_rhs(stmt) File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 1474, in eval_rhs return self.eval_rvalue(rhs[0], stmt.loc) File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 763, in eval_rvalue lvalue = self.eval_lvalue(expr.operand, loc) File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 724, in eval_lvalue raise NotImplementedError('eval_lvalue: %r %s' % (expr, expr)) NotImplementedError: eval_lvalue: gcc.FunctionDecl('arm_linux_syscall_next_pc') gcc.FunctionDecl('arm_linux_syscall_next_pc')
Tom
On Wed, 2011-10-12 at 13:31 -0600, Tom Tromey wrote:
Dave> I hope I've fixed this in 269f8f3f5237c892554b3e07398edc73470d433e: Dave> http://git.fedorahosted.org/git/?p=gcc-python-plugin.git;a=commitdiff;h=269f...
Ok, this did help that problem. This revealed a new one:
Thanks.
Please can you post the fragment of code that caused the problem:
../../archer/gdb/arm-linux-tdep.c: In function ‘arm_linux_init_abi’: ../../archer/gdb/arm-linux-tdep.c:1152:25: error: Unhandled Python exception raised calling 'execute' method
It's here ^^^^
Traceback (most recent call last): File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/absinterp.py", line 724, in eval_lvalue raise NotImplementedError('eval_lvalue: %r %s' % (expr, expr))
...
NotImplementedError: eval_lvalue: gcc.FunctionDecl('arm_linux_syscall_next_pc') gcc.FunctionDecl('arm_linux_syscall_next_pc')
Having said that, I _think_ it's having trouble dealing with the initialization of a pointer-to-a-function l-value with a r-value that's the name of a function.
Dave
"David" == David Malcolm dmalcolm@redhat.com writes:
David> Please can you post the fragment of code that caused the problem:
../../archer/gdb/arm-linux-tdep.c: In function ‘arm_linux_init_abi’: ../../archer/gdb/arm-linux-tdep.c:1152:25: error: Unhandled Python exception raised calling 'execute' method
David> It's here ^^^^
That line is:
tdep->syscall_next_pc = arm_linux_syscall_next_pc;
arm_linux_syscall_next_pc is a function.
David> Having said that, I _think_ it's having trouble dealing with the David> initialization of a pointer-to-a-function l-value with a r-value that's David> the name of a function.
I agree.
Tom
On Wed, 2011-10-12 at 13:38 -0600, Tom Tromey wrote:
"David" == David Malcolm dmalcolm@redhat.com writes:
...
David> Having said that, I _think_ it's having trouble dealing with the David> initialization of a pointer-to-a-function l-value with a r-value that's David> the name of a function.
Thanks. Should be fixed as of b6496b518378d67067f42c15057664643943b9b1
For good measure, the analyzer will now emit errors for paths through a function for which it can prove that a call through a function pointer is calling through an uninitialized or NULL r-value.
See: http://git.fedorahosted.org/git/?p=gcc-python-plugin.git;a=commitdiff;h=b649... for the gory details
Dave
Dave> Thanks. Should be fixed as of b6496b518378d67067f42c15057664643943b9b1
Thanks, that helped.
I got a bunch more errors this time. Probably they were there all along, I just stopped at the first one.
I've appended a short summary of all of them -- I did some simple uniquification, but it didn't collapse everything possible. Many problems seem to be missing exprcodes, there is just a single spot in absinterp.py that gives that error.
I also get some false errors. E.g.:
../../archer/gdb/arm-tdep.c: In function ‘gdb_print_insn_arm’: ../../archer/gdb/arm-tdep.c:8381:10: error: comparison against uninitialized data: gcc.VarDecl(31027) at ../../archer/gdb/arm-tdep.c:8381
The code here is:
static struct coff_symbol_struct csym; static struct bfd fake_bfd; static bfd_target fake_target;
if (csym.native == NULL) {
... since csym is static, it is 0-initialized.
Or another example:
../../archer/gdb/arm-linux-tdep.c: In function ‘arm_linux_cleanup_svc’: ../../archer/gdb/arm-linux-tdep.c:874:18: error: comparison against uninitialized data: gcc.VarDecl('apparent_pc.15') at ../../archer/gdb/arm-linux-tdep.c:874 ../../archer/gdb/arm-linux-tdep.c:868:13: note: when treating unknown struct displaced_step_closure * from ../../archer/gdb/arm-linux-tdep.c:866 as non-NULL at: CORE_ADDR from = dsc->insn_addr; ../../archer/gdb/arm-linux-tdep.c:867:1: note: graphical error report for function 'arm_linux_cleanup_svc' written out to 'arm-linux-tdep.c.arm_linux_cleanup_svc-refcount-errors.html'
Here the code is:
CORE_ADDR from = dsc->insn_addr; ULONGEST apparent_pc; int within_scratch;
regcache_cooked_read_unsigned (regs, ARM_PC_REGNUM, &apparent_pc);
within_scratch = (apparent_pc >= dsc->scratch_base && apparent_pc < (dsc->scratch_base + DISPLACED_MODIFIED_INSNS * 4 + 4));
regcache_cooked_read_unsigned sets apparent_pc, so it isn't uninitialized.
How would you like to proceed? You can check out and build gdb pretty easily... that might be the simplest. Otherwise I can provide context for all of the appended, but that will take some time.
Tom
AttributeError: 'NoneType' object has no attribute 'loc' NotImplementedError: Don't know how to cope with exprcode: <type 'gcc.AbsExpr'> (<type 'gcc.AbsExpr'>) NotImplementedError: Don't know how to cope with exprcode: <type 'gcc.BitFieldRef'> (<type 'gcc.BitFieldRef'>) NotImplementedError: Don't know how to cope with exprcode: <type 'gcc.BitNotExpr'> (<type 'gcc.BitNotExpr'>) NotImplementedError: Don't know how to cope with exprcode: <type 'gcc.Constructor'> (<type 'gcc.Constructor'>) NotImplementedError: Don't know how to cope with exprcode: <type 'gcc.MaxExpr'> (<type 'gcc.MaxExpr'>) NotImplementedError: Don't know how to cope with exprcode: <type 'gcc.MinExpr'> (<type 'gcc.MinExpr'>) NotImplementedError: Don't know how to cope with exprcode: <type 'gcc.NegateExpr'> (<type 'gcc.NegateExpr'>) NotImplementedError: Don't know how to cope with exprcode: <type 'gcc.TruncModExpr'> (<type 'gcc.TruncModExpr'>) NotImplementedError: Don't know how to cope with exprcode: <type 'gcc.TruthXorExpr'> (<type 'gcc.TruthXorExpr'>) NotImplementedError: Don't know how to cope with gcc.GimplePredict() (// predicted unlikely by continue predictor.) NotImplementedError: Don't know how to cope with type conversion of: ConcreteValue(gcctype='int', loc=gcc.Location(file='../../archer/gdb/arm-tdep.c', line=7719), value=1) ((int)1 from ../../archer/gdb/arm-tdep.c:7719) NotImplementedError: Don't know how to cope with type conversion of: ConcreteValue(gcctype='int', loc=gcc.Location(file='../../archer/gdb/i387-tdep.c', line=675), value=128) ((int)128 from ../../archer/gdb/i387-tdep.c:675) NotImplementedError: Don't know how to cope with type conversion of: ConcreteValue(gcctype='long unsigned int', loc=gcc.Location(file='../../archer/gdb/i386-tdep.c', line=3691), value=0) ((long unsigned int)0 from ../../archer/gdb/i386-tdep.c:3691) NotImplementedError: Don't know how to cope with type conversion of: ConcreteValue(gcctype='unsigned int', loc=gcc.Location(file='../../archer/gdb/arm-tdep.c', line=5784), value=14) ((unsigned int)14 from ../../archer/gdb/arm-tdep.c:5784) NotImplementedError: Don't know how to cope with type conversion of: ConcreteValue(gcctype='unsigned int', loc=gcc.Location(file='../../archer/gdb/mips-tdep.c', line=1670), value=0) ((unsigned int)0 from ../../archer/gdb/mips-tdep.c:1670) NotImplementedError: Don't know how to cope with type conversion of: PointerToRegion(gcctype='char *', loc=gcc.Location(file='../../archer/gdb/i386-cygwin-tdep.c', line=158), region=Region('heap-region-6[12]')) ((char *)&Region('heap-region-6[12]') from ../../archer/gdb/i386-cygwin-tdep.c:158) NotImplementedError: Don't know how to cope with type conversion of: PointerToRegion(gcctype='gdb_byte *', loc=gcc.Location(file='../../archer/gdb/i386-tdep.c', line=616), region=Region('heap-region-310')) ((gdb_byte *)&Region('heap-region-310') from ../../archer/gdb/i386-tdep.c:616) NotImplementedError: Don't know how to cope with type conversion of: PointerToRegion(gcctype='struct i386_insn *', loc=gcc.Location(file='../../archer/gdb/i386-tdep.c', line=1194), region=Region('heap-region-300')) ((struct i386_insn *)&Region('heap-region-300') from ../../archer/gdb/i386-tdep.c:1194) NotImplementedError: Don't know how to cope with type conversion of: UninitializedData(gcctype='CORE_ADDR', loc=gcc.Location(file='../../archer/gdb/m68hc11-tdep.c', line=616)) (uninitialized data NotImplementedError: Don't know how to cope with type conversion of: UninitializedData(gcctype='long int', loc=gcc.Location(file='../../archer/gdb/i386-linux-tdep.c', line=423)) (uninitialized data NotImplementedError: Don't know how to cope with type conversion of: UninitializedData(gcctype='long unsigned int', loc=gcc.Location(file='../../archer/gdb/mep-tdep.c', line=872)) (uninitialized data TypeError: struct gdbarch_info / <gcc.RecordType object TypeError: struct srcdest / <gcc.RecordType object TypeError: type "const void" does not have a "sizeof" TypeError: type "void" does not have a "sizeof"
On Wed, 2011-10-12 at 15:01 -0600, Tom Tromey wrote:
Dave> Thanks. Should be fixed as of b6496b518378d67067f42c15057664643943b9b1
Thanks, that helped.
I got a bunch more errors this time. Probably they were there all along, I just stopped at the first one.
Yes, I've been running into similar behavior when running the checker against the plugin.
I've appended a short summary of all of them -- I did some simple uniquification, but it didn't collapse everything possible. Many problems seem to be missing exprcodes, there is just a single spot in absinterp.py that gives that error.
Many thanks for doing this. Various replies inline below.
I also get some false errors. E.g.:
../../archer/gdb/arm-tdep.c: In function ‘gdb_print_insn_arm’: ../../archer/gdb/arm-tdep.c:8381:10: error: comparison against uninitialized data: gcc.VarDecl(31027) at ../../archer/gdb/arm-tdep.c:8381
The code here is:
static struct coff_symbol_struct csym; static struct bfd fake_bfd; static bfd_target fake_target; if (csym.native == NULL)
{
... since csym is static, it is 0-initialized.
Ooops; thanks. I've fixed this in fcc1a57b50dae09868451e229242ebe4d81198a5 http://git.fedorahosted.org/git/?p=gcc-python-plugin.git;a=commitdiff;h=fcc1...
As noted in that commit, it doesn't yet attempt to track the state of such static variables across multiple function calls - it assumes an UnknownValue at the top of the function each time, hence it will report on some impossible paths (e.g. in the test case in my commit) - but at least it ought to fix that false warning above.
Or another example:
../../archer/gdb/arm-linux-tdep.c: In function ‘arm_linux_cleanup_svc’: ../../archer/gdb/arm-linux-tdep.c:874:18: error: comparison against uninitialized data: gcc.VarDecl('apparent_pc.15') at ../../archer/gdb/arm-linux-tdep.c:874 ../../archer/gdb/arm-linux-tdep.c:868:13: note: when treating unknown struct displaced_step_closure * from ../../archer/gdb/arm-linux-tdep.c:866 as non-NULL at: CORE_ADDR from = dsc->insn_addr; ../../archer/gdb/arm-linux-tdep.c:867:1: note: graphical error report for function 'arm_linux_cleanup_svc' written out to 'arm-linux-tdep.c.arm_linux_cleanup_svc-refcount-errors.html'
Here the code is:
CORE_ADDR from = dsc->insn_addr; ULONGEST apparent_pc; int within_scratch;
regcache_cooked_read_unsigned (regs, ARM_PC_REGNUM, &apparent_pc);
within_scratch = (apparent_pc >= dsc->scratch_base && apparent_pc < (dsc->scratch_base + DISPLACED_MODIFIED_INSNS * 4 + 4));
regcache_cooked_read_unsigned sets apparent_pc, so it isn't uninitialized.
This is a different bug, which (I hope) I've fixed in 496bf276623d6930fe8cfbc42a837cbc62bfe519 http://git.fedorahosted.org/git/?p=gcc-python-plugin.git;a=commitdiff;h=496b...
How would you like to proceed? You can check out and build gdb pretty easily... that might be the simplest. Otherwise I can provide context for all of the appended, but that will take some time.
What recipe are you using to check out and configure the code?
There is a third way, which is to try compiling GCC's own test suite, using GCC with the cpychecker code. That ought to achieve a much higher level of coverage than I've been getting up till now. I may have a look at this tomorrow.
BTW, is the code you're compiling purely C ?
In the meantime, here are some notes on the other errors you reported:
AttributeError: 'NoneType' object has no attribute 'loc'
I'm not sure of the context for this one ^^^^
NotImplementedError: Don't know how to cope with exprcode: <type 'gcc.AbsExpr'> (<type 'gcc.AbsExpr'>) NotImplementedError: Don't know how to cope with exprcode: <type 'gcc.BitFieldRef'> (<type 'gcc.BitFieldRef'>) NotImplementedError: Don't know how to cope with exprcode: <type 'gcc.BitNotExpr'> (<type 'gcc.BitNotExpr'>) NotImplementedError: Don't know how to cope with exprcode: <type 'gcc.Constructor'> (<type 'gcc.Constructor'>) NotImplementedError: Don't know how to cope with exprcode: <type 'gcc.MaxExpr'> (<type 'gcc.MaxExpr'>) NotImplementedError: Don't know how to cope with exprcode: <type 'gcc.MinExpr'> (<type 'gcc.MinExpr'>) NotImplementedError: Don't know how to cope with exprcode: <type 'gcc.NegateExpr'> (<type 'gcc.NegateExpr'>) NotImplementedError: Don't know how to cope with exprcode: <type 'gcc.TruncModExpr'> (<type 'gcc.TruncModExpr'>) NotImplementedError: Don't know how to cope with exprcode: <type 'gcc.TruthXorExpr'> (<type 'gcc.TruthXorExpr'>)
Re the above, I'm not sure of the context for the 'gcc.Constructor' one. I think I can figure out the other ones.
NotImplementedError: Don't know how to cope with gcc.GimplePredict() (// predicted unlikely by continue predictor.)
^^^ not sure where this is coming from
NotImplementedError: Don't know how to cope with type conversion of: ConcreteValue(gcctype='int', loc=gcc.Location(file='../../archer/gdb/arm-tdep.c', line=7719), value=1) ((int)1 from ../../archer/gdb/arm-tdep.c:7719)
... snip various similar ones... ^^^ I'm running into these myself, FWIW
TypeError: struct gdbarch_info / <gcc.RecordType object TypeError: struct srcdest / <gcc.RecordType object
^^^ not sure what happened here
TypeError: type "const void" does not have a "sizeof" TypeError: type "void" does not have a "sizeof"
^^^ not sure what happened here
Thanks again for the feedback Dave
David> What recipe are you using to check out and configure the code?
First: yum-builddeps gdb. Then: git clone git://sourceware.org/git/gdb.git src
Then I make new build and install directories and build in a separate tree:
mkdir build install cd build ../src/configure --prefix=$(cd ../install && pwd) --enable-targets=all make -j2
If you want to really use the resulting gdb on Fedora you also want --with-separate-debug-dir=/usr/lib/debug/ in there.
For this test I was then doing 'cd gdb; make mostlyclean'; then running running make in just this directory with the plugin arguments. That is, I didn't try building libiberty and bfd and whatnot with the plugin.
Now I'm trying something else: I'm removing just the python-using objects from gdb to see what happens with those. I'll let you know.
David> BTW, is the code you're compiling purely C ?
Yes.
FWIW I looked and I interrupted the build partway through yesterday. So there are probably even more errors than what I posted.
David> In the meantime, here are some notes on the other errors you reported:
AttributeError: 'NoneType' object has no attribute 'loc'
David> I'm not sure of the context for this one ^^^^ [...]
I was going to attach the whole log so you can see the context, but it is quite large.
Tom
Tom> Now I'm trying something else: I'm removing just the python-using Tom> objects from gdb to see what happens with those. I'll let you know.
I tried this. I get various Python exceptions and also a bunch of errors emitted by the plugin. I haven't gone through all the errors; but when I spot-check them they seem to be incorrect.
One generic problem is that the plugin seems to make assumptions about function calls which are not wholly warranted in gdb. E.g., consider this function:
PyObject * create_breakpoint_event_object (PyObject *breakpoint_list, PyObject *first_bp) { PyObject *breakpoint_event_obj = create_stop_event_object (&breakpoint_event_object_type);
if (!breakpoint_event_obj) goto fail;
if (evpy_add_attribute (breakpoint_event_obj, "breakpoint", first_bp) < 0) goto fail; if (evpy_add_attribute (breakpoint_event_obj, "breakpoints", breakpoint_list) < 0) goto fail;
return breakpoint_event_obj;
fail: Py_XDECREF (breakpoint_event_obj); return NULL; }
Here, evpy_add_attribute follows the convention that a negative return means failure, and furthermore that a Python exception has been set. But, I get these errors:
../../archer/gdb/python/py-bpevent.c: In function ‘create_breakpoint_event_object’: ../../archer/gdb/python/py-bpevent.c:49:1: error: returning (PyObject*)NULL without setting an exception ../../archer/gdb/python/py-bpevent.c:29:13: note: when create_stop_event_object() succeeds at: PyObject *breakpoint_event_obj = ../../archer/gdb/python/py-bpevent.c:32:6: note: taking False path at: if (!breakpoint_event_obj) ../../archer/gdb/python/py-bpevent.c:35:26: note: reaching: if (evpy_add_attribute (breakpoint_event_obj, ../../archer/gdb/python/py-bpevent.c:35:6: note: when taking True path at: if (evpy_add_attribute (breakpoint_event_obj, ../../archer/gdb/python/py-bpevent.c:47:3: note: taking False path at: Py_XDECREF (breakpoint_event_obj); ../../archer/gdb/python/py-bpevent.c:47:3: note: reaching: Py_XDECREF (breakpoint_event_obj); ../../archer/gdb/python/py-bpevent.c:47:3: note: when taking True path at: Py_XDECREF (breakpoint_event_obj); ../../archer/gdb/python/py-bpevent.c:48:3: note: reaching: return NULL;
Now, I understand that the plugin cannot know that evpy_add_attribute follows this convention -- the function is defined elsewhere, not visible to the current compilation.
One thing this suggests to me is having the plugin export various attributes that I could use to mark up function declarations. Then the plugin could use the attributes to make assumptions about function calls it sees; and furthermore check that the function definition in fact conforms to the declared attribute.
In a scenario like this I can understand that you'd only want to support some limited set of attributes; but I'd be willing to change code in gdb if it meant that I could get robust refcount checking.
Tom
On Thu, 2011-10-13 at 07:45 -0600, Tom Tromey wrote:
David> What recipe are you using to check out and configure the code?
First: yum-builddeps gdb.
Minor nit: "yum-builddep", rather than "yum-builddeps"
Then: git clone git://sourceware.org/git/gdb.git src
Then I make new build and install directories and build in a separate tree:
mkdir build install cd build ../src/configure --prefix=$(cd ../install && pwd) --enable-targets=all make -j2
If you want to really use the resulting gdb on Fedora you also want --with-separate-debug-dir=/usr/lib/debug/ in there.
For this test I was then doing 'cd gdb; make mostlyclean'; then running running make in just this directory with the plugin arguments. That is, I didn't try building libiberty and bfd and whatnot with the plugin.
I was able to do this after the "make mostlyclean" with: $ make CC=$(pwd)/../../../gcc-python-working-copy/gcc-with-cpychecker
(with an appropriate path to a build of the plugin, having hacked it up to forcibly enable the refcount checking code) [looks like such a path needs to be absolute, given that the make traverses various subdirectories]
...and I'm now seeing the errors you reported. Thanks!
[...snip...]
On Fri, 2011-10-14 at 17:29 -0400, David Malcolm wrote:
On Thu, 2011-10-13 at 07:45 -0600, Tom Tromey wrote:
David> What recipe are you using to check out and configure the code?
[...snip instructions for building gdb using gcc-python-plugin with checking of reference counts turned on]
I'm attaching some HTML error reports. Within gdb/python/py-breakpoint.c: gdbpy_breakpoints there appear to be some false positives about returning NULL without setting an exception, but the "ob_refcnt of '*list' is 1 too high" errors appear to be a genuine memory leak in gdb.breakpoints()
Within gdb/python/py-inferior.c : gdbpy_inferiors this seems very similar to the above, both with analogous false positives, and with what appear to be genuine leaks of "*list".
There are a few more of these; I'm trying to decide what the best place to send them to is, given that there's a fair chance that the checker has errors within it.
Hope this is helpful Dave
"David" == David Malcolm dmalcolm@redhat.com writes:
David> I'm attaching some HTML error reports. David> Within gdb/python/py-breakpoint.c: gdbpy_breakpoints David> there appear to be some false positives about returning NULL without David> setting an exception
Yeah. On that path the error will have been set by 'build_bp_list'.
David>, but the "ob_refcnt of '*list' is 1 too high" David> errors appear to be a genuine memory leak in gdb.breakpoints()
I agree.
David> Within gdb/python/py-inferior.c : gdbpy_inferiors David> this seems very similar to the above, both with analogous false David> positives, and with what appear to be genuine leaks of "*list".
Yup.
David> There are a few more of these; I'm trying to decide what the best place David> to send them to is, given that there's a fair chance that the checker David> has errors within it.
I guess gdb bug reports, if that isn't too much trouble. http://sourceware.org/bugzilla/
Alternatively if most of the noise is gone from the plugin output, one of us can run the plugin and work through the gdb bugs.
Tom
On Mon, 2011-10-17 at 13:32 -0600, Tom Tromey wrote:
"David" == David Malcolm dmalcolm@redhat.com writes:
David> I'm attaching some HTML error reports. David> Within gdb/python/py-breakpoint.c: gdbpy_breakpoints David> there appear to be some false positives about returning NULL without David> setting an exception
Yeah. On that path the error will have been set by 'build_bp_list'.
David>, but the "ob_refcnt of '*list' is 1 too high" David> errors appear to be a genuine memory leak in gdb.breakpoints()
I agree.
Thanks; filed as: http://sourceware.org/bugzilla/show_bug.cgi?id=13308
(I hand-edited the HTML before reporting, to remove the false positives; thankfully the HTML is relatively sane).
David> Within gdb/python/py-inferior.c : gdbpy_inferiors David> this seems very similar to the above, both with analogous false David> positives, and with what appear to be genuine leaks of "*list".
Yup.
Filed as: http://sourceware.org/bugzilla/show_bug.cgi?id=13309
David> There are a few more of these; I'm trying to decide what the best place David> to send them to is, given that there's a fair chance that the checker David> has errors within it.
I guess gdb bug reports, if that isn't too much trouble. http://sourceware.org/bugzilla/
Thanks. I've filed another one as: http://sourceware.org/bugzilla/show_bug.cgi?id=13310
Alternatively if most of the noise is gone from the plugin output, one of us can run the plugin and work through the gdb bugs.
Unfortunately there's still a lot of noise in the output, which I'm slowly fixing...
Dave
gcc-python-plugin@lists.fedorahosted.org