Unable to get local variables in vscode while debugging golang executable - go

I create a sample project in Golang:
sampleapp/
sampleapp/main.go
which has the following code:
package main
import (
"flag"
"fmt"
)
func main() {
var name = flag.String("name", "user1", "user name")
var age = flag.Int("age", 20, "user age")
fmt.Println(*name)
fmt.Println(*age)
}
I followed https://code.visualstudio.com/docs/editor/debugging and created the following launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch file",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/main.go",
"env": {},
"args": []
},
{
"name": "Launch exec",
"type": "go",
"request": "launch",
"mode": "exec",
"program": "${workspaceFolder}/sampleapp",
"env": {},
"args": []
}
]
}
When I use Launch File debug mode setting breakpoints on main - I am able to single step through the program and can see the values of username and age as follows:
But when I use Launch exec debug mode after building the app like so:
go build
I can single step through the code but the Local section hangs with a spinner going on continuously and doesn't show any local variables as per the following:
I have to do a Reload window to get rid of the hanging Local vars spinner. I checked vscode issues and saw https://github.com/microsoft/vscode-go/issues/2444 but in that case the variables are not shown when there is a panic. But in my case, I am just printing 2 variables.
I thought it might be an issue with my dlv installation but when I debugged using dlv with the executable, I was able to get the values (deleting unnecessary lines from dlv output):
dlv exec sampleapp
Type 'help' for list of commands.
(dlv) break main.main
Breakpoint 1 set at 0x109e1f3 for main.main() ./main.go:8
(dlv) s
> main.main() ./main.go:8 (hits goroutine(1):1 total:1) (PC: 0x109e1f3)
Warning: debugging optimized function
3: import (
4: "flag"
5: "fmt"
6: )
7:
=> 8: func main() {
9: var name = flag.String("name", "user1", "user name")
10: var age = flag.Int("age", 20, "user age")
11: fmt.Println(*name)
12: fmt.Println(*age)
13: }
(dlv) s
> main.main() ./main.go:9 (PC: 0x109e202)
Warning: debugging optimized function
4: "flag"
5: "fmt"
6: )
7:
8: func main() {
=> 9: var name = flag.String("name", "user1", "user name")
10: var age = flag.Int("age", 20, "user age")
11: fmt.Println(*name)
12: fmt.Println(*age)
13: }
(dlv) s
> main.main() ./main.go:11 (PC: 0x109e29f)
Warning: debugging optimized function
6: )
7:
8: func main() {
9: var name = flag.String("name", "user1", "user name")
10: var age = flag.Int("age", 20, "user age")
=> 11: fmt.Println(*name)
12: fmt.Println(*age)
13: }
(dlv) stepout
user1
> main.main() ./main.go:12 (PC: 0x109e31a)
Warning: debugging optimized function
7:
8: func main() {
9: var name = flag.String("name", "user1", "user name")
10: var age = flag.Int("age", 20, "user age")
11: fmt.Println(*name)
=> 12: fmt.Println(*age)
13: }
(dlv) p name
*"user1"
(dlv) p age
*20
Is there something very basic that I am missing here?

I could reproduce your issue initially but after I upgrade to VSCode Version 1.35.1 (I am on MacOSX), the issue is gone. I can see the variable values during debug with "Launch exec"
I think the compiler optimisation made it problematic. Should works fine for executable built with
go build -gcflags=all="-N -l"
-N: disable optimization
-l: disable inlining
Golang officially suggested it as well: https://golang.org/doc/gdb

Related

Concatenate declared variable with random string

It is possible, using Terratest, to declare a tfvars file with the following variable:
bar = {
name = "test"
domain = "test.com"
regions = [
{ location = "France Central", alias = "france" }
]
}
But include a random prefix to the bar.domain string inside the go code?
I'm using terraformOptions as follows:
terraformOptions := &terraform.Options{
TerraformDir: sourcePath,
VarFiles: []string{variablesPath + "/integration.tfvars"},
}
It is not ideal for one to make use of the tfvars file directly to take the input in case of tests. More on this here
To answer your question :
You can use something similar to this :
options := terraform.Options{
TerraformDir: "sourcePath",
Vars: map[string]interface{}{
"name": "test",
"domain": addRandomprefix()+"test.com",
"region ": map[string]interface{}{
"location" : "France Central",
"alias" : "france",
},
},
}
Just create your own custom addRandomprefix() method. I hope this helps :)

IOS SWIFT PARSE : Pfcloud.callFunction

i have an old app in objective C using cloudcode to send pushes to back4app platform.
The app manage to send correctly the pushes and this is the code :
- (IBAction)inviaPush:(UIButton *)sender {
NSString *canale;
for (int i=0; i<=4; i++) {
switch (i) {
case 0:canale=#"TraduzioniEDI";
break;
case 1:canale=#"NavFtpYM";
break;
case 2:canale=#"InvioMailFTP";
break;
case 3:canale=#"VermasMto";
break;
case 4:canale=#"EdiAltova";
break;
default:
break;
}
NSString *testoPush =[NSString stringWithFormat:#"%# Test Invio %#", canale,[NSDate date]];
[PFCloud callFunctionInBackground:#"push"
withParameters:#{#"channels": #[canale], #"data": #{#"alert": testoPush,#"badge":#"Increment"}}
block:^( NSString *result, NSError *error) {
if (!error) {
NSLog(#"Risultato: %#",result);
} else{
NSLog(#"Errore %#",error);
}
}];
}
}
Running the code i receive the 5 pushes and in the info of back4app dashboard i find :
2020-03-02T01:14:53.533Z - Ran cloud function push for user undefined with:
Input: {"channels":["VermasMto"],"data":{"alert":"VermasMto Test Invio 2020-03-02 01:14:52 +0000"}}
Result: "Sent!!"
i tried to convert the program in swift
the code to send push is :
func inviaPush (){
var canale :String = ""
for i in 0...4
{
switch i {
case 0: canale = "TraduzioniEDI"
case 1: canale = "NavFtpYM"
case 2: canale = "InvioMailFTP"
case 3: canale = "VermasMto"
case 4: canale = "EdiAltova"
default: canale=""
}
let testoPush = "\(canale) Test invio - Swift"
PFCloud.callFunction(inBackground: "push", withParameters: ["channels": canale, "data": ["alert": testoPush,"badge":"Increment"]], block: {
(result: Any?, error: Error?) -> Void in
if error != nil {
if let descrip = error?.localizedDescription{
print(descrip)
}
}else{
print(result as! String)
}
})
}
}
in this case i receive no pushes, and in the info i find following :
2020-03-02T01:17:25.505Z - Ran cloud function push for user undefined with:
Input: {"channels":"NavFtpYM","data":{"alert":"NavFtpYM Test invio"}}
Result: "Sent!!"
2020-03-02T01:17:25.504Z - Can't count installations for PushStatus hm5hbCzDvd: bad $in value
Comparing the info shown in the dashboard i see a difference in input
in ojective C (Working) the in input the channel have a square bracket :
Input: {"channels":["VermasMto"],
while when sent from swift they have not
Input: {"channels":"NavFtpYM",
surely i'm calling the method PFCloud.callFunction in a wrong way.
Any suggestion ?
Fabrizio
the solution was simple ...
need to change
PFCloud.callFunction(inBackground: "push", withParameters: ["channels": canale, "data": ["alert": testoPush,"badge":"Increment"]], block: {
in
PFCloud.callFunction(inBackground: "push", withParameters: ["channels": [canale], "data": ["alert": testoPush,"badge":"Increment"]], block: {
Fabrizio

Showing after hiding window removes all content

I am using following code which produces a main window with a button to open other window. I want to be able to repeatedly hide and show other window. Closing main window should exit the program:
package main
import ("github.com/andlabs/ui")
func main() {
ui.Main(makeAllWins)
}
var mainWindow *ui.Window
var otherWindow *ui.Window
func makeAllWins(){
makeMainWin()
makeOtherWin()
mainWindow.Show()
}
func makeMainWin(){
var otherButton = ui.NewButton("Other module")
otherButton.OnClicked( func (*ui.Button) { otherWindow.Show() })
var box = ui.NewVerticalBox()
box.Append(ui.NewLabel("Select module"), false)
box.Append(otherButton, false)
mainWindow = ui.NewWindow("Hello", 200, 100, false)
mainWindow.SetChild(box)
mainWindow.OnClosing( func (*ui.Window) bool { ui.Quit(); return true } )
}
func makeOtherWin(){
var box = ui.NewVerticalBox()
box.Append(ui.NewLabel("label1"), false)
box.Append(ui.NewLabel("label2"), false)
box.Append(ui.NewLabel("label3"), false)
otherWindow = ui.NewWindow("Other", 200, 100, false)
otherWindow.SetChild(box)
otherWindow.OnClosing( func (*ui.Window) bool { otherWindow.Hide(); return true } ) // I THINK PROBLEM IS IN THIS LINE
}
However, when I show the other window after hiding it once, all the labels are gone. On repeating, the program crashes with following error:
fatal error: unexpected signal during runtime execution
[signal SIGSEGV: segmentation violation code=0x1 addr=0x67fb0a pc=0x67fb0a]
Where is the problem and how can it be solved. Thanks for your help.
Here:
otherWindow.OnClosing( func (*ui.Window) bool { otherWindow.Hide(); return true } )
you should be returning false instead of true. As it is, the window is getting destroyed when you close it, leading to the segmentation fault when you try to reference it later.
Per the documentation comments:
OnClosing registers f to be run when the user clicks the Window's
close button. Only one function can be registered at a time. If f
returns true, the window is destroyed with the Destroy method. If f
returns false, or if OnClosing is never called, the window is not
destroyed and is kept visible.

Reading a registry key results in "The file type being saved or retrieved has been blocked" error

I'm trying to read a registry key value and it fails even when I run app as an Administrator:
extern crate winreg;
use winreg::enums::{HKEY_LOCAL_MACHINE, KEY_READ};
fn main() {
let hklm = winreg::RegKey::predef(HKEY_LOCAL_MACHINE);
let subkey = hklm
.open_subkey_with_flags(
r#"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"#,
KEY_READ,
)
.expect("Failed to open subkey");
let u_uac_status: String = subkey.get_value("EnableLUA").expect("Failed to read");
let mut r_uac_status: String = String::new();
if u_uac_status == "1" {
r_uac_status = String::from("Enable");
} else {
r_uac_status = String::from("Disable");
}
println!("UAC status: {}", r_uac_status);
}
The error I get:
thread 'main' panicked at 'Failed to read: Os { code: 222, kind: Other, message: "The file type being saved or retrieved has been blocked." }', libcore\result.rs:1009:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.
error: process didn't exit successfully (exit code: 101)
You're trying to read a String, but the registry contains an integer value. Try with:
let r_uac_status = subkey.get_value::<u32, _>("EnableLUA")
.map (|u_uac_status|
if u_uac_status == 1 { "Enable" } else { "Disable" })
.expect("Failed to read");
Note: you don't even need administrator rights to read the value.

How do you quickly find the URL for a Win32 API on MSDN?

How do you quickly find the URL for a Win32 API on MSDN? It's easy for .NET methods -- just add the method name (for example, System.Byte.ToString) to http://msdn.microsoft.com/library/.
However, for Win32 APIs (say GetLongPathName), this doesn't work: http://msdn.microsoft.com/en-us/library/GetLongPathName.
I want to be able to use the URL in code comments or documentation. So the URL one gets with an MSDN or Google search (for example, http://msdn.microsoft.com/library/aa364980.aspx) isn't really what I'm looking for. I'd really like my code comments to look something like:
// blah blah blah. See http://msdn.microsoft.com/en-us/library/GetLongPathName for more information.
What's the magic pixie dust for Win32 APIs? Or does it only work for .NET methods?
Google might be your best bet. I know the msdn site search has time and again pointed me in the wrong direction, but a quick switch to Google ("GetLongPathName site:msdn.microsoft.com") never steers me wrong.
FWIW if you have the MSDN installed locally on your machine the Zeus editor has a feature to search the local copy of the MSDN.
For example, placing the cursor on the GetLongPathName word within a text document and using the Zeus Help, Quick Help, Current Word menu, the following MSDN page gets loaded:
ms-help://MS.VSCC.v80/MS.MSDN.vAug06.en/fileio/fs/getlongpathname.htm
I am using Linkify by cough me, which lets you link
// see msdn:GetLongPathName
to the google search japollock mentions.
You could use MSDN search.
http://social.msdn.microsoft.com/Search/en-US/?Refinement=86&Query=GetLongPathName
Refinement=86 stands for Win32 search.
MSDN GET api (I don't know how new this is)
"https://learn.microsoft.com/api/search?locale=en-us&scoringprofile=semantic-captions&%24top=1&search=" functionName
returns json like such:
{
"results": [
{
"title": "KeClearEvent function (wdm.h) - Windows drivers",
"url": "https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-keclearevent",
"displayUrl": {
"content": "/windows-hardware/drivers/ddi/wdm/nf-wdm-keclearevent",
"hitHighlights": [
{
"start": 41,
"length": 12
}
]
},
"description": "The KeClearEvent routine sets an event to a not-signaled state.",
"descriptions": [
{
"content": "KeClearEvent function (wdm.h) Article 04/18/2022 2 minutes to read In this article The KeClearEvent routine sets an event to a not-signaled state.",
"hitHighlights": [
{
"start": 0,
"length": 12
},
{
"start": 87,
"length": 12
}
]
},
{
"content": "For better performance, use KeClearEvent unless the caller uses the value returned by KeResetEvent to determine what to do next.",
"hitHighlights": [
{
"start": 28,
"length": 12
}
]
}
],
"lastUpdatedDate": "2022-04-18T04:31:00+00:00",
"breadcrumbs": []
}
],
"spellingCorrection": [],
"scopeRemoved": false,
"count": 18,
"nextLink": "https://learn.microsoft.com/api/Search?locale=en-us\u0026search=KeClearEvent\u0026$skip=1\u0026$top=1",
"srcheng": "02"
}
if you want really fast, you can bind it to a hotkey
AutohotkeyV2
#SingleInstance force
ListLines 0
KeyHistory 0
SendMode "Input" ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir A_ScriptDir ; Ensures a consistent starting directory.
linkFromName(functionName) {
json:=downloadToVar("https://learn.microsoft.com/api/search?locale=en-us&scoringprofile=semantic-captions&%24top=1&search=" functionName)
obj:=JSON_parse(json)
if (obj.results.Length) {
RegExMatch(obj.results[1].title, ".*?(?=\s|$)", &OutputVar)
if (OutputVar.0 = functionName) {
validUrl:=obj.results[1].url
} else if (OutputVar.0 = functionName "W" || OutputVar.0 = functionName "A") {
validUrl:=SubStr(obj.results[1].url, 1, -1) "w"
}
; A_Clipboard:=validUrl
Run validUrl
}
}
; linkFromName("GetLongPathNameW") ;works
; linkFromName("GetLongPathName") ;works
linkFromName(A_Clipboard)
Exitapp
f3::Exitapp
downloadToVar(url) {
whr := ComObject("WinHttp.WinHttpRequest.5.1")
whr.Open("GET", url, true)
whr.SetRequestHeader("User-Agent", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)")
whr.Send()
; Using 'true' above and the call below allows the script to remain responsive.
whr.WaitForResponse()
return whr.ResponseText
}
JSON_parse(str) {
c_:=1
return JSON_value()
JSON_value() {
char_:=SubStr(str, c_, 1)
Switch char_ {
case "{":
obj_:=Map()
;object
c_++
loop {
skip_s()
if (SubStr(str, c_, 1) == "}") {
c_++
return obj_
}
; key_:=JSON_objKey()
; a or "a"
if (SubStr(str, c_, 1) == "`"") {
RegExMatch(str, "(?:\\.|.)*?(?=`")", &OutputVar, c_ + 1)
key_:=RegExReplace(OutputVar.0, "\\(.)", "$1")
c_+=OutputVar.Len
} else {
RegExMatch(str, ".*?(?=[\s:])", &OutputVar, c_)
key_:=OutputVar.0
c_+=OutputVar.Len
}
c_:=InStr(str, ":", true, c_) + 1
skip_s()
value_:=JSON_value()
obj_[key_]:=value_
obj_.DefineProp(key_, {Value: value_})
skip_s()
if (SubStr(str, c_, 1) == ",") {
c_++, skip_s()
}
}
case "[":
arr_:=[]
;array
c_++
loop {
skip_s()
if (SubStr(str, c_, 1) == "]") {
c_++
return arr_
}
value_:=JSON_value()
arr_.Push(value_)
skip_s()
char_:=SubStr(str, c_, 1)
if (char_ == ",") {
c_++, skip_s()
}
}
case "`"":
RegExMatch(str, "(?:\\.|.)*?(?=`")", &OutputVar, c_ + 1)
unquoted:=RegExReplace(OutputVar.0, "\\(.)", "$1")
c_+=OutputVar.Len + 2
return unquoted
case "0", "1", "2", "3", "4", "5", "6", "7", "8", "9":
RegExMatch(str, "[0-9.]*", &OutputVar, c_)
c_+=OutputVar.Len
return Number(OutputVar.0)
case "t":
;"true"
c_+=4
return {a:1}
case "f":
;"false"
c_+=5
return {a:0}
case "n":
;"null"
c_+=4
return {a:-1}
}
}
skip_s() {
RegExMatch(str, "\s*", &OutputVar, c_)
c_+=OutputVar.Len
}
}

Resources