Detecting When a Struct or Hashtable Get Modified or Corrupted












0















Are there any tools in Common Lisp that can be used to debug a condition along the following lines?



There is a hashtable that gets modified (one of key's values turns to NIL), and I am trying to debug it. I was able to narrow it down to where it is supposedly happening, but the table does not explicitly get modified there via the official accessors.



I can't post code because it is proprietary.










share|improve this question


















  • 2





    What is the implementation? Are there any threading issues?

    – sds
    Nov 21 '18 at 19:53






  • 1





    What do you mean by “one of key's values”? Is a value modified or a key?

    – Svante
    Nov 21 '18 at 23:20











  • a key has only one value in a hash-table, it doesn't have multiple values.

    – Rainer Joswig
    Nov 22 '18 at 8:13











  • It is an Allegro. And, yes, I meant that a particular key has a value that gets modified.

    – MadPhysicist
    Nov 23 '18 at 1:13











  • if it's allegro you should ask support

    – Vsevolod Dyomkin
    Nov 28 '18 at 7:00
















0















Are there any tools in Common Lisp that can be used to debug a condition along the following lines?



There is a hashtable that gets modified (one of key's values turns to NIL), and I am trying to debug it. I was able to narrow it down to where it is supposedly happening, but the table does not explicitly get modified there via the official accessors.



I can't post code because it is proprietary.










share|improve this question


















  • 2





    What is the implementation? Are there any threading issues?

    – sds
    Nov 21 '18 at 19:53






  • 1





    What do you mean by “one of key's values”? Is a value modified or a key?

    – Svante
    Nov 21 '18 at 23:20











  • a key has only one value in a hash-table, it doesn't have multiple values.

    – Rainer Joswig
    Nov 22 '18 at 8:13











  • It is an Allegro. And, yes, I meant that a particular key has a value that gets modified.

    – MadPhysicist
    Nov 23 '18 at 1:13











  • if it's allegro you should ask support

    – Vsevolod Dyomkin
    Nov 28 '18 at 7:00














0












0








0








Are there any tools in Common Lisp that can be used to debug a condition along the following lines?



There is a hashtable that gets modified (one of key's values turns to NIL), and I am trying to debug it. I was able to narrow it down to where it is supposedly happening, but the table does not explicitly get modified there via the official accessors.



I can't post code because it is proprietary.










share|improve this question














Are there any tools in Common Lisp that can be used to debug a condition along the following lines?



There is a hashtable that gets modified (one of key's values turns to NIL), and I am trying to debug it. I was able to narrow it down to where it is supposedly happening, but the table does not explicitly get modified there via the official accessors.



I can't post code because it is proprietary.







runtime-error runtime common-lisp hashtable






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 21 '18 at 19:10









MadPhysicistMadPhysicist

1,37441341




1,37441341








  • 2





    What is the implementation? Are there any threading issues?

    – sds
    Nov 21 '18 at 19:53






  • 1





    What do you mean by “one of key's values”? Is a value modified or a key?

    – Svante
    Nov 21 '18 at 23:20











  • a key has only one value in a hash-table, it doesn't have multiple values.

    – Rainer Joswig
    Nov 22 '18 at 8:13











  • It is an Allegro. And, yes, I meant that a particular key has a value that gets modified.

    – MadPhysicist
    Nov 23 '18 at 1:13











  • if it's allegro you should ask support

    – Vsevolod Dyomkin
    Nov 28 '18 at 7:00














  • 2





    What is the implementation? Are there any threading issues?

    – sds
    Nov 21 '18 at 19:53






  • 1





    What do you mean by “one of key's values”? Is a value modified or a key?

    – Svante
    Nov 21 '18 at 23:20











  • a key has only one value in a hash-table, it doesn't have multiple values.

    – Rainer Joswig
    Nov 22 '18 at 8:13











  • It is an Allegro. And, yes, I meant that a particular key has a value that gets modified.

    – MadPhysicist
    Nov 23 '18 at 1:13











  • if it's allegro you should ask support

    – Vsevolod Dyomkin
    Nov 28 '18 at 7:00








2




2





What is the implementation? Are there any threading issues?

– sds
Nov 21 '18 at 19:53





What is the implementation? Are there any threading issues?

– sds
Nov 21 '18 at 19:53




1




1





What do you mean by “one of key's values”? Is a value modified or a key?

– Svante
Nov 21 '18 at 23:20





What do you mean by “one of key's values”? Is a value modified or a key?

– Svante
Nov 21 '18 at 23:20













a key has only one value in a hash-table, it doesn't have multiple values.

– Rainer Joswig
Nov 22 '18 at 8:13





a key has only one value in a hash-table, it doesn't have multiple values.

– Rainer Joswig
Nov 22 '18 at 8:13













It is an Allegro. And, yes, I meant that a particular key has a value that gets modified.

– MadPhysicist
Nov 23 '18 at 1:13





It is an Allegro. And, yes, I meant that a particular key has a value that gets modified.

– MadPhysicist
Nov 23 '18 at 1:13













if it's allegro you should ask support

– Vsevolod Dyomkin
Nov 28 '18 at 7:00





if it's allegro you should ask support

– Vsevolod Dyomkin
Nov 28 '18 at 7:00












1 Answer
1






active

oldest

votes


















2














I would suggest two things. The first is to try to trace the function that modifies hash tables. That is (setf gethash) except that gethash is an accessor and not a function. To find out which function is used by the implementation to update the hash-table, do e.g.



(disassemble (compile (defun foo (x y) (setf (gethash x y) t))))


which shows assembly code that should contain a call to an internal function with a name like puthash.



The act of (trace puthash) might lead to a problem as the implementation might update a hash-table as part of this call. But assuming it works, it might show you where an unexpected hash-table update takes place.



Some implementations have extended the functionality of trace. For example Allegro CL offer many trace options. E.g. if your functions are called foo and bar and you want to see calls to excl::%puthash from within those functions, you'd say:



(trace (excl::%puthash :inside (foo bar))


and if you want to see what the context of the call is, include a bit of the stack:



cl-user(1): (trace (excl::%puthash :inside foo :show-stack 3))
(excl::%puthash)
cl-user(2): (setf (gethash 3 (make-hash-table)) 2)
;; Note: no trace output, because not in foo
2
cl-user(3): (foo 3 (make-hash-table))
;; Note: within foo, so trace output which includes 3 stack frames
0[2]: (excl::%puthash 3 #<eql hash-table with 0 entries @ #x100192cfa72> t)
0^ <- (system::..runtime-operation "fwrap_start" 3 #<eql hash-table with 0 entries @ #x100192cfa72> t)
0^ <- (foo 3 #<eql hash-table with 0 entries @ #x100192cfa72>)
0^ <- (eval (foo 3 (make-hash-table)))
0[2]: returned t
t


Tracing like this can be extremely helpful when dealing with unknown code.



The second thing to do, is checking the code to make sure that keys stored in the hash-table are not modified. E.g.



(let ((x (list 1 2))
(ht (make-hash-table :test 'equal))
(setf (gethash x ht) t)
(setf (car x) 10) ;; not allowed!
(gethash x ht)) ;; now in a funny state: may return T, or nil


See 18.1.2 Modifying Hash Table Keys.
Moreover literal objects may not be modified either, that could be a cause of weirdness too:



(let ((x '(1 2)))
(setf (car x) 10) ;; not allowed!





share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53419027%2fdetecting-when-a-struct-or-hashtable-get-modified-or-corrupted%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    2














    I would suggest two things. The first is to try to trace the function that modifies hash tables. That is (setf gethash) except that gethash is an accessor and not a function. To find out which function is used by the implementation to update the hash-table, do e.g.



    (disassemble (compile (defun foo (x y) (setf (gethash x y) t))))


    which shows assembly code that should contain a call to an internal function with a name like puthash.



    The act of (trace puthash) might lead to a problem as the implementation might update a hash-table as part of this call. But assuming it works, it might show you where an unexpected hash-table update takes place.



    Some implementations have extended the functionality of trace. For example Allegro CL offer many trace options. E.g. if your functions are called foo and bar and you want to see calls to excl::%puthash from within those functions, you'd say:



    (trace (excl::%puthash :inside (foo bar))


    and if you want to see what the context of the call is, include a bit of the stack:



    cl-user(1): (trace (excl::%puthash :inside foo :show-stack 3))
    (excl::%puthash)
    cl-user(2): (setf (gethash 3 (make-hash-table)) 2)
    ;; Note: no trace output, because not in foo
    2
    cl-user(3): (foo 3 (make-hash-table))
    ;; Note: within foo, so trace output which includes 3 stack frames
    0[2]: (excl::%puthash 3 #<eql hash-table with 0 entries @ #x100192cfa72> t)
    0^ <- (system::..runtime-operation "fwrap_start" 3 #<eql hash-table with 0 entries @ #x100192cfa72> t)
    0^ <- (foo 3 #<eql hash-table with 0 entries @ #x100192cfa72>)
    0^ <- (eval (foo 3 (make-hash-table)))
    0[2]: returned t
    t


    Tracing like this can be extremely helpful when dealing with unknown code.



    The second thing to do, is checking the code to make sure that keys stored in the hash-table are not modified. E.g.



    (let ((x (list 1 2))
    (ht (make-hash-table :test 'equal))
    (setf (gethash x ht) t)
    (setf (car x) 10) ;; not allowed!
    (gethash x ht)) ;; now in a funny state: may return T, or nil


    See 18.1.2 Modifying Hash Table Keys.
    Moreover literal objects may not be modified either, that could be a cause of weirdness too:



    (let ((x '(1 2)))
    (setf (car x) 10) ;; not allowed!





    share|improve this answer




























      2














      I would suggest two things. The first is to try to trace the function that modifies hash tables. That is (setf gethash) except that gethash is an accessor and not a function. To find out which function is used by the implementation to update the hash-table, do e.g.



      (disassemble (compile (defun foo (x y) (setf (gethash x y) t))))


      which shows assembly code that should contain a call to an internal function with a name like puthash.



      The act of (trace puthash) might lead to a problem as the implementation might update a hash-table as part of this call. But assuming it works, it might show you where an unexpected hash-table update takes place.



      Some implementations have extended the functionality of trace. For example Allegro CL offer many trace options. E.g. if your functions are called foo and bar and you want to see calls to excl::%puthash from within those functions, you'd say:



      (trace (excl::%puthash :inside (foo bar))


      and if you want to see what the context of the call is, include a bit of the stack:



      cl-user(1): (trace (excl::%puthash :inside foo :show-stack 3))
      (excl::%puthash)
      cl-user(2): (setf (gethash 3 (make-hash-table)) 2)
      ;; Note: no trace output, because not in foo
      2
      cl-user(3): (foo 3 (make-hash-table))
      ;; Note: within foo, so trace output which includes 3 stack frames
      0[2]: (excl::%puthash 3 #<eql hash-table with 0 entries @ #x100192cfa72> t)
      0^ <- (system::..runtime-operation "fwrap_start" 3 #<eql hash-table with 0 entries @ #x100192cfa72> t)
      0^ <- (foo 3 #<eql hash-table with 0 entries @ #x100192cfa72>)
      0^ <- (eval (foo 3 (make-hash-table)))
      0[2]: returned t
      t


      Tracing like this can be extremely helpful when dealing with unknown code.



      The second thing to do, is checking the code to make sure that keys stored in the hash-table are not modified. E.g.



      (let ((x (list 1 2))
      (ht (make-hash-table :test 'equal))
      (setf (gethash x ht) t)
      (setf (car x) 10) ;; not allowed!
      (gethash x ht)) ;; now in a funny state: may return T, or nil


      See 18.1.2 Modifying Hash Table Keys.
      Moreover literal objects may not be modified either, that could be a cause of weirdness too:



      (let ((x '(1 2)))
      (setf (car x) 10) ;; not allowed!





      share|improve this answer


























        2












        2








        2







        I would suggest two things. The first is to try to trace the function that modifies hash tables. That is (setf gethash) except that gethash is an accessor and not a function. To find out which function is used by the implementation to update the hash-table, do e.g.



        (disassemble (compile (defun foo (x y) (setf (gethash x y) t))))


        which shows assembly code that should contain a call to an internal function with a name like puthash.



        The act of (trace puthash) might lead to a problem as the implementation might update a hash-table as part of this call. But assuming it works, it might show you where an unexpected hash-table update takes place.



        Some implementations have extended the functionality of trace. For example Allegro CL offer many trace options. E.g. if your functions are called foo and bar and you want to see calls to excl::%puthash from within those functions, you'd say:



        (trace (excl::%puthash :inside (foo bar))


        and if you want to see what the context of the call is, include a bit of the stack:



        cl-user(1): (trace (excl::%puthash :inside foo :show-stack 3))
        (excl::%puthash)
        cl-user(2): (setf (gethash 3 (make-hash-table)) 2)
        ;; Note: no trace output, because not in foo
        2
        cl-user(3): (foo 3 (make-hash-table))
        ;; Note: within foo, so trace output which includes 3 stack frames
        0[2]: (excl::%puthash 3 #<eql hash-table with 0 entries @ #x100192cfa72> t)
        0^ <- (system::..runtime-operation "fwrap_start" 3 #<eql hash-table with 0 entries @ #x100192cfa72> t)
        0^ <- (foo 3 #<eql hash-table with 0 entries @ #x100192cfa72>)
        0^ <- (eval (foo 3 (make-hash-table)))
        0[2]: returned t
        t


        Tracing like this can be extremely helpful when dealing with unknown code.



        The second thing to do, is checking the code to make sure that keys stored in the hash-table are not modified. E.g.



        (let ((x (list 1 2))
        (ht (make-hash-table :test 'equal))
        (setf (gethash x ht) t)
        (setf (car x) 10) ;; not allowed!
        (gethash x ht)) ;; now in a funny state: may return T, or nil


        See 18.1.2 Modifying Hash Table Keys.
        Moreover literal objects may not be modified either, that could be a cause of weirdness too:



        (let ((x '(1 2)))
        (setf (car x) 10) ;; not allowed!





        share|improve this answer













        I would suggest two things. The first is to try to trace the function that modifies hash tables. That is (setf gethash) except that gethash is an accessor and not a function. To find out which function is used by the implementation to update the hash-table, do e.g.



        (disassemble (compile (defun foo (x y) (setf (gethash x y) t))))


        which shows assembly code that should contain a call to an internal function with a name like puthash.



        The act of (trace puthash) might lead to a problem as the implementation might update a hash-table as part of this call. But assuming it works, it might show you where an unexpected hash-table update takes place.



        Some implementations have extended the functionality of trace. For example Allegro CL offer many trace options. E.g. if your functions are called foo and bar and you want to see calls to excl::%puthash from within those functions, you'd say:



        (trace (excl::%puthash :inside (foo bar))


        and if you want to see what the context of the call is, include a bit of the stack:



        cl-user(1): (trace (excl::%puthash :inside foo :show-stack 3))
        (excl::%puthash)
        cl-user(2): (setf (gethash 3 (make-hash-table)) 2)
        ;; Note: no trace output, because not in foo
        2
        cl-user(3): (foo 3 (make-hash-table))
        ;; Note: within foo, so trace output which includes 3 stack frames
        0[2]: (excl::%puthash 3 #<eql hash-table with 0 entries @ #x100192cfa72> t)
        0^ <- (system::..runtime-operation "fwrap_start" 3 #<eql hash-table with 0 entries @ #x100192cfa72> t)
        0^ <- (foo 3 #<eql hash-table with 0 entries @ #x100192cfa72>)
        0^ <- (eval (foo 3 (make-hash-table)))
        0[2]: returned t
        t


        Tracing like this can be extremely helpful when dealing with unknown code.



        The second thing to do, is checking the code to make sure that keys stored in the hash-table are not modified. E.g.



        (let ((x (list 1 2))
        (ht (make-hash-table :test 'equal))
        (setf (gethash x ht) t)
        (setf (car x) 10) ;; not allowed!
        (gethash x ht)) ;; now in a funny state: may return T, or nil


        See 18.1.2 Modifying Hash Table Keys.
        Moreover literal objects may not be modified either, that could be a cause of weirdness too:



        (let ((x '(1 2)))
        (setf (car x) 10) ;; not allowed!






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 22 '18 at 22:52









        zutzut

        55624




        55624
































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53419027%2fdetecting-when-a-struct-or-hashtable-get-modified-or-corrupted%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            "Incorrect syntax near the keyword 'ON'. (on update cascade, on delete cascade,)

            Alcedinidae

            Origin of the phrase “under your belt”?