Detecting When a Struct or Hashtable Get Modified or Corrupted
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
add a comment |
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
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
add a comment |
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
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
runtime-error runtime common-lisp hashtable
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
add a comment |
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
add a comment |
1 Answer
1
active
oldest
votes
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!
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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!
add a comment |
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!
add a comment |
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!
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!
answered Nov 22 '18 at 22:52
zutzut
55624
55624
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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