Recent

Author Topic: Damaged values of global variables with GDB 32-bit (Windows)  (Read 1844 times)

Igor Kokarev

  • Jr. Member
  • **
  • Posts: 75
Damaged values of global variables with GDB 32-bit (Windows)
« on: November 15, 2018, 01:38:01 pm »
Hi,

I discovered a problem of damaged values for global variables when 32-bit app is working under GDB debugger on Windows 10.

This problem doesn't occur in 64-bit app under GDB debugger.

For example, I call ExpandEnvironmentStringsW() to get a value of global variable %LOCALAPPDATA%

For 32-bit app under GDB debugger I get damaged value:

Quote
C:\Users\Р?Р?Р?С?С?\AppData\Local

Non-latin symbols are damaged.

Same 32-bit app without GDB, or 64-bit with/or without GDB returns correct value:

Quote
C:\Users\Игорь\AppData\Local

You can simulate this problem - add a new global variable in Windows 10 with a path to a folder with non-Latin symbols (Russian, or French, German).

Another example where this problem occurs. My profile name in Windows 10 is "Игорь" (non-Latin symbols). And when I call Open/Save dialog window in my 32-bit app under GDB debugger I always see an error message from in Open/Save dialog that path to Desktop can't be found. See the screenshot.

Lazarus 1.8.4, fpc 3.0.4, Windows 10 64 bit, v1803.

Test app:

Code: Pascal  [Select]
  1. {$APPTYPE CONSOLE}
  2. program EnvTest;
  3.  
  4. function ExpandEnvironmentStringsW(lpSrc: PWideChar; lpDst: PWideChar;
  5.   nSize: Cardinal): Cardinal; stdcall; external 'kernel32.dll' name 'ExpandEnvironmentStringsW';
  6.  
  7. function GetEnv(const Name: WideString): WideString;
  8. var
  9.   Len     : Cardinal;
  10. begin
  11.   Len:=ExpandEnvironmentStringsW( PWideChar(Name), nil, 0);
  12.   if Len>0 then begin
  13.     SetLength(Result, Len-1);
  14.     ExpandEnvironmentStringsW( PWideChar(Name), PWideChar(Result), Len );
  15.   end else Result:='';
  16. end;
  17.  
  18. procedure Test(const Name : WideString);
  19. begin
  20.   WriteLn( Name,' = ', GetEnv(Name) );
  21. end;
  22.  
  23. begin
  24.   WriteLn('Sizeof(Pointer) = ',Sizeof(Pointer)*8,' bits');
  25.   Test('%LOCALAPPDATA%');
  26.   ReadLn;
  27. end.
  28.  
« Last Edit: November 15, 2018, 01:41:13 pm by Igor Kokarev »

Thaddy

  • Hero Member
  • *****
  • Posts: 7610
Re: Damaged values of global variables with GDB 32-bit (Windows)
« Reply #1 on: November 15, 2018, 02:42:05 pm »
What gdb version are you using?
Ad Brexinitum (can't help it)

Igor Kokarev

  • Jr. Member
  • **
  • Posts: 75
Re: Damaged values of global variables with GDB 32-bit (Windows)
« Reply #2 on: November 15, 2018, 04:25:16 pm »
Default GDB debugger from Lazarus 1.8.4 (fpc 3.0.4).

I think it's 7.7.1 ?
« Last Edit: November 15, 2018, 04:27:07 pm by Igor Kokarev »

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 5163
    • wiki
Re: Damaged values of global variables with GDB 32-bit (Windows)
« Reply #3 on: November 15, 2018, 04:29:30 pm »
For 32-bit app under GDB debugger I get damaged value:

Quote
C:\Users\Р?Р?Р?С?С?\AppData\Local

Non-latin symbols are damaged.

1) For clarification, this is what you see in the watches window (there is a small chance the watches window is wrong), and you application also behave badly => i.e., your app fails, because the data is indeed wrong?

2) On the sourceforge page, in the section "windows 32" -> "Alternative debuggers" are other gdb versions, please test with those.


If (1) is "your app fails due to wrong data" => then this may go wrong when the IDE sets up the environment for the debugged app.

If (1) is "your app fails due to wrong data" => then report as a bug (if possible with results for all tested gdb versions)

ASerge

  • Hero Member
  • *****
  • Posts: 1122
Re: Damaged values of global variables with GDB 32-bit (Windows)
« Reply #4 on: November 15, 2018, 05:16:05 pm »
I discovered a problem of damaged values for global variables when 32-bit app is working under GDB debugger on Windows 10.
Confirm. Windows 7. Lazarus 2.0.0RC2 32x. GDB 7.7 or GDB 8.2
The program gives different result when start by F9 vs by Ctrl+Shift+F9.
GDB provides the application with corrupt environment variables (I see this in Process Explorer).

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 5163
    • wiki
Re: Damaged values of global variables with GDB 32-bit (Windows)
« Reply #5 on: November 16, 2018, 10:37:04 am »
Have to do some tests, how to (if possible) fix this with gdb. You may want to report it on the bugtracker.

In the meantime, it seems that LazDebuggerFp (FpDebug) can handle this. (Your app may have to call the widestring version of GetEnvironmentVariable, unless all chars are in your Windows' local encoding).

Note that FpDebug has other shortcomings.
To use it install the package LazDebuggerFp, and change the debugger type in the options (no external exe, you can leave the path to gdb as it is - it is not used).
For FpDebug you want to be at least on Lazarus 2.0 fixes (or RC2), or trunk. Though it is available in 1.8 too. (If you stay 32 bit 1.8 may be ok-ish, not sure when environment was implemented / env works on trunk, tested on win64, but should be the same on w32)

Igor Kokarev

  • Jr. Member
  • **
  • Posts: 75
Re: Damaged values of global variables with GDB 32-bit (Windows)
« Reply #6 on: November 16, 2018, 03:01:50 pm »
Hi Martin,

Thanks for your reply!

We use a workaround to partially avoid this problem in gdb:

We manually recover coding of global variables. We convert a resulting WideString to the Windows default ANSI code page by using of MultiByteToWideChar() with a flag CP_ACP. Then the resulting bytes of string we interpret as UTF8 string. Converting of this UTF8 string to WideString gives the correct global variable string.

Probably in gdb there is a back sequence of actions:
1. global variable string is being converted to UTF8 string;
2. resulting string (bytes of UTF8 string) is being converted to WideString with converting to the Windows default  ANSI code page instead of UTF8.

This workaround works only for chars of current locale in Windows.
For example, Russian chars (in global variables) for Russian current locale in Windows.

P.S. Our workaround doesn't work in Open/Save dialog windows, because it's not our code.