Android Debugging stalls indefinitely in VS2015

visual-studio
cooper

(Matt Robertson) #1

When debugging my Android app in VS2015, the debugger often stalls indefinitely. If I “pause” the debugger, it always take me to a line where I have a call to Android’s getResources().getIdentifier(). Occasionally the debugger simply refuses to run, displaying the following error: “No Compatible Code Running. The selected debug engine does not support any code executing on the current thread (e.g. only native runtime code is executing).”

A Google search led me to this VS forum thread: https://developercommunity.visualstudio.com/content/problem/70880/no-compatible-code-running-the-selected-debug-engi.html

The MS reply says, “We have determined that this issue is not a bug. That error happens when you are debugging managed code, but there is an error that occurs in native code and only native code is on the callstack” and provides this link:
https://docs.microsoft.com/en-us/visualstudio/debugger/how-to-debug-in-mixed-mode

Since the debugger always appears to stall on the request for an Android resource it makes sense that this could be what’s going on for me too. (I should note that the debugger was running fine for me for a while even with the Android resource call - it does not seem to be a consistent problem, but it is currently a problem about 90% of the time for me right now, making debugging impossible.)

It looks like for C++, C#, and VB there is a “Debug” tab in project settings with an option for debugging mixed/native code that can be used to address the issue, but there is no Debug tab in the Oxygene project settings.


(marc hoffman) #2

Does the same happen in Water? I doubt the links you fund are applicable, since Android debugging is entirely our own debug engine, and not using Microsoft’s debugger (they refer to .NET and, when they say Mixed Mode, .NET+Win32).

AT this stage Oyxgene supports only Java-level debugging for Android, although we’ll be adding mixed (Java+NDK) debugging, later. But this seems entirely unrelated.

Can I assume if you tun your app outside of the debugger (ie just tap it to launch), it gets beyond getResources().getIdentifier()., and your app runs fine? Do any exceptions get reported in the IDE before/when it hangs?


(Matt Robertson) #3

I don’t have Water - I was under the impression it had not been released yet?

And yes the app runs fine outside of the debugger. No exceptions and no crash or fail in the IDE, it just hangs indefinitely.


(marc hoffman) #4

It’s in beta, but close to ready. If you like, I can send you a copy of .2311 including Water (and it’ll update your version in VS too). While it’s the same debug engine in both, Water is “closer to the metal”, So if we do (or don’t) see the same issue win Water, we can rule out VS’s debug API overhead getting in the way of things…

What’s your username on remobjects.com?

ok, good. Note that any Andpoid app will throw dozens of (caught) exceptions on launch. im guessing one of those hicks the debugger up, somehow.


(marc hoffman) #5

Nevermind, found it. the download should be available to you. now at https://www.remobjects.com/portal/downloads/personal.


(Matt Robertson) #6

Installed Water. It’s a bit difficult to check debugging at the moment. I was previously building on 9.3.103.2211 – after installing the latest version I am getting a few thousand build errors on the same code.


(Matt Robertson) #7

It is possibly related to compiler directives (which we have a lot of in our code). This is one of the first build errors:

error E1: {$ENDIF} expected, got END

This is the code it is complaining about:

{$IF NOT OXYGENE}
    {------------------- TProtoStrResource stuff ------------------------------}

	TProtoStrResource = public class(TObject) // OXYGENE NOT USED
	public
		PROCEDURE GetStringFromResource (stringListID, itemNum: LongInt;
										VAR sText: Str;
										VAR found: Boolean); virtual;
	END;


    {--------------------- TSyncTaskType ----------------------------}
    TYPE
    	TSyncTaskType = public class (TObject)
    	public
    		fTask: DropboxSyncTaskType;
    		fFileName: UStr;
    		fLastSyncDate: Double;
    		fDownloadSize: LongInt;
    		fRunningDownloadBytesTotal: Int64;
    		fMergeDict: TDictionary;
    		PROCEDURE ITSyncTaskType ;
    		PROCEDURE Free ;
    			OVERRIDE;
		END;
{$ENDIF NOT OXYGENE}

(marc hoffman) #8

Ah, see, that would have been important to know. 9.3 is almost a year old at tis stage, and the debug infrastructure has changed significantly since then. So even whatever issues you’re seeing in Visual Studion may long be solved…

Yes, $IFDEFs got a bit stricter in v10. Essentially, you cannot put {$IF}/$END} around partial code constructs (eg comment out a “begin” but not the matching “end” with the same ifdef. Also, all code, even undefined, must be syntactically valid (but it can use undefined names, of course).

Most iof these issues are easily fixed by moving the {$IFs around a bit. What precedes the {$IF NOT OXYGENE} in this example?


(Matt Robertson) #9

Ah - if I’m understanding you correctly here, this will make it impossible for us to ever update to the latest Elements version. We have a significant amount of code shared with Windows/Mac targeted builds and are mostly using compiler directives to avoid syntax conflicts on FPC syntax not supported by Oxygene. When you say “must be syntactically valid,” I assume that does not include syntactically valid Pascal code not supported by Oxygene? (e.g., New(), Destructor, x = Object(), Otherwise)


(marc hoffman) #10

Delphi-compatible code should be fine (and if you find any that isn’t, please let us know and we’ll fix it. The only thing that never be fine is overlapped structured, for (contrived) example:

type
  Foo = public class
    method A;
    method B;
    {$IFDEF BAR}
    method B;
  end;

  Bar = public class
    method D;
    method E;
    {$ENDIF}
    method F;
  end;

IOW, if you think of your code as nested structures (classes, methods, loops/blocks, individual statements…) then {$IFDEF}/{$ENDIF} are such a structure too. They must either surround the structures they contain completely, or be within them completely; they cannot overlap/break.

Just as an two regular code strictures could not overlap (eg, dummy code:

repeat

  if whatever then begin

  until false; // ends the repeat

end; // ends the if

(Matt Robertson) #11

Thanks Marc. I’ll have to look into it more, but I’m guessing there will be some future requests from us related to this. We definitely appreciate your support here.

Here is a bit more of the code you asked for – not sure how far back you need, but I imagine this should be enough to see what you’re looking for

	TYPE
{$IF NOT OXYGENE}
		LineRec = public class
		public
			startX, startY, endX, endY: Single;
		END;
{$ENDIF NOT OXYGENE}

		HMENU = HandleWin;
		MenuRef = HMENU;
		MenuRefArrayList = AcArrayList<MenuRef>;
		MenuAccelArrayList = AcArrayList<ACCEL>;
		ControlPartCode = Integer;
		TWndArray = AcArrayList<HWND_Object>;
		regClassArray_0Base = ARRAY[0..pred(kMaxAtoms)] OF Word;

{$IF NOT OXYGENE}
	{------------------- TProtoStrResource stuff ------------------------------}

		TProtoStrResource = public class(TObject)
		public
			PROCEDURE GetStringFromResource (stringListID, itemNum: LongInt;
											VAR sText: Str;
											VAR found: Boolean); virtual;
		END;


	{--------------------- TSyncTaskType ----------------------------}
	TYPE
		TSyncTaskType = public class (TObject)
		public
			fTask: DropboxSyncTaskType;
			fFileName: UStr;
			fLastSyncDate: Double;
			fDownloadSize: LongInt;
			fRunningDownloadBytesTotal: Int64;
			fMergeDict: TDictionary;
			PROCEDURE ITSyncTaskType ;
			PROCEDURE Free ;
				OVERRIDE;
		END;
{$ENDIF NOT OXYGENE}

	VAR
	MacRomanToUnicode : {etc., etc.}

(RemObjects) #12

Thanks, logged as bugs://80734


(marc hoffman) #13

Reproduced & logged.

I’d expect this one would be easily fixable. It’s the extra “type” when already in a type declaration block that throws it off. Imho this should be allowed, and needs a fix. What’s probably happens is that the compiler considers the ifdef “inside” the “type” block, and this doesnt allow to close it off and start a new one.

Workaround, of course, is to simply remove there extra and unnecessary second “TYPE” keyword.

thanx!


(RemObjects) #14

bugs://80734 got closed with status fixed.