Continue after assert with Android NDK and GDB - android

Is it possible to trigger an GDB break from C++ in an Android NDK program which still allows the program to resume afterwards?
Meaning, I hit the assert causing GDB to halt the program, and I want to be able to press the "Play" button in Eclipse to resume the program, continuing beyond the assert.
Right now I am using:
__asm__ ("bkpt 0");
This triggers the program to halt, and brings me to the line of code that triggered it, but does not allow me to resume afterwards.
GDB output the following at the time that the program is halted.
(gdb)
82 info signal SIGBUS
&"info signal SIGBUS\n"
~"Signal Stop\tPrint\tPass to program\tDescription\n"
~"SIGBUS Yes\tYes\tYes\t\tBus error\n"
82^done
(gdb)
If I press "resume" at this point I get the following output in the LogCat:
Fatal signal 11 (SIGSEGV) at 0xfffffffd (code=1)
Perhaps my quesiton is how to throw a non-fatal break?

The standard Linux way of detecting if your process is being debugged is:
if (ptrace(PTRACE_TRACEME, 0, NULL, 0) == -1)
//Yes, we're running under GDB
With that in mind, do a conditional hard breakpoint (bkpt 0) that only fires when under debugger.
Not sure if Java-only debugging in Android would affect ptrace. Give it a try.
EDIT: call raise(SIGABRT) to break. Then in GDB, type signal 0 to continue. Other signals, like SIGINT and SIGTRAP, might work too.

Related

using continue in LLDB stops the process and throws a SIGSEGV

I'm trying to debug a native C++ App that is crashing using lldb
I also have a sleep(5) at the start of android_main so that I can attach to my app in that time, if that matters
After attaching the app is paused/stopped. So, I use continue
But the process is immediately stopped after using continue and throws a SIGSEGV
(lldb) continue
Process 4158 resuming
Process 4158 stopped
* thread #19, name = 'com.example.app', stop reason = signal SIGSEGV: invalid address (fault address: 0x0)
frame #0: 0x00007cefe26282c8
-> 0x7cefe26282c8: movq (%rcx), %rdx
0x7cefe26282cb: movq %rdx, 0x18a0(%rax)
0x7cefe26282d2: movl 0x8(%rcx), %ecx
0x7cefe26282d5: movl %ecx, 0x18a8(%rax)
After another continue, the app just exits/crashes
(lldb) continue
Process 4158 exited with status = 11 (0x0000000b)
How do I fix this and just continue execution as normal?
Your app crashed because the register rcx was supposed to hold the address of some object, but in fact held a value that was not in readable memory. That's what SIGSEGV means - a request was made to access memory that couldn't be fulfilled. You can't "continue execution as normal" since the program didn't get some data it needs, so it doesn't have a way to move forward. If you knew the value that SHOULD have been in rcx, you could set rcx to the right value, and then continue. But what you really have to do is figure out why that value was bad, fix the code, rebuild and rerun.

Explain behavior of Unix sleep() function executed on Android

I am currently compiling and executing some C++ code on a rooted Android device. I use adb (adb shell). To compile my code, I don't use the NDK, but I cross-compile with CMake
I'm using the function sleep(seconds) of unistd.h.
I've experienced some curious behaviors with that function on Android: Basically, I have a for loop in which I std::cout something and then call sleep(x).
If I call sleep(1), the behavior is the one expected: The program waits 1 second, and then executes the next instructions.
If I call sleep(2), the behavior isn't the one expected. The program gets stuck on that instruction for ever.... until I hit a key on my PC keyboard (not the device's one), and then it gets stuck on the next sleep(2)... until I hit a key, etc...
This behavior happens only when the device screen is off. As soon as I click on the power button to turn the screen on, the program resumes and has the expected behavior.
N.B: The behavior is the same with usleep(useconds)
I have tried to see where the limit is between 1 and 2 seconds:
1.5s, 1.25s, 1.125s -> always stay blocked | 1.0625s -> ~50% chance of staying blocked.
Obviously, there is something that prevents a thread to wake up if it sleeps more than 1 seconds (at least 2).
So my question would be, does anyone have any idea of why this is happening, and has a detailed explanation of the process ?
Thank you !
Android puts applications in the background when they aren't doing any user interaction - unix sleep and java timers etc. won't wake them up. You have to use an android alarm or runnable postDelayed handler.

Android NDK - Debugging a random crash with a bad callstack

My android native application crashes randomly but frequently, and I am unable to get sufficient info out ndk-gdb. This is the message following the crash:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 19983]
0x4012c6ac in memcpy () from /Users/Andreas/dev/android/obj/local/armeabi-v7a/libc.so
bt returns an unusable callstack:
#0 0x4012c6ac in memcpy () from /Users/Andreas/dev/android/obj/local/armeabi-v7a/libc.so
#1 0x67337388 in ?? ()
Cannot access memory at address 0x7
#2 0x67337388 in ?? ()
Cannot access memory at address 0x7
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
I am using NDK-r8e
I have checked all uses of memcpy() in my program and they're not responsible for this (verified by making them call another memcpy-like function with a different name, and still getting the above crash with the exact signature).
Any ideas how to get a more useable call stack, or to further debug this? Does the NDK offer any memory check functionality in case this is a memory overwrite?

Android crash sometime on exit

I've found that my problem have been report many times on Internet, but I do not found any correct explanantion about it.
On my Galaxy Note, when I exit from my program, I have some time this kind of message into le logcat.
threadid=3: reacting to signal 3
Wrote stack traces to '/data/anr/traces.txt'
I can't acces to the file. DDMS view does not show me anything into the Explorer.
I read on Internet that ANR (Application Not Responding) was due to Activity long process.
But in my case, my activity does not do any special things.
I'm using a SurfaceView that launch 3 Threads.
One of them can take a long time (1 or 2 seconds) at the beginnig of the application (it read's big data files from sdcard), but it does not do anything at the end when I exit.
I can see 10 process into DDMS view, but I do not know what thread is the #3 !
So I do not know if it's one of the thread I launch or if this is a Android thread.
More than finding the problem, I'd like to understand what is signal 3.
When this king of problem happened. Is it only due to a process that not responding or can it be due to another problem ?
I tested my native code under linux (beagleboard). There is no memory leak and no segmentation fault.
Why does this problem happened only when I exit my application (and only sometimes). Does it mean that my thread destruction is not correct ?
I'm using this code
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
while (retry) {
try {
thread.join();
retry = false;
} catch (InterruptedException e) {
// try again shutting down the thread
}
}
}
I also have a special code into onDestroy of my Activity.
This code make some native Code free.
Because it's c++ code, it call all the destructor of my objects.
I don't know if this destrution is long, but I suppose it must not take more than 1 ms.
Well. I've work on this problem for 1 week now.
The next step for me if I do not understand the problem will be to restart a new projet and import my code, part by part to check when the problem really occured.
Well. I've started a new project, And I found some informations!
Thread #3 might be the Garbage collector Thread.
It seem's that the problem occured on exit when the GC do something with the malloc I've made into my native code.
I changed all my code and just made a big C++ malloc (20Mo) into the OnCreate of the activity. And a free into OnDestroy.
After some exit and restart, I have the problem.
I do not know what is the link between CG and native C malloc, but I guess that after some start the malloc failed, because th GC process do not have enough time to clean the native buffer...
Actually no crash.
Sometime the application take few seconds to start but the phone do not crash.
This is possible that I do not test every where the result of my malloc calls, so my problem could comes from a failed malloc. I will check again.

Android with jdb confusion using waitForDebugger

I'd like to debug my Android application on my device (Nexus One - not the emulator) using the command line.
I'm confused at how to set a breakpoint using jdb in combination with android.os.Debug.waitForDebugger.
Say I put the following code in my main activity onCreate:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
android.os.Debug.waitForDebugger();
int j = 10;
int r = j;
}
Using ddms I can see that my application is waiting for the debugger (red bug icon) when I start it.
However, I don't understand how to set a breakpoint after the waitForDebugger() call so that I can start stepping.
Obviously just attaching jdb is going to immediately continue running the app without stopping.
e.g.
jdb -attach localhost:8700
Is there way to preset breakpoints prior to running jdb or a way to start jdb set breakpoints and then attach?
jdb has a config file : ~/.jdrbc in Linux. e.g in mine I have:
stop in net.richardriley.myproj.myact.onCreate
The in your device emulator dev settings you can set "wait for debugger" for the application class in question. Run the application, start the debugger and it will break.
Unfortunately, there is no way for the VM to tell the debugger that it's already suspended. The various debuggers I've tried get confused if the initial state is anything other than "running". As a result, after the debugger connects, the VM has to resume all threads. (The only exception to the above is if the VM was just started, in which case it can send a special "I just started" message indicating whether it's going to come up running or stay suspended. This doesn't help here.)
What waitForDebugger() does do is wait until the initial burst of activity from the debugger quiets down. After the debugger connects, the method will sleep until there has been no activity from the debugger for 1.5 seconds. This allows the debugger a chance to set any breakpoints before the VM resumes.
For Eclipse, this hack works out pretty well, because you can configure your breakpoints before you attach. For jdb, there's no way I can see to tell it to attach after it has started up, so you have to be quick on the keyboard or use some sort of config file (which I also don't see).
You could solve this a different way: below the waitForDebugger call, add a loop like:
static volatile boolean staticField = false;
...
while (!MyClass.staticField) {
Log.d(tag, "waiting for go");
Thread.sleep(2000);
}
Then, after you've got jdb configured the way you want, use something like:
> set MyClass.staticField = true
If you're quick, you could skip the loop and just Thread.sleep(5000) to give yourself a little extra time to slam breakpoints in.
I've tried with both solutions (the one from fadden and the one from Richard Riley), but none of them worked. The app launched in the emulator get unblocked as soon as a jdb is attached to the debug port (8700 via Dalvik) but then it runs on its own, without synchronizing with jdb at all. Introducing a waiting loop does not change things, and breakpoint commands in .jdbrc have no effect. Invariably, the jdb answer is "Deferring breakpoint etc. etc. It will be set after the class is loaded.", as the app was not running; but, if you type "run" the answer is "Nothing suspended.", as the app was already running...

Categories

Resources