{"action":"created","comment":{"url":"https://api.github.com/repos/derekparker/delve/pulls/comments/22400979","id":22400979,"diff_hunk":"@@ -490,27 +498,71 @@ func (thread *ThreadContext) extractVariableFromEntry(entry *dwarf.Entry) (*Vari\n \treturn &Variable{Name: n, Type: t.String(), Value: val}, nil\n }\n \n-// Extracts the value from the instructions given in the DW_AT_location entry.\n-// We execute the stack program described in the DW_OP_* instruction stream, and\n-// then grab the value from the other processes memory.\n-func (thread *ThreadContext) extractValue(instructions []byte, addr int64, typ interface{}) (string, error) {\n-\taddress := addr\n+// Execute the stack program taking into account the current stack frame\n+func (thread *ThreadContext) executeStackProgram(instructions []byte) (int64, error) {\n+\tregs, err := thread.Registers()\n+\tif err != nil {\n+\t\treturn 0, err\n+\t}\n \n-\tif address == 0 {\n-\t\tregs, err := thread.Registers()\n+\tfde, err := thread.Process.FrameEntries.FDEForPC(regs.PC())\n+\tif err != nil {\n+\t\treturn 0, err\n+\t}\n+\n+\tfctx := fde.EstablishFrame(regs.PC())\n+\tcfaOffset := fctx.CFAOffset() + int64(regs.SP())\n+\n+\taddress, err := op.ExecuteStackProgram(cfaOffset, instructions)\n+\tif err != nil {\n+\t\treturn 0, err\n+\t}\n+\treturn address, nil\n+}\n+\n+// Extracts the address of a variable, dereferencing any pointers\n+func (thread *ThreadContext) extractVariableDataAddress(entry *dwarf.Entry, reader *reader.Reader) (int64, error) {\n+\tinstructions, err := instructionsForEntry(entry)\n+\tif err != nil {\n+\t\treturn 0, err\n+\t}\n+\n+\taddress, err := thread.executeStackProgram(instructions)\n+\tif err != nil {\n+\t\treturn 0, err\n+\t}\n+\n+\t// dereference pointers to get down the concrete type\n+\tfor typeEntry, err := reader.SeekToType(entry, true, false); typeEntry != nil; typeEntry, err = reader.SeekToType(typeEntry, true, false) {\n \t\tif err != nil {\n-\t\t\treturn \"\", err\n+\t\t\treturn 0, err\n \t\t}\n \n-\t\tfde, err := thread.Process.FrameEntries.FDEForPC(regs.PC())\n+\t\tif typeEntry.Tag != dwarf.TagPointerType {\n+\t\t\tbreak\n+\t\t}\n+\n+\t\tptraddress := uintptr(address)\n+\n+\t\tptr, err := thread.readMemory(ptraddress, ptrsize)\n \t\tif err != nil {\n-\t\t\treturn \"\", err\n+\t\t\treturn 0, err\n \t\t}\n+\t\taddress = int64(binary.LittleEndian.Uint64(ptr))\n+\t}\n+\n+\treturn address, nil\n+}\n \n-\t\tfctx := fde.EstablishFrame(regs.PC())\n-\t\tcfaOffset := fctx.CFAOffset() + int64(regs.SP())\n+// Extracts the value from the instructions given in the DW_AT_location entry.\n+// We execute the stack program described in the DW_OP_* instruction stream, and\n+// then grab the value from the other processes memory.\n+func (thread *ThreadContext) extractValue(instructions []byte, addr int64, typ interface{}) (string, error) {\n+\tvar err error\n+\taddress := addr","path":"proctl/variables.go","position":130,"original_position":130,"commit_id":"03ba69d082f31c6b73c6841c78429b2baf59433d","original_commit_id":"03ba69d082f31c6b73c6841c78429b2baf59433d","user":{"login":"derekparker","id":1314079,"avatar_url":"https://avatars.githubusercontent.com/u/1314079?v=3","gravatar_id":"","url":"https://api.github.com/users/derekparker","html_url":"https://github.com/derekparker","followers_url":"https://api.github.com/users/derekparker/followers","following_url":"https://api.github.com/users/derekparker/following{/other_user}","gists_url":"https://api.github.com/users/derekparker/gists{/gist_id}","starred_url":"https://api.github.com/users/derekparker/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/derekparker/subscriptions","organizations_url":"https://api.github.com/users/derekparker/orgs","repos_url":"https://api.github.com/users/derekparker/repos","events_url":"https://api.github.com/users/derekparker/events{/privacy}","received_events_url":"https://api.github.com/users/derekparker/received_events","type":"User","site_admin":false},"body":"Might as well just use `addr` here. It isn't used after being assigned to the local, so we shouldn't have to preserve it.","created_at":"2015-01-01T18:21:57Z","updated_at":"2015-01-01T18:21:57Z","html_url":"https://github.com/derekparker/delve/pull/39#discussion_r22400979","pull_request_url":"https://api.github.com/repos/derekparker/delve/pulls/39","_links":{"self":{"href":"https://api.github.com/repos/derekparker/delve/pulls/comments/22400979"},"html":{"href":"https://github.com/derekparker/delve/pull/39#discussion_r22400979"},"pull_request":{"href":"https://api.github.com/repos/derekparker/delve/pulls/39"}}},"pull_request":{"url":"https://api.github.com/repos/derekparker/delve/pulls/39","id":26741818,"html_url":"https://github.com/derekparker/delve/pull/39","diff_url":"https://github.com/derekparker/delve/pull/39.diff","patch_url":"https://github.com/derekparker/delve/pull/39.patch","issue_url":"https://api.github.com/repos/derekparker/delve/issues/39","number":39,"state":"open","locked":false,"title":"Better handling of struct pointers","user":{"login":"epipho","id":622665,"avatar_url":"https://avatars.githubusercontent.com/u/622665?v=3","gravatar_id":"","url":"https://api.github.com/users/epipho","html_url":"https://github.com/epipho","followers_url":"https://api.github.com/users/epipho/followers","following_url":"https://api.github.com/users/epipho/following{/other_user}","gists_url":"https://api.github.com/users/epipho/gists{/gist_id}","starred_url":"https://api.github.com/users/epipho/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/epipho/subscriptions","organizations_url":"https://api.github.com/users/epipho/orgs","repos_url":"https://api.github.com/users/epipho/repos","events_url":"https://api.github.com/users/epipho/events{/privacy}","received_events_url":"https://api.github.com/users/epipho/received_events","type":"User","site_admin":false},"body":"- `print structptr.member` now works\r\n- attempting to print a pointer variable that is nil will no longer panic\r\n- attempting to print a member variable of a nil struct will no longer panic\r\n- added a bunch more tests for error conditions","created_at":"2015-01-01T09:46:31Z","updated_at":"2015-01-01T18:21:57Z","closed_at":null,"merged_at":null,"merge_commit_sha":"d6cd1a7336a77af355ada82b95cb60fb584d533a","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/derekparker/delve/pulls/39/commits","review_comments_url":"https://api.github.com/repos/derekparker/delve/pulls/39/comments","review_comment_url":"https://api.github.com/repos/derekparker/delve/pulls/comments/{number}","comments_url":"https://api.github.com/repos/derekparker/delve/issues/39/comments","statuses_url":"https://api.github.com/repos/derekparker/delve/statuses/03ba69d082f31c6b73c6841c78429b2baf59433d","head":{"label":"epipho:struct-ptr","ref":"struct-ptr","sha":"03ba69d082f31c6b73c6841c78429b2baf59433d","user":{"login":"epipho","id":622665,"avatar_url":"https://avatars.githubusercontent.com/u/622665?v=3","gravatar_id":"","url":"https://api.github.com/users/epipho","html_url":"https://github.com/epipho","followers_url":"https://api.github.com/users/epipho/followers","following_url":"https://api.github.com/users/epipho/following{/other_user}","gists_url":"https://api.github.com/users/epipho/gists{/gist_id}","starred_url":"https://api.github.com/users/epipho/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/epipho/subscriptions","organizations_url":"https://api.github.com/users/epipho/orgs","repos_url":"https://api.github.com/users/epipho/repos","events_url":"https://api.github.com/users/epipho/events{/privacy}","received_events_url":"https://api.github.com/users/epipho/received_events","type":"User","site_admin":false},"repo":{"id":28658931,"name":"delve","full_name":"epipho/delve","owner":{"login":"epipho","id":622665,"avatar_url":"https://avatars.githubusercontent.com/u/622665?v=3","gravatar_id":"","url":"https://api.github.com/users/epipho","html_url":"https://github.com/epipho","followers_url":"https://api.github.com/users/epipho/followers","following_url":"https://api.github.com/users/epipho/following{/other_user}","gists_url":"https://api.github.com/users/epipho/gists{/gist_id}","starred_url":"https://api.github.com/users/epipho/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/epipho/subscriptions","organizations_url":"https://api.github.com/users/epipho/orgs","repos_url":"https://api.github.com/users/epipho/repos","events_url":"https://api.github.com/users/epipho/events{/privacy}","received_events_url":"https://api.github.com/users/epipho/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/epipho/delve","description":"Go debugger","fork":true,"url":"https://api.github.com/repos/epipho/delve","forks_url":"https://api.github.com/repos/epipho/delve/forks","keys_url":"https://api.github.com/repos/epipho/delve/keys{/key_id}","collaborators_url":"https://api.github.com/repos/epipho/delve/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/epipho/delve/teams","hooks_url":"https://api.github.com/repos/epipho/delve/hooks","issue_events_url":"https://api.github.com/repos/epipho/delve/issues/events{/number}","events_url":"https://api.github.com/repos/epipho/delve/events","assignees_url":"https://api.github.com/repos/epipho/delve/assignees{/user}","branches_url":"https://api.github.com/repos/epipho/delve/branches{/branch}","tags_url":"https://api.github.com/repos/epipho/delve/tags","blobs_url":"https://api.github.com/repos/epipho/delve/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/epipho/delve/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/epipho/delve/git/refs{/sha}","trees_url":"https://api.github.com/repos/epipho/delve/git/trees{/sha}","statuses_url":"https://api.github.com/repos/epipho/delve/statuses/{sha}","languages_url":"https://api.github.com/repos/epipho/delve/languages","stargazers_url":"https://api.github.com/repos/epipho/delve/stargazers","contributors_url":"https://api.github.com/repos/epipho/delve/contributors","subscribers_url":"https://api.github.com/repos/epipho/delve/subscribers","subscription_url":"https://api.github.com/repos/epipho/delve/subscription","commits_url":"https://api.github.com/repos/epipho/delve/commits{/sha}","git_commits_url":"https://api.github.com/repos/epipho/delve/git/commits{/sha}","comments_url":"https://api.github.com/repos/epipho/delve/comments{/number}","issue_comment_url":"https://api.github.com/repos/epipho/delve/issues/comments/{number}","contents_url":"https://api.github.com/repos/epipho/delve/contents/{+path}","compare_url":"https://api.github.com/repos/epipho/delve/compare/{base}...{head}","merges_url":"https://api.github.com/repos/epipho/delve/merges","archive_url":"https://api.github.com/repos/epipho/delve/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/epipho/delve/downloads","issues_url":"https://api.github.com/repos/epipho/delve/issues{/number}","pulls_url":"https://api.github.com/repos/epipho/delve/pulls{/number}","milestones_url":"https://api.github.com/repos/epipho/delve/milestones{/number}","notifications_url":"https://api.github.com/repos/epipho/delve/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/epipho/delve/labels{/name}","releases_url":"https://api.github.com/repos/epipho/delve/releases{/id}","created_at":"2014-12-31T06:59:21Z","updated_at":"2015-01-01T08:16:20Z","pushed_at":"2015-01-01T13:23:58Z","git_url":"git://github.com/epipho/delve.git","ssh_url":"git@github.com:epipho/delve.git","clone_url":"https://github.com/epipho/delve.git","svn_url":"https://github.com/epipho/delve","homepage":null,"size":9835,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"derekparker:master","ref":"master","sha":"1289f38f8733c344e275ae116b6492922d7f955f","user":{"login":"derekparker","id":1314079,"avatar_url":"https://avatars.githubusercontent.com/u/1314079?v=3","gravatar_id":"","url":"https://api.github.com/users/derekparker","html_url":"https://github.com/derekparker","followers_url":"https://api.github.com/users/derekparker/followers","following_url":"https://api.github.com/users/derekparker/following{/other_user}","gists_url":"https://api.github.com/users/derekparker/gists{/gist_id}","starred_url":"https://api.github.com/users/derekparker/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/derekparker/subscriptions","organizations_url":"https://api.github.com/users/derekparker/orgs","repos_url":"https://api.github.com/users/derekparker/repos","events_url":"https://api.github.com/users/derekparker/events{/privacy}","received_events_url":"https://api.github.com/users/derekparker/received_events","type":"User","site_admin":false},"repo":{"id":19994257,"name":"delve","full_name":"derekparker/delve","owner":{"login":"derekparker","id":1314079,"avatar_url":"https://avatars.githubusercontent.com/u/1314079?v=3","gravatar_id":"","url":"https://api.github.com/users/derekparker","html_url":"https://github.com/derekparker","followers_url":"https://api.github.com/users/derekparker/followers","following_url":"https://api.github.com/users/derekparker/following{/other_user}","gists_url":"https://api.github.com/users/derekparker/gists{/gist_id}","starred_url":"https://api.github.com/users/derekparker/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/derekparker/subscriptions","organizations_url":"https://api.github.com/users/derekparker/orgs","repos_url":"https://api.github.com/users/derekparker/repos","events_url":"https://api.github.com/users/derekparker/events{/privacy}","received_events_url":"https://api.github.com/users/derekparker/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/derekparker/delve","description":"Go debugger","fork":false,"url":"https://api.github.com/repos/derekparker/delve","forks_url":"https://api.github.com/repos/derekparker/delve/forks","keys_url":"https://api.github.com/repos/derekparker/delve/keys{/key_id}","collaborators_url":"https://api.github.com/repos/derekparker/delve/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/derekparker/delve/teams","hooks_url":"https://api.github.com/repos/derekparker/delve/hooks","issue_events_url":"https://api.github.com/repos/derekparker/delve/issues/events{/number}","events_url":"https://api.github.com/repos/derekparker/delve/events","assignees_url":"https://api.github.com/repos/derekparker/delve/assignees{/user}","branches_url":"https://api.github.com/repos/derekparker/delve/branches{/branch}","tags_url":"https://api.github.com/repos/derekparker/delve/tags","blobs_url":"https://api.github.com/repos/derekparker/delve/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/derekparker/delve/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/derekparker/delve/git/refs{/sha}","trees_url":"https://api.github.com/repos/derekparker/delve/git/trees{/sha}","statuses_url":"https://api.github.com/repos/derekparker/delve/statuses/{sha}","languages_url":"https://api.github.com/repos/derekparker/delve/languages","stargazers_url":"https://api.github.com/repos/derekparker/delve/stargazers","contributors_url":"https://api.github.com/repos/derekparker/delve/contributors","subscribers_url":"https://api.github.com/repos/derekparker/delve/subscribers","subscription_url":"https://api.github.com/repos/derekparker/delve/subscription","commits_url":"https://api.github.com/repos/derekparker/delve/commits{/sha}","git_commits_url":"https://api.github.com/repos/derekparker/delve/git/commits{/sha}","comments_url":"https://api.github.com/repos/derekparker/delve/comments{/number}","issue_comment_url":"https://api.github.com/repos/derekparker/delve/issues/comments/{number}","contents_url":"https://api.github.com/repos/derekparker/delve/contents/{+path}","compare_url":"https://api.github.com/repos/derekparker/delve/compare/{base}...{head}","merges_url":"https://api.github.com/repos/derekparker/delve/merges","archive_url":"https://api.github.com/repos/derekparker/delve/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/derekparker/delve/downloads","issues_url":"https://api.github.com/repos/derekparker/delve/issues{/number}","pulls_url":"https://api.github.com/repos/derekparker/delve/pulls{/number}","milestones_url":"https://api.github.com/repos/derekparker/delve/milestones{/number}","notifications_url":"https://api.github.com/repos/derekparker/delve/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/derekparker/delve/labels{/name}","releases_url":"https://api.github.com/repos/derekparker/delve/releases{/id}","created_at":"2014-05-20T19:24:43Z","updated_at":"2015-01-01T04:19:27Z","pushed_at":"2014-12-31T21:55:17Z","git_url":"git://github.com/derekparker/delve.git","ssh_url":"git@github.com:derekparker/delve.git","clone_url":"https://github.com/derekparker/delve.git","svn_url":"https://github.com/derekparker/delve","homepage":null,"size":9835,"stargazers_count":1318,"watchers_count":1318,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":55,"mirror_url":null,"open_issues_count":9,"forks":55,"open_issues":9,"watchers":1318,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/derekparker/delve/pulls/39"},"html":{"href":"https://github.com/derekparker/delve/pull/39"},"issue":{"href":"https://api.github.com/repos/derekparker/delve/issues/39"},"comments":{"href":"https://api.github.com/repos/derekparker/delve/issues/39/comments"},"review_comments":{"href":"https://api.github.com/repos/derekparker/delve/pulls/39/comments"},"review_comment":{"href":"https://api.github.com/repos/derekparker/delve/pulls/comments/{number}"},"commits":{"href":"https://api.github.com/repos/derekparker/delve/pulls/39/commits"},"statuses":{"href":"https://api.github.com/repos/derekparker/delve/statuses/03ba69d082f31c6b73c6841c78429b2baf59433d"}}}}