In Immunity Debugger you would use Shift+F7 to pass the exception to the app. How do I do this in Windbg? Pressing g does not do anything. It only repeats the error message.
In WinDbg you have additional choice of
gh (Go with Exception Handled) or gn (Go with Exception Not Handled)
It also distinguishes between first chance and second chance exceptions.
On first chance, pressing g or gn will pass the exception to to the program.
If the program doesn’t handle, there will be a second chance, which looks nearly the same in WinDbg.
(3480.1bf0): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
CrashTest!CCrashTestDlg::OnButtonCrash+0x15:
00000001`400083f5 c70005000000 mov dword ptr [rax],5 ds:00000000`00000000=????????
0:000> g
(3480.1bf0): Access violation - code c0000005 (!!! second chance !!!)
CrashTest!CCrashTestDlg::OnButtonCrash+0x15:
00000001`400083f5 c70005000000 mov dword ptr [rax],5 ds:00000000`00000000=????????
More info: Controlling Exceptions and Events (MSDN)
Related
I'm debugging a dumpfile (memory dump, not a crashdump), which seems to contain two times the amount of expected objects. While investigating the corresponding symbols, I've noticed the following:
0:000> x /2 <product_name>!<company>::<main_product>::<chapter>::<subchapter>::<Current_Object>*
012511cc <product_name>!<company>::<main_product>::<chapter>::<subchapter>::<Current_ObjectID>::`vftable'
012511b0 <product_name>!<company>::<main_product>::<chapter>::<subchapter>::<Current_ObjectID>::`vftable'
01251194 <product_name>!<company>::<main_product>::<chapter>::<subchapter>::<Current_Object>::`vftable'
0125115c <product_name>!<company>::<main_product>::<chapter>::<subchapter>::<Current_Object>::`vftable'
For your information, the entries Current_Object and Current_ObjectID are present in the code, no problem there.
What I don't understand, is that there seem to be two entries for every symbol, and their memory addresses are very close to each other.
Does anybody know how I can interprete this?
it can be due to veriety of reasons Optimizations and redundant code elimination being one at the linking time (pdb is normally made when you compile) see this link by raymond chen for an overview
quoting relevent paragraph from the link
And when you step into the call to p->GetValue() you find yourself in Class1::GetQ.
What happened?
What happened is that the Microsoft linker combined functions that are identical
at the code generation level.
?GetQ#Class1##QAEPAHXZ PROC NEAR ; Class1::GetQ, COMDAT
00000 8b 41 04 mov eax, DWORD PTR [ecx+4]
00003 c3 ret 0
?GetQ#Class1##QAEPAHXZ ENDP ; Class1::GetQ
?GetValue#Class2##UAEHXZ PROC NEAR ; Class2::GetValue, COMDAT
00000 8b 41 04 mov eax, DWORD PTR [ecx+4]
00003 c3 ret 0
?GetValue#Class2##UAEHXZ ENDP ; Class2::GetValue
Observe that at the object code level, the two functions are identical.
(Note that whether two functions are identical at the object code level is
highly dependent on which version of what compiler you're using, and with
which optimization flags. Identical code generation for different functions
occurs with very high frequency when you use templates.) Therefore, the
linker says, "Well, what's the point of having two identical functions? I'll
just keep one copy and use it to stand for both Class1::GetQ and
Class2::GetValue."
In particular the print command typically (80-90% failure rate) does not work
I've verified already:
https://developer.apple.com/library/content/qa/qa1947/_index.html
Example 1
(lldb) p prevMsg
error: Couldn't materialize: couldn't get the value of runOnce: extracting data from value failed error: errored out in DoExecute, couldn't PrepareToExecuteJITExpression
Example 2 A more typical example that puts you in a stone age of computing:
(lldb) p activeNetworkRequests
error: Execution was interrupted, reason: EXC_BAD_ACCESS (code=1, address=0x1700530). The process has been returned to the state before expression evaluation.
This seems to have gotten progressively worse since Xcode 7.
Printing variables scoped from the enclosing function of a closure are particularly hopeless.
The code base is not small, about 15K lines. It would not be practical to isolate and reproduce all the code here.
Surely others are experiencing this?
UPDATE: I'm told about the merits of expression --unwind-on-error=0 -- variable-in-question, presumably for example2
UPDATE 2:
Code:
Util.log("Returning \(key) from file cache", [.Caches])
Output:
08:03:11.201 v2.0.64d other TwoStageCache.swift objectForKey(_:completion:)[95]: Returning https://example.server.com/Storage/Retrieve?FileName=accounts/person#domain.com/resource/47a58660-26d1-11e7-8e7f-c9f4cd679b03.html from file cache
(So the value of key is fine)
(lldb) fr var key
(URL) key = unable to read data
(lldb) print key
error: Execution was interrupted, reason: EXC_BAD_ACCESS (code=1, address=0x1d787583).
The process has been returned to the state before expression evaluation.
If we look at the crash:
(lldb) expression --unwind-on-error=0 -- key
libobjc.A.dylib`objc_retain:
0x22562b0 <+0>: pushl %ebp
0x22562b1 <+1>: movl %esp, %ebp
0x22562b3 <+3>: subl $0x8, %esp
0x22562b6 <+6>: calll 0x22562bb ; <+11>
0x22562bb <+11>: popl %ecx
0x22562bc <+12>: movl 0x8(%ebp), %eax
0x22562bf <+15>: testl %eax, %eax
0x22562c1 <+17>: je 0x22562e1 ; <+49>
0x22562c3 <+19>: movl (%eax), %edx
-> 0x22562c5 <+21>: testb $0x2, 0x10(%edx)
From:
1 $__lldb_expr(UnsafeMutablePointer<Any>) -> ()
2 Beta Viewer`#objc AppDelegate.init() -> AppDelegate:
3 sharedEnchantment`partial apply for TwoStageCache.(objectForKey(URL, completion : (imgData : Data?, err : BBError?) -> ()) -> ()).(closure #1)
4 sharedEnchantment`thunk:
Sorry in advance for the essay, but hopefully the info will be worth the read...
lldb has two ways of looking at variables(*): print and frame variable.
print isn't really meant primarily for printing variables - that's just a side effect of what it really does. print is an alias for expression which gives you a little more sense of what it is: a full expression evaluator which runs the expression you pass at the point where you are stopped in your code.
It builds a context that emulates the code at the current pc (including the Class/Protocol context) and then takes the snippet you pass it, compiles it in that context, JIT's the result, inserts the JIT'ed code into the process you are debugging and runs it. That's quite powerful - you can change values, call functions in your program, introduce new functions, new types, etc. But there is also a lot of machinery just to get it going, and with swift some of this machinery is tricky to get right.
frame variable can only print locals and arguments in the current frame (with the -g flag it can also print globals & statics). It can't call functions, or any of the other fancy things print can do. It does understand a limited subset of the variable access syntax, so:
(lldb) frame variable foo.bar.baz
will work. But under the covers, all it needs to do is read the debug information to find the variable, its type, and where it is in memory, and then it can extract the value from that information. So it is faster and more robust for what it does do - which is a large percentage of the work people generally ask print to do.
Note, you can get "object printing" for variables you access with frame variable by using the -O flag, and it supports the same formatting options for results as print. For context, the Xcode "Locals" view is roughly equivalent to calling frame variable.
I tend to use frame variable for simple locals printing, but even if you like to use one command for all your needs - which will be print - it's good to know that there's a fallback if print is failing for some reason.
Back to your examples...
Example 1: one of the things print does in Swift is introduce all the visible local variables into the context of the expression, so they are available to your code. The error in Example 1 is because one of the local variables couldn't be realized - maybe it was a only specified by a protocol conformance and we couldn't figure out what it really was - so we failed building the context, which means the parse or JIT steps failed. The print code does a pre-scan for this sort of failure and omits failing locals, but you've found a case this scan misses.
frame variable would have probably also failed to print runOnce but since it doesn't depend on the current context, the inability to do that wouldn't have affected your ability to print other variables.
If you can reproduce this issue, even if you can't make the project available to us we can often figure out what's going on from lldb's debugging log. So drive the debug session to the point where the print is going to fail, and do:
(lldb) log enable -f /tmp/lldb-log.txt lldb expr types
then run the failing expression. Then grab that log, and file a bug as described here:
https://swift.org/contributing/#reporting-bugs
Example 2: Was activeNetworkRequests a property? Those require us to call the "get" method to access them, and I have seen a few cases where lldb doesn't emit the code to call the property getters correctly. The log above will show us the code that was emitted, and we might be able to tell from there what went wrong. Of course, if you can make a test case you can send with the bug that is always best, but that's often not possible...
(*)For gdb users this is pretty close to the info locals vrs. print...
The following link says that read is a syscall:
What is the difference between read() and fread()?
Now, I am trying to understand what makes read a system call.
For example:
I use Nuttx OS and registered a device structure flash_dev (path '/dev/flash0') with open, close and ioctl methods. This is added as a inode in pesudo file system with semaphore support for mutual exclusion.
Now, from application I open ('/dev/flash0') and do read & ioctls.
Now, which part in the above process makes read a syscall?
The read() function is a thin wrapper around whatever instructions are necessary to call into the system, IOW, to make a system call. When you call read() (and fread() call it as well), the relevant kernel/driver code gets invoked and does whatever is necessary to read from a file.
A system call is a call whose functionality lives almost entirely in the kernel rather than in user space. Traditionally, open(), read(), write(), etc, are in the kernel whereas fread(), fwrite(), etc, have code that runs in user space that calls into the kernel as needed.
For example, in Linux when you call read() the standard library your application linked against might do the following:
mov eax, 3 ;3 -> read
mov ebx, 2 ;file id
mov ecx, buffer
mov edx, 5 ;5 bytes
int 80h
That's it - it simply takes the parameters you passed in and invokes the kernel via the int 80h (interrupt) instruction. As an application programmer, it's not usually important whether the call runs in user space, in the kernel, or both. It can be important for debugging or performance reasons, but for simple applications it really doesn't matter much.
I wanted to analyse the execution of my code using trace, and hence I entered
(trace oddp)
into the REPL. In contrast to what I expected I got an error message telling me:
** - Continuable Error
TRACE(ODDP): #<PACKAGE COMMON-LISP> is locked
If you continue (by typing 'continue'): Ignore the lock and proceed
What exactly does this mean, why does it happen, and is it safe to proceed by ignoring the lock?
TRACE works by redefining the function to something that prints the trace messages and then calls the original function. But you're not normally allowed to redefine built-in functions, so you get this error.
Is there way to tell WinDbg to ignore program breakpoints like caused by DebugBreak function?
Have a look at the Controlling Exceptions and Events page on MSDN. It explains how to use the sx* commands to break, ignore, or print exceptions/events as they happen.
What you are looking for is probably:
sxn bpe
This tells the debugger to print a message without breaking when a breakpoint exception (0x80000003) occurs.
Typical debugger output looks like:
(b70.11fc): Break instruction exception - code 80000003 (first chance)