Observations when evaluating VisualGDB for our environment

Sysprogs forums Forums VisualGDB Observations when evaluating VisualGDB for our environment

Viewing 8 posts - 1 through 8 (of 8 total)
  • Author
    Posts
  • #36439
    oold_le
    Participant

    Hello,

    I’ve been evaluating VisualGDB for use in our company. There have been a few issues that cropped up right away, so I’d like to collect them in this topic.

    Additional context: This is a CMakePresets.json-based CMake project.

    1. Clang IntelliSense can’t find headers when no toolchain is configured for the project.
    2. Our Gdbserver rejects the port argument when it is given as :2000. It wants something like 123.123.123.123:2000.
    3. Deployed files cannot be checked for whether they are up-to-date with stat. Our target system doesn’t have that command.
    4. Building only a specific target fails. The command line looks like cmake.exe --build --target HelloWorld build/debug-linux-arm-gnu. I believe the folder should be after the --build.
    5. Upload fails. On the first try, the file simply doesn’t exist where it was supposedly uploaded to. On subsequent tries, I receive access violation errors from VisualGDB or Visual Studio crashes, which isn’t surprising given the access violation error.

    To 1.:

    We already define our toolchain via a toolchain file that is also pulled in via the presets file. We really do not want to make our developers configure the toolchains globally as they are checked into VCS and each project might pull in different versions of toolchains. It must be possible to retrieve this information another way to make IntelliSense work.

    To 3. and 5.:

    Log from first try:

    SSH [2] [@8.8] opening channel for "export"
    SSH [2] closed after 156 msec
    SSH [3] [@9.1] opening channel for "setenv"
    SSH [3] closed after 165 msec
    Deploying 1 items...
    Deploying output of ...
    SSH [4] [@9.3] opening channel 
    SSH [4] closed after 145 msec
    Checking if C:/cmakehw/build/debug-linux-arm-gnu/src/main/HelloWorld needs deployment /tmp/HelloWorld on 10.0.0.11...
    Querying stat for C:/cmakehw/build/debug-linux-arm-gnu/src/main/HelloWorld
    SSH [5] [@9.5] opening channel for ""stat" "/tmp/HelloWorld" -L -c "com.sysprogs.statline %s %Y""
    SSH [5] closed after 211 msec
    failed to run FS operation: ------------------ mi3+m ------------------ 
    mi3+m: 'stat "/tmp/HelloWorld" -L -c "com.sysprogs.statline %s %Y"' exited with code 1 
    at mi3.w1.a_6_2(Nullable1 a) 
    at mi3.w`1.a_2_2_2_2() 
    at zf.c[_Ty](ky3`1 a) 
    trace=[mi3+w1.a_6_2:46, mi3+w1.a_2_2_2_2:122, zf.c:0]
    
    Starting deployment of C:/cmakehw/build/debug-linux-arm-gnu/src/main/HelloWorld...
    SSH [6] [@9.7] opening channel for ""mkdir" -p "/tmp""
    SSH [6] closed after 431 msec
    Uploading 1 file(s) with SCP...
    SSH [7] [@10.1] opening channel for "mkdir -p "/tmp""
    SSH [7] closed after 244 msec
    Uploading '/tmp/HelloWorld' (size=14896, time=2/18/2025 5:24:57 PM, mode=) via scp
    SSH [8] [@10.6] opening channel for ""touch" -d @1739890665 "/tmp/HelloWorld""
    SSH [8] closed after 167 msec
    failed to run FS operation: ------------------ mi3+m ------------------ 
    mi3+m: 'touch -d @1739890665 "/tmp/HelloWorld"' exited with code 127 
    at mi3.w1.a_6_2(Nullable1 a) 
    at mi3.w`1.a_2_2_2_2() 
    at zf.e(ky3`1 a) 
    trace=[mi3+w1.a_6_2:46, mi3+w1.a_2_2_2_2:122, zf.e:0]
    
    Deployment complete
    SSH [9] [@10.8] opening channel for ""chmod" +x "/tmp/HelloWorld""
    SSH [9] closed after 212 msec
    Deployed all items.
    SSH [10] [@11.0] opening channel for ""which" "gdbserver""
    SSH [10] closed after 158 msec
    SSH [11] [@11.2] opening channel for ""which" which"
    SSH [11] closed after 158 msec
    SSH [12] [@11.3] opening channel in 'xterm' mode for "cd "/tmp" && "gdbserver" 10.0.0.11:2000 "/tmp/HelloWorld""
    Waiting for gdb server to start (up to 1000 msec)...
    SSH [12] closed after 391 msec
    GDBServer started in 573 msec. IsRunning = False, TriggerMatched = False
    Determining the top-level window to show a WPF popup...
    GetActiveWindow() returned 270bcc. Will use it.
    Unexpected exception: ------------------ System.OperationCanceledException ------------------ 
    System.OperationCanceledException: The operation was canceled. 
    at bb.e() 
    at bb.k_2(DebugCustomizationSettings a, Boolean b) 
    at xq1.v2() 
    at n52.h_6() 
    at VisualGDB.GDBDebugEngine.o1(sv3 b, g a) 
    trace=[bb.e:1138, bb.k_2:224, xq1.v2:64, n52.h_6:28, VisualGDB.GDBDebugEngine.o1:58]

    Log from second try:

    SSH [13] [@14.4] opening channel 
    SSH [13] closed after 278 msec
    Deploying 1 items...
    Deploying output of ...
    SSH [14] [@14.7] opening channel 
    SSH [14] closed after 143 msec
    Checking if C:/cmakehw/build/debug-linux-arm-gnu/src/main/HelloWorld needs deployment /tmp/HelloWorld on 10.0.0.11...
    Querying stat for C:/cmakehw/build/debug-linux-arm-gnu/src/main/HelloWorld
    SSH [15] [@14.8] opening channel for ""stat" "/tmp/HelloWorld" -L -c "com.sysprogs.statline %s %Y""
    SSH [15] closed after 203 msec
    failed to run FS operation: ------------------ mi3+m ------------------ 
    mi3+m: 'stat "/tmp/HelloWorld" -L -c "com.sysprogs.statline %s %Y"' exited with code 1 
    at mi3.w1.a_6_2(Nullable1 a) 
    at mi3.w`1.a_2_2_2_2() 
    at zf.c[_Ty](ky3`1 a) 
    trace=[mi3+w1.a_6_2:46, mi3+w1.a_2_2_2_2:122, zf.c:0]
    
    Starting deployment of C:/cmakehw/build/debug-linux-arm-gnu/src/main/HelloWorld...
    SSH [16] [@15.0] opening channel for ""mkdir" -p "/tmp""
    SSH [16] closed after 201 msec
    Uploading 1 file(s) with SCP...
    SSH [17] [@15.2] opening channel for "mkdir -p "/tmp""
    SSH [17] closed after 194 msec
    Uploading '/tmp/HelloWorld' (size=14896, time=2/18/2025 5:36:48 PM, mode=) via scp
    failed to upload /tmp/HelloWorld: ------------------ System.AccessViolationException ------------------ 
    System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. 
    at dt2.r.libssh2_scp_send64(IntPtr e, String c, Int32 d, Int64 a, Int32 b, Int32 f) 
    at dt2.r.ManagedLibSSH2.ImportHelpers.ILibSSH2Library.libssh2_scp_send64(IntPtr a, String c, Int32 b, Int64 d, Int32 f, Int32 e) 
    at th1.r4.a() 
    at th1.o.c() 
    at th1.i2(LIBSSH2Action`1 b, Int32& a) 
    at th1.a4(LIBSSH2Action`1 a) 
    at th1.s(LIBSSH2Action`1 b, Int32& a) 
    at th1.l3(String a, Int64 c, DateTime d, Nullable`1 b) 
    at q03.b(String b, List`1 a, ot2 d, e e, f22 c, UploadRetryContext f) 
    trace=[dt2+r.libssh2_scp_send64:-1, dt2+r.ManagedLibSSH2.ImportHelpers.ILibSSH2Library.libssh2_scp_send64:0, th1+r4.a:0, th1+o.c:0, th1.i2:3, th1.a4:22, th1.s:5, th1.l3:267, q03.b:211]
    
    Deployment exception: ------------------ System.AccessViolationException ------------------ 
    System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. 
    at qt1.c(FileTransferAction e, ra1 c, fz2 d, fz2 a, ot2 b, SimpleProgressHandler f) 
    at bb.s1(f23 a, List`1 b) 
    trace=[qt1.c:752, bb.s1:979]
    
    SSH [18] [@15.5] opening channel for ""pidof" "HelloWorld""
    SSH [18] closed after 286 msec
    SSH [19] [@15.8] opening channel for ""pgrep" '(^|/)HelloWorld'"
    SSH [19] closed after 159 msec
    Unexpected exception: ------------------ j02 ------------------ 
    j02: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. ---> System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. 
    at qt1.c(FileTransferAction e, ra1 c, fz2 d, fz2 a, ot2 b, SimpleProgressHandler f) 
    at bb.s1(f23 a, List`1 b) 
    at bb.r.a(f23 a) 
    at ae3.f`1.g(f23 a) 
    at VisualGDB.Add_In.Tool_Windows.WPF.DockedProgressPresenter.RunItemizedOperation(Action`1 operation, String caption, s7 exceptionHandler, String[] stages) 
    at ae3.o1[_ResultType](gh2`1 a, String c, Int32 b, String[] d) 
    at bb.x1() 
    --- End of inner exception stack trace --- 
    at bb.x1() 
    at bb.k_2(DebugCustomizationSettings a, Boolean b) 
    at xq1.v2() 
    at n52.h_6() 
    at VisualGDB.GDBDebugEngine.o1(sv3 b, g a) 
    trace=[bb.x1:200, bb.k_2:53, xq1.v2:64, n52.h_6:28, VisualGDB.GDBDebugEngine.o1:58] 
    ------------------ Inner exception ------------------ 
    ------------------ System.AccessViolationException ------------------ 
    System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. 
    at qt1.c(FileTransferAction e, ra1 c, fz2 d, fz2 a, ot2 b, SimpleProgressHandler f) 
    at bb.s1(f23 a, List`1 b) 
    at bb.r.a(f23 a) 
    at ae3.f`1.g(f23 a) 
    at VisualGDB.Add_In.Tool_Windows.WPF.DockedProgressPresenter.RunItemizedOperation(Action`1 operation, String caption, s7 exceptionHandler, String[] stages) 
    at ae3.o1[_ResultType](gh2`1 a, String c, Int32 b, String[] d) 
    at bb.x1() 
    trace=[qt1.c:752, bb.s1:1618, bb+r.a:0, ae3+f`1.g:0, VisualGDB.Add_In.Tool_Windows.WPF.DockedProgressPresenter.RunItemizedOperation:234, ae3.o1:92, bb.x1:123]
    
    Determining the top-level window to show a WPF popup...
    GetActiveWindow() returned 8208a8. Will use it.
    Unexpected exception: ------------------ j02 ------------------ 
    j02: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. ---> System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. 
    at qt1.c(FileTransferAction e, ra1 c, fz2 d, fz2 a, ot2 b, SimpleProgressHandler f) 
    at bb.s1(f23 a, List`1 b) 
    at bb.r.a(f23 a) 
    at ae3.f`1.g(f23 a) 
    at VisualGDB.Add_In.Tool_Windows.WPF.DockedProgressPresenter.RunItemizedOperation(Action`1 operation, String caption, s7 exceptionHandler, String[] stages) 
    at ae3.o1[_ResultType](gh2`1 a, String c, Int32 b, String[] d) 
    at bb.x1() 
    --- End of inner exception stack trace --- 
    at bb.x1() 
    at bb.k_2(DebugCustomizationSettings a, Boolean b) 
    at xq1.v2() 
    at n52.h_6() 
    at VisualGDB.GDBDebugEngine.o1(sv3 b, g a) 
    trace=[bb.x1:200, bb.k_2:53, xq1.v2:64, n52.h_6:28, VisualGDB.GDBDebugEngine.o1:58] 
    ------------------ Inner exception ------------------ 
    ------------------ System.AccessViolationException ------------------ 
    System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. 
    at qt1.c(FileTransferAction e, ra1 c, fz2 d, fz2 a, ot2 b, SimpleProgressHandler f) 
    at bb.s1(f23 a, List`1 b) 
    at bb.r.a(f23 a) 
    at ae3.f`1.g(f23 a) 
    at VisualGDB.Add_In.Tool_Windows.WPF.DockedProgressPresenter.RunItemizedOperation(Action`1 operation, String caption, s7 exceptionHandler, String[] stages) 
    at ae3.o1[_ResultType](gh2`1 a, String c, Int32 b, String[] d) 
    at bb.x1() 
    trace=[qt1.c:752, bb.s1:1618, bb+r.a:0, ae3+f`1.g:0, VisualGDB.Add_In.Tool_Windows.WPF.DockedProgressPresenter.RunItemizedOperation:234, ae3.o1:92, bb.x1:123]

    Additionally, it would be much preferred for our scenario to have an FTP upload. Our system is very slow at processing encrypted data and that can cause uploads of ~100 MiB, which is a typical size for our binaries, to take several minutes.

    By the way, the upload test procedure always pretends to succeed, but the file still isn’t uploaded.

    To 4.:

    Build log:

    Run "cmake.exe --build --target HelloWorld build/debug-linux-arm-gnu" in directory "C:/cmakehw" on local computer
    cmake.exe --build --target HelloWorld build/debug-linux-arm-gnu
    Usage: cmake --build <dir> [options] [-- [native-options]]
    cmake --build --preset <preset> [options] [-- [native-options]]
    Options:
    <dir> = Project binary directory to be built.
    --preset <preset>, --preset=<preset>
    = Specify a build preset.
    --list-presets[=<type>]
    = List available build presets.
    --parallel [<jobs>], -j [<jobs>]
    = Build in parallel using the given number of jobs. 
    If <jobs> is omitted the native build tool's 
    default number is used.
    The CMAKE_BUILD_PARALLEL_LEVEL environment variable
    specifies a default parallel level when this option
    is not given.
    -t <tgt>..., --target <tgt>...
    = Build <tgt> instead of default targets.
    --config <cfg> = For multi-configuration tools, choose <cfg>.
    --clean-first = Build target 'clean' first, then build.
    (To clean only, use --target 'clean'.)
    --resolve-package-references={on|only|off}
    = Restore/resolve package references during build.
    -v, --verbose = Enable verbose output - if supported - including
    the build commands to be executed. 
    -- = Pass remaining options to the native tool.
    -------------------------------------------------------------
    Command exited with code 1
    Executable: cmake.exe
    Arguments: --build --target HelloWorld build/debug-linux-arm-gnu
    Directory: C:/cmakehw
    Command-line action failed
    
    ========== Project Build Summary ==========
    cmakehw built in 00:00
    ========== Build: 0 Succeeded, 1 Failed, 0 Skipped ==========

    Looking forward to your help. I’m sure we can make this work for our use case.

    #36470
    support
    Keymaster

    Hi,

    No problem, please try this build: VisualGDB-6.0.107.5304.msi. It should fix the issues #1 and #4.

    You can override the GDB server command line by switching the debug mode to Custom GDB Stub (VisualGDB Project Properties -> Debug Settings) and specifying the gdbserver command line manually.

    The SSH issues are trickier, but not unsolvable. One option would be to use the custom transport interfaces to define your own transport using FTP, Telnet or anything else. VisualGDB will delegate the low-level tasks like running commands to it, so you can ensure it only uses the interfaces supported by your target. Another option would be to patch libssh2 to work with your target, and emulate missing commands like stat. Our fork of libssh2 is published here; you can build a debug version and investigate why it is crashing.

     

    #36472
    oold_le
    Participant

    I can confirm that #1 and #4 are fixed now. Thank you very much!

    We will probably implement the transport for the problematic target via the plugin solution. Is it possible to only implement the file transfer that way and fall back to the default implementation for running commands on the target system? It looks to me like the access violation is only triggered by the file transfer.

    Another more or less minor issue for our workflow I’ve noticed is the debug target being configured for all project configurations. We have separate configurations for different target systems and it would be preferrable if we could save different sets of debug settings that are automatically selected via the chosen project configuration.

    #36473
    support
    Keymaster

    Hi,

    No problem. If you only want to override file transfers, it could be easier to disable deployment and source uploads on the VisualGDB level, figure out command-line tools that would do the deployment (ftp client?) and just run custom pre-build or pre-debug commands invoking those tools.

    With multiple targets, VisualGDB does support overriding the debug settings, however it only works when letting VisualGDB manage configurations and platforms. If you are using CMake presets, VisualGDB assumes that they can be changed at any moment outside VisualGDB, and tries to minimize dependencies on them. That said, you can try using Debugger Setups. The only difference is that you would need to pick a setup via the VisualGDB toolbar separately from picking the build preset.

    #36487
    oold_le
    Participant

    Hello,

    I have built a tool that takes care of uploading the file via FTP. The tool is launched via custom debug steps, followed by running a command that takes care of setting the executable permission on the file.

    For some reason, after modifying the gdbserver command in the VisualGDB properties, VisualGDB tries to debug locally with GDB, but still launched the gdbserver.

    The problem with gdbserver demanding the IP address before the port number also seems to stem from failed name resolution. It seems just the port number would work in general, but our system’s name resolution mechanism is broken.

    Also, VisualGDB detected the gdbserver not being able to bind to the port because a previous instance was still running and offered to kill it. That failed because it tried to run “killall -v gdbserver” and our killall responded with “killall: bad signal name ‘v'”. I guess I’ll just run “killall gdbserver” as pre-debug step before each session.

    #36488
    support
    Keymaster

    Hi,

    Good to know it’s starting to work.

    Running GDB locally would be happening if you did not enable the “Allow choosing build/clean/debug command hosts independently” checkbox in VisualGDB Project Properties -> Linux Project. If it is set, you would need to double-check the host configured in the GDB command selector.

    VisualGDB passes -v to killall so that it could log errors reported by it. We’ll monitor feedback from other users and will consider adding an option to disable it if it causes trouble on other systems. As a workaround, running killall as a custom pre-debug step should work just fine.

    #36489
    oold_le
    Participant

    Hi,

    I forgot to fill in the “target selection command”. Starting GDB and connecting works now.

    I’ll probably bundle a tool to be run before debugging and would like to know whether it’s possible to reference the path to the command via a registry value. Regular MSBuild projects allow grabbing values from the registry via “$(registry:…)”. Is that also possible in VisualGDB projects?

    #36490
    support
    Keymaster

    Hi,

    There is no direct mapping of registry keys into VisualGDB parameters, however you can use custom per-user variables (see this page) or define it via a system-level environment variable, and just reference it using the regular variable syntax.

Viewing 8 posts - 1 through 8 (of 8 total)
  • You must be logged in to reply to this topic.