I am using Visual Studio, developing a native application, I have a programmatical breakpoint (assert) in my code placed using __asm int 3 or __debugbreak. Sometimes when I hit it, I would like to disable it so that successive hits in the same debugging session no longer break into the debugger. How can I do this?
x86 / x64
Assuming you are writing x86/x64 application, write following in your watch window:
x86: *(char *)eip,x
x64: *(char *)rip,x
You should see a value 0xcc, which is opcode for INT 3. Replace it with 0x90, which is opcode for NOP. You can also use the memory window with eip as an address.
PPC
Assuming you are writing PPC application (e.g. Xbox 360), write following in your watch window:
*(int *)iar,x
You should see a value 0xfeNNNNNN, which is opcode for trap (most often 0x0fe00016 = unconditional trap). Replace it with 0x60000000, which is opcode for NOP.
You might try something like this:
#define ASSERT(x) {\
if (!(x)) \
{ \
static bool ignore = false; \
if (!ignore) \
{ \
ignore = true; \
__asm int 3 \
} \
}\
}
This should hit the debug only once. You might even show a messagebox to the user and ask what to do: continue (nothing happens), break (int 3 is called) or ignore (ignore is set to true, the breakpoint is never hit again)
Related
I now try create a firmware image running STM32F0xx MCU. It's like flash algorithm, provide some function call to control STM32F0xx MCU Pins, but it's more complicated than flash algorithm. So it will use STM32 HAL lib and Mbed lib.
The Compiler/linker use "-ffunction-sections" and "-fdata-sections" flags.
So I use "attribute((used))" to try keep function into firmware image, but it's failed.
arm-none-eabi-gcc toolchain version is 4.9.3.
My codes like this:
extern "C" {
__attribute__((__used__)) void writeSPI(uint32_t value)
{
for (int i = 0; i < spiPinsNum; i++) {
spiPins[i] = (((value >> i) & 0x01) != 0) ? 1 : 0;
}
__ASM volatile ("movs r0, #0"); // set R0 to 0 show success
__ASM volatile ("bkpt #0"); // halt MCU
}
}
After build succeed, the writeSPI symbol no in image.
I also try static for function, the "-uXXXXX" flag, create a new section.
Question: How keep writeSPI function code with "-ffunction-sections" and "-fdata-sections" flags?
One way to ensure a wanted function doesn't get garbage collected is to create a function pointer to it within a method that is used. You don't have to do anything with the function pointer, just initialize it.
void(*dummy)(uint32_t)=&writeSPI;
An alternative would be to omit the -ffunction-sections flag from the compilation units that contain functions that should not be stripped, but that may involve significant restructuring of your code base.
Code for an interrupt service handler:
volatile unsigned char x = 0;
void interruptHandler() __attribute__ ((signal));
void interruptHandler() {
f();
g();
}
Calls:
void f() { x ++; } // could be more complex, could also be in a different file
void g() { x ++; } // as `f()`, this is just a very simple example
Because x is a volatile variable, it is read and written every time it is used. The body of the interrupt handler compiles to (avr-gcc -g -c -Wa,-alh -mmcu=atmega328p -Ofast file.c):
lds r24,x
subi r24,lo8(-(1))
sts x,r24
lds r24,x
subi r24,lo8(-(1))
sts x,r24
Now I can manually inline the functions and employ a temporary variable:
unsigned char y = x;
y ++;
y ++;
x = y;
Or I can just write:
x += 2;
Both examples compile to the much more efficient:
lds r24,x
subi r24,lo8(-(2))
sts x,r24
Is it possible to tell avr-gcc to optimize access to volatile variables inside of interruptHandler, i.e. to do my manual optimization automatically?
After all, while interruptHandler is running, global interrupts are disabled, and it is impossible for x to change. I prefer not having to hand optimize code, thereby possibly creating duplicate code (if f() and g() are needed elsewhere) and introducing errors.
Is it possible to tell avr-gcc to optimize access to volatile variables inside of interruptHandler, i.e. to do my manual optimization automatically?
No, that is not possible in the C language.
After all, while interruptHandler is running, global interrupts are disabled
The compiler does not know this - and you could simply put an sei into the handler to turn them back on.
Also note that hardware registers are declared volatile, too. Some of these - like the UART data register - have side effects even when read. The compiler must not remove any reads or writes for these.
If you declare a variable to be volatile, then all accesses to it are volatile - the compiler will read and write it exactly as many times as the source code says, without combining them or doing similar optimisations.
So if you want combining optimisations, declare the variable without the "volatile" - then you will get what you need inside the interrupt code.
And then from outside the interrupt code, you can force volatile accesses using something like this macro:
#define volatileAccess(v) *((volatile typeof((v)) *) &(v))
Use "volatileAccess(x)" rather than "x" outside the interrupt code.
Just don't forget that "volatile" does not mean "atomic" !
How to write this assembly code as inline assembly? Compiler: gcc(i586-elf-gcc). The GAS syntax confuses me. Please give tell me how to write this as inline assembly that works for gcc.
.set_video_mode:
mov ah,00h
mov al,13h
int 10h
.init_mouse:
mov ax,0
int 33h
Similar one I have in assembly. I wrote them separate as assembly routines to call them from my C program. I need to call these and some more interrupts from C itself.
Also I need to put some values in some registers depending on which interrupt routine I'm calling. Please tell me how to do it.
All that I want to do is call interrupt routines from C. It's OK for me even to do it using int86() but i don't have source code of that function.
I want int86() so that i can call interrupts from C.
I am developing my own tiny OS so i got no restrictions for calling interrupts or for any direct hardware access.
I've not tested this, but it should get you started:
void set_video_mode (int x, int y) {
register int ah asm ("ah") = x;
register int al asm ("al") = y;
asm volatile ("int $0x10"
: /* no outputs */
: /* no inputs */
: /* clobbers */ "ah", "al");
}
I've put in two 'clobbers' as an example, but you'll need to set the correct list of clobbers so that the compiler knows you've overwritten register values (maybe none).
First, keep in mind GCC doesn't support 16-bit code yet, so you'll end up compiling 32-bit code in 16-bit mode, which is very inefficient but doable (it is used, for example, by Linux and SeaBIOS). It can be done with the following at the begging of each file:
__asm__ (".code16gcc");
Newer GCC versions (since 4.9 IIRC) support the -m16 flag that does the same thing.
Also, there's no mouse driver available unless you load it previous to your kernel running init_mouse.
You seem to be using an API commonly available in several x86 DOS.
asm can take care of the register assignments, so the code can be reduced to:
void set_video_mode(int mode)
{
mode &= 255;
__asm__ __volatile__ (
"int $0x10"
: "+a" (mode) /* %eax = mode & 255 => %ah = 0, %al = mode */
);
}
void init_mouse(void)
{
/* XXX it is really important to check the IDT entry isn't 0 */
int tmp = 0;
__asm__ __volatile__ (
"int $0x33"
: "+a" (tmp) /* %eax = 0*/
:: "ebx" /* %ebx is also clobbered by DOS mouse drivers */
);
}
The asm statement is documented in the GCC manual, although perhaps not in enough depth and lacks x86 examples. The outputs (after first colon) have a distinctively obscure syntax, while the rest is far easier to understand (the second colon specifies the inputs and the third the clobbered registers, flags and/or memory).
The outputs must be prefixed with =, meaning you don't care the previous value it may have had, or +, meaning you want to use it as an input too. In this context we use that instead of an input because the value is modified by the interrupt and you're not allowed to specify input registers in the clobbered list (because the compiler is forbidden from using them).
I'm trying to put the equivalent of asm{int 3} (or similar) into my iPhone program. My goal is to have Xcode stop exactly on the offending line, without having to fiddle with the call stack (so _Debugger doesn't sound like it would do, not that I could find which framework it's in anyway...), and leave me able to resume execution (which is why I'm not happy with assert).
(I'm used to both these behaviours on other systems, and I'd like to reproduce them on iOS.)
My best attempt so far has been this:
asm volatile("bkpt 1");
This stops Xcode on the line in question, but when I try to continue with Cmd+Alt+P, Xcode appears to run the BKPT again. And if I use Shift+Cmd+O, I just get this:
Watchdog has expired. Remote device was disconnected? Debugging session terminated.
(Needless to say, the remote device IS still connected.)
I don't have a huge amount of experience with iOS, Mac, ARM, gdb, or gcc's asm stuff. So I'm stumped already. Is there some way of getting iOS and Xcode to do what I want?
(I don't know if it makes a difference but judging by the instruction size my program is ARM code.)
Try:
__builtin_trap();
works on Mac as well as iOS, and you can drag the little green cursor to the next line to continue running.
raise(SIGTRAP) is a relatively portable way to have an "in code" breakpoint.
I've tried all of these solutions and although #RichardGroves answer preserved the stack, the best solution is to:
create your own assert method, such as Debug::assert(...)
set a breakpoint within XCode on that implementation
use the Step Out command to get back to the caller
This is because it's the only reliable way to both
view the stack trace
step / continue
int resume = false;
for (int i = 0; i < 20 && !resume; ++i)
sleep(1);
Above is a poor man's trap in that you have to manually attach to the program in question. Increase the delay as appropriate. Put the code where you want to break, and insert a breakpoint on the sleep statement, build and run your program, and attach to it from Xcode. Once Xcode breaks, you can right-click on the resume variable and edit it to 1, to resume execution.
I tried to find implementation that behaves the same as __debugbreak() that comes with Microsoft compiler and breaks inside my code and not somewhere inside system libraries and allows me to continue execution. This implementation of __debugbreak() works exactly as I wanted:
#if defined(__APPLE__) && defined(__aarch64__)
#define __debugbreak() __asm__ __volatile__( \
" mov x0, %x0; \n" /* pid */ \
" mov x1, #0x11; \n" /* SIGSTOP */ \
" mov x16, #0x25; \n" /* syscall 37 = kill */ \
" svc #0x80 \n" /* software interrupt */ \
" mov x0, x0 \n" /* nop */ \
:: "r"(getpid()) \
: "x0", "x1", "x16", "memory")
#elif defined(__APPLE__) && defined(__arm__)
#define __debugbreak() __asm__ __volatile__( \
" mov r0, %0; \n" /* pid */ \
" mov r1, #0x11; \n" /* SIGSTOP */ \
" mov r12, #0x25; \n" /* syscall 37 = kill */ \
" svc #0x80 \n" /* software interrupt */ \
" mov r0, r0 \n" /* nop */ \
:: "r"(getpid()) \
: "r0", "r1", "r12", "memory")
#elif defined(__APPLE__) && defined(__i386__)
#define __debugbreak() __asm__ __volatile__("int $3; mov %eax, %eax")
#endif
#define ASSERT(expr) do { if (!(expr)){ __debugbreak(); } } while(0)
int pthread_kill(pthread_t thread, int sig); allows for continuation, and pauses on the current thread, via pthread_self().
Similar to other signal functions (e.g., kill(), raise(), etc.), however,pthread_kill() is used to request that a signal be delivered to a particular thread.
Pthread_kill Manual
std::runtime_error::runtime_error("breakpoint")
together with an XCode exception breakpoint of type
Exception:C++ "named:std::runtime"
worked for me (using XCode 8.0).
It yields the same result as if I had set a breakpoint manually at the line where the
std::runtime_error::runtime_error
function is called, i.e. correct thread, correct call stack, and the possibility to resume.
To force xcode to break, use
kill(getpid(), SIGSTOP)
You can then step out/up and use lldb per usual. When you're done, you can hit continue and it works just like a breakpoint set from the Xcode GUI.
Tested with Swift 5 and Xcode 11.3
Direct equivalent of x86 int3 / int 3 in arm / arm64 is
#if TARGET_CPU_ARM | TARGET_CPU_ARM64 | TARGET_CPU_ARM64E
asm volatile("trap");
#endif
I have a more complicated version of the following:
unsigned int foo ();
unsigned int bar ();
unsigned int myFunc () {
return foo()+bar();
}
In my case, myFunc is called from lots of places. In one of the contexts there is something going wrong. I know from debugging further down what the return value of this function is when things are bad, but unfortunately I don't know what path resulted in this value.
I could add a temporary variable that stored the result of the expression "foo()+bar()" and then add the conditional breakpoint on that value, but I was wondering if it is possible to do in some other way.
I'm working on x86 architecture.
From this and this answer I thought I could set a breakpoint at the exact location of the return from the function:
gdb> break *$eip
And then add a conditional breakpoint based on the $eax register, but at least in my tests here the return is not in this register.
Is this possible?
Agree with previous commenter that this is probably something you don't want to do, but for me, setting a conditional breakpoint at the last instruction on $eax (or $rax if you are on 64-bit x86) works just fine.
For the code
unsigned int foo(void) { return 1; }
unsigned int bar(void) { return 4; }
unsigned int myFunc(void) { return foo()+bar(); }
using gdb ..
(gdb) disass myFunc
Dump of assembler code for function myFunc:
0x080483d8 <myFunc+0>: push %ebp
0x080483d9 <myFunc+1>: mov %esp,%ebp
0x080483db <myFunc+3>: push %ebx
0x080483dc <myFunc+4>: call 0x80483c4 <foo>
0x080483e1 <myFunc+9>: mov %eax,%ebx
0x080483e3 <myFunc+11>: call 0x80483ce <bar>
0x080483e8 <myFunc+16>: lea (%ebx,%eax,1),%eax
0x080483eb <myFunc+19>: pop %ebx
0x080483ec <myFunc+20>: pop %ebp
0x080483ed <myFunc+21>: ret
End of assembler dump.
(gdb) b *0x080483ed if $eax==5
Breakpoint 1 at 0x80483ed
(gdb) run
Starting program: /tmp/x
Breakpoint 1, 0x080483ed in myFunc ()
(gdb)
I don't get whether you're compiling from the command line or not, but from within Visual Studio, once you set your breakpoint, right-click it and click the "Condition..." option for a dialog to appear to let you edit the condition for your breakpoint to break.
Hope this helps! :-)