Posts

Post not yet marked as solved
1 Replies
1.6k Views
I want to do source level debugging of an external environment using Xcode's graphical debugger. I have an External Build System project with local source files that builds libraries/executables (not macOS or iOS) and creates their dSYM symbol files (also stored locally). I have a script that I can run from Xcode that starts the library/executables (in an external environment), and gets their slide addresses so their symbols can be loaded into lldb. The script also returns a gdb-remote url that I can use with lldb to begin debugging. Is there a way for Xcode to use the lldb info gathered by my script to start its graphical debugger? If this feature doesn't exist, then I see two simple ways that this feature could be implemented: a) In the Run Action, there's a Run Script action in the Pre-actions to start the remote environment and gather the debug info to create a lldb script that has the gdb-remote command, and commands to add the target modules, and to load the target modules with their slide values. All of that I've already implemented. The Run Action can then have an option to launch lldb with the generated lldb source script. b) The Run Script action in the Pre-actions of the Run Action that sets up the external environment and gathers the debug info can launch lldb itself with the generated lldb source script. The Run Action can have an option to watch the terminal output for an lldb prompt and then take over when the prompt appears.
Posted
by joevt.
Last updated
.
Post not yet marked as solved
1 Replies
644 Views
I've used DB_KPRT to send IOLog, printf, and kprintf messages over serial port (115200 baud) to another Mac. If I try to do the same with FireWire, it appears that only kprintf messages are sent. Is there a boot arg that can change that? If not then what would have to be changed in xnu? A global variable or function or something? Is there another connection type such as USB or Ethernet that can send IOLog like the serial port can?
Posted
by joevt.
Last updated
.
Post not yet marked as solved
0 Replies
657 Views
I am playing with IOI2CSendRequest and found a couple things I cannot do with it: E-DDC read of EDIDs that are longer than 256 bytes. This requires a transaction with two sends (one for the segment pointer and one for the offset) with a start bit before each and then the reply preceded by a start bit and ended by a stop bit. IOI2CSendRequest can only do one send and one reply in a single transaction. The E-DDC transaction cannot be split because a second transaction would add an extra stop bit which would reset the segment pointer. A transaction without the offset part works with the GTX 680 or Intel UHD 630 but not with the AMD W5700. DisplayPort DPCD read from DisplayPort device connected to a DisplayPort branch device. This requires a send to the sideband message down request buffer and a reply from the sideband message down reply buffer. This cannot be done with a single IOI2CSendRequest send and reply because the reply is not immediate. I don't think the reply can be polled because I think that is handled by a DisplayPort interrupt and the reply is probably read by the GPU driver and not passed to the user client. Is there a special way to setup the IOI2CRequest to do the above? In the E-DDC case, the i2c handler could maybe suppress the stop bit of the first send after it recognizes that the send is for the segment pointer. In the DisplayPort sideband case, the i2c handler could recognize that the user client wants to get a reply from a sideband message by examining the request sent in the contents of the DisplayPort send buffer, and should therefore queue up the request and wait for the reply. What about M1 Macs? I understand there are some undocumented APIs that people are using to do DDC/CI (MCCS) or to read the EDID but I don't know if they can get more than 256 bytes of the EDID.
Posted
by joevt.
Last updated
.
Post not yet marked as solved
4 Replies
1.1k Views
I think I've found a strange behavior which is easy to reproduce (running macOS 10.15.4):I have a kext which simply attaches to an IOService in the IO Registry.My function start is like this:bool MyAIC::start( IOService * provider ) { IOLog("[ MyAIC::start11\n"); bool result = super::start( provider ); IOLog("] MyAIC::start\n"); return result; }I update the number in the first IOLog after each update to make sure I know the correct code is working. It says "start11" now and will be "start12" next time.I use the following to log output in Terminal.app:log stream -style compact --info --predicate "message contains 'MyAIC'"I use the following install script to load a new version of the kext after building in Xcode:cd /Volumes/Work/Programming/MyProjects/MyAIC kextidentifier="com.joevt.driver.MyAIC" kextname="MyAIC.kext" kextsrcdir="DerivedData/MyAIC/Build/Products/Debug" kexttmpdir="$(mktemp -d)" kextinstalldir=/Library/Extensions while ( kextstat | grep "$kextidentifier" ); do sleep 1 sudo kextunload -b "$kextidentifier" done sudo cp -p -R "$kextsrcdir/$kextname" "$kexttmpdir/" sudo chown -R root:wheel "$kexttmpdir/$kextname" sudo find "$kexttmpdir/$kextname" -type d -exec /bin/chmod 0755 {} \; sudo find "$kexttmpdir/$kextname" -type f -exec /bin/chmod 0644 {} \; sudo kextutil "$kexttmpdir/$kextname" kextstat | grep "$kextidentifier" echo "done"After running the install script, the log in Terminal.app shows:2020-05-21 00:09:11.879 E kernel[0:d7a8] (MyAIC) [ MyAIC::start11I use the following to check the code was compiled and copied properly:strings "$kextsrcdir/$kextname/Contents/macOS/"* | egrep 'start[0-9]' strings "$kexttmpdir/$kextname/Contents/macOS/"* | egrep 'start[0-9]'The result after the first time installing is:[ MyAIC::start11 [ MyAIC::start11 [ MyAIC::start11 [ MyAIC::start11Now, while the log stream is still running in Terminal.app, I update the code and rebuild the kext so the log should show "start12". I execute the install script, but Terminal.app shows "start11" which means the kext was loaded from some copy located who knows where? I can repeat the install script multiple times and each time it shows "start11". I use the strings command to check that the code contains the "start12" string.I have to stop and start the "log" in Terminal.app, then the next execution of the install script will show "start12". How does this make sense? What does "log" have to do with "kextutil"? Also, I have to stop and start the "log" after executing at least once the install script with the new kext. That means it takes two installs to get the new code to work.Is there a command I can add to my install script to make it load the latest version of my kext properly?Ok, now for something even more strange:I have a macro for IOLog like this in my code:#define IOLog(...) os_log_error(OS_LOG_DEFAULT, __VA_ARGS__)If I change the macro to use os_log instead of os_log_error, and I increase the start number, then build, then install, the log shows the old start number but shows Df for default instead of E for error. So it will pick up the change in the function call but not in the string text? Are the code and data sections handled (cached) differently?
Posted
by joevt.
Last updated
.