Skip to content

Commit ab5d38d

Browse files
committed
Add script for debugging Cygwin tests from WSL shell using TTD and WinDbg
1 parent 0b86b5f commit ab5d38d

File tree

1 file changed

+243
-0
lines changed

1 file changed

+243
-0
lines changed

tools/debug-cygwin.sh

Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
#!/bin/bash
2+
3+
# Script to launch TTD (Time Travel Debugging) session using WinDbgX from WSL.
4+
5+
source `dirname ${BASH_SOURCE[0]}`/../.github/scripts/config.sh
6+
7+
find_windbgx() {
8+
echo `which WinDbgX.exe`
9+
}
10+
11+
find_ttd_engine() {
12+
echo `which TTD.exe`
13+
}
14+
15+
path_to_windows() {
16+
wslpath -w "$1"
17+
}
18+
19+
show_help() {
20+
echo "Usage: $0 [options] <executable> [executable_args]"
21+
echo ""
22+
echo "Options:"
23+
echo " -h, --help Show this help message"
24+
echo " -o, --output <file> Specify output .run file for TTD recording"
25+
echo " -w, --windbg <path> Specify WinDbgX path (optional)"
26+
echo " -t, --ttd <path> Specify TTD engine path (optional)"
27+
echo " -d, --debug Directly debug the executable (optional)"
28+
echo " -c, --collect Launch TDD recording (optional)"
29+
echo " -l, --launch Launch WinDbgX immediately after recording (optional)"
30+
echo " --child <id> Launch WinDbgx session for child process recording (optional)"
31+
echo " -f, --folder <path> Specify folder to copy binary and cygwin1.dll (optional)"
32+
echo ""
33+
echo "Example:"
34+
echo " $0 -o myrecording.run -c -l ltp/fork01 arg1 arg2"
35+
}
36+
37+
DEBUG=0
38+
COLLECT=0
39+
LAUNCH=0
40+
OUTPUT_FILE=""
41+
EXECUTABLE_NAME=""
42+
EXECUTABLE_DIR=""
43+
EXECUTABLE=""
44+
EXECUTABLE_ARGS=""
45+
WINDBGX_PATH=""
46+
TTD_ENGINE=""
47+
COPY_FOLDER=""
48+
CHILD=0
49+
CHILD_ID="01"
50+
WSL_DISTRO=Ubuntu-24.04
51+
52+
while [[ $# -gt 0 ]]; do
53+
case $1 in
54+
-h|--help)
55+
show_help
56+
exit 0
57+
;;
58+
-o|--output)
59+
OUTPUT_FILE="$2"
60+
shift 2
61+
;;
62+
-w|--windbg)
63+
WINDBGX_PATH="$2"
64+
shift 2
65+
;;
66+
-t|--ttd)
67+
TTD_ENGINE="$2"
68+
shift 2
69+
;;
70+
-d|--debug)
71+
DEBUG=1
72+
shift
73+
;;
74+
-c|--collect)
75+
COLLECT=1
76+
shift
77+
;;
78+
-l|--launch)
79+
LAUNCH=1
80+
shift
81+
;;
82+
--child)
83+
CHILD=1
84+
CHILD_ID="$2"
85+
shift 2
86+
;;
87+
-f|--folder)
88+
COPY_FOLDER="$2"
89+
shift 2
90+
;;
91+
-*)
92+
echo "Error: Unknown option $1"
93+
show_help
94+
exit 1
95+
;;
96+
*)
97+
EXECUTABLE_NAME="$1"
98+
EXECUTABLE_DIR=$(dirname "$BUILD_PATH/cygwin/$TARGET/winsup/testsuite/winsup.api/$EXECUTABLE_NAME.exe")
99+
EXECUTABLE_NAME=$(basename "$EXECUTABLE_NAME")
100+
EXECUTABLE="$EXECUTABLE_DIR/$EXECUTABLE_NAME.exe"
101+
shift
102+
EXECUTABLE_ARGS="$@"
103+
break
104+
;;
105+
esac
106+
done
107+
108+
# Check if debugging and recording and launching are not both enabled.
109+
if [ $DEBUG -eq 1 ] && [ $COLLECT -eq 1 ]; then
110+
echo "Error: Cannot debug and collect at the same time."
111+
exit 1
112+
fi
113+
if [ $DEBUG -eq 1 ] && [ $LAUNCH -eq 1 ]; then
114+
echo "Error: Cannot debug and launch at the same time."
115+
exit 1
116+
fi
117+
118+
# Check for debugged executable.
119+
if [ -z "$EXECUTABLE_NAME" ]; then
120+
echo "Error: No executable specified"
121+
show_help
122+
exit 1
123+
fi
124+
125+
# Find TTD engine if not specified.
126+
if [ -z "$TTD_ENGINE" ]; then
127+
TTD_ENGINE=$(find_ttd_engine "$WINDBGX_PATH")
128+
if [ -z "$TTD_ENGINE" ]; then
129+
echo "Error: TTD engine not found. Please specify path using -t option."
130+
exit 1
131+
fi
132+
echo "Using TTD engine: $TTD_ENGINE"
133+
fi
134+
135+
# Find WinDbgX if not specified.
136+
if [ -z "$WINDBGX_PATH" ]; then
137+
WINDBGX_PATH=$(find_windbgx)
138+
if [ -z "$WINDBGX_PATH" ]; then
139+
echo "Error: WinDbgX not found. Please specify path using -w option."
140+
exit 1
141+
fi
142+
echo "Using WinDbgX: $WINDBGX_PATH"
143+
fi
144+
145+
# If a copy folder is specified, copy the binary and cygwin1.dll to that folder.
146+
if [ -n "$COPY_FOLDER" ]; then
147+
mkdir -p "$COPY_FOLDER"
148+
149+
if [ $DEBUG -eq 1 ] || [ $COLLECT -eq 1 ]; then
150+
rm -rf "$COPY_FOLDER/$EXECUTABLE_NAME.exe" "$COPY_FOLDER/cygwin1.dll"
151+
152+
rm -rf $COPY_FOLDER/*.out \
153+
$COPY_FOLDER/*.run \
154+
$COPY_FOLDER/*.idx \
155+
$COPY_FOLDER/*.old
156+
157+
cp "$EXECUTABLE" "$COPY_FOLDER"
158+
cp "$BUILD_PATH/cygwin/$TARGET/winsup/testsuite/testinst/bin/cygwin1.dll" "$COPY_FOLDER"
159+
sleep 1
160+
fi
161+
162+
EXECUTABLE="$COPY_FOLDER/$EXECUTABLE_NAME.exe"
163+
EXECUTABLE_DIR=$COPY_FOLDER
164+
fi
165+
166+
# Generate output filename if not specified.
167+
if [ -z "$OUTPUT_FILE" ]; then
168+
OUTPUT_FILE="$EXECUTABLE_DIR/$EXECUTABLE_NAME.run"
169+
fi
170+
LOG_FILE="$EXECUTABLE_DIR/$EXECUTABLE_NAME.out"
171+
172+
# Convert paths to Windows format.
173+
WIN_EXECUTABLE=$(wslpath -w "$EXECUTABLE")
174+
WIN_EXECUTABLE_DIR=$(wslpath -w "$EXECUTABLE_DIR")
175+
WIN_OUTPUT_FILE=$(wslpath -w "$OUTPUT_FILE")
176+
WIN_TTD_ENGINE=$(wslpath -w "$TTD_ENGINE")
177+
WIN_SOURCE_PATH=$(wslpath -w "$SOURCE_PATH/cygwin")
178+
WIN_SOURCE_PATH="W:\\${WIN_SOURCE_PATH#\\\\wsl.localhost\\$WSL_DISTRO\\}"
179+
180+
if [ $COLLECT -eq 1 ]; then
181+
# Run the TTD recording with elevated privileges
182+
echo "Starting TTD recording for: $EXECUTABLE"
183+
echo "Recording will be saved to: $OUTPUT_FILE"
184+
echo "Log will be saved to: $LOG_FILE"
185+
powershell.exe "Set-Location -Path $WIN_EXECUTABLE_DIR; Start-Process -Wait -Verb RunAs -FilePath $WIN_TTD_ENGINE -ArgumentList \"-out $WIN_OUTPUT_FILE -noUI -children $WIN_EXECUTABLE $EXECUTABLE_ARGS\"; exit \$LASTEXITCODE"
186+
187+
TTD_RESULT=$?
188+
if [ $TTD_RESULT -ne 0 ]; then
189+
echo "Error: TTD recording failed with exit code $TTD_RESULT"
190+
exit $TTD_RESULT
191+
fi
192+
193+
if [ -f "$LOG_FILE" ]; then
194+
echo "Parent recording log:"
195+
cat "$LOG_FILE"
196+
fi
197+
198+
if [ $CHILD -eq 1 ]; then
199+
echo "Child $CHILD_ID recording log:"
200+
cat "${LOG_FILE%.out}$CHILD_ID.out"
201+
fi
202+
203+
if [ ! -f "$OUTPUT_FILE" ]; then
204+
echo "Error: TTD output file $OUTPUT_FILE has not been created."
205+
exit 1
206+
fi
207+
208+
echo "TTD recording complete: $OUTPUT_FILE"
209+
fi
210+
211+
# Launch WinDbgX if requested
212+
if [ $LAUNCH -eq 1 ] || [ $DEBUG -eq 1 ]; then
213+
if [ $LAUNCH -eq 1 ]; then
214+
if [ ! -f "$OUTPUT_FILE" ]; then
215+
echo "Error: Output file $OUTPUT_FILE does not exist. Please run TTD recording first."
216+
exit 1
217+
fi
218+
219+
if [ $CHILD -eq 1 ]; then
220+
WIN_OUTPUT_FILE="${WIN_OUTPUT_FILE%.run}$CHILD_ID.run"
221+
fi
222+
fi
223+
224+
# Add any WinDbg commands here
225+
cat <<EOF > $EXECUTABLE_DIR/script
226+
bm main
227+
g
228+
EOF
229+
230+
if ! command -v unix2dos &> /dev/null; then
231+
echo "unix2dos command not found, installing..."
232+
sudo apt install -y dos2unix
233+
fi
234+
unix2dos $EXECUTABLE_DIR/script
235+
236+
if [ $DEBUG -eq 1 ]; then
237+
echo "Launching WinDbgX in debug mode..."
238+
"$WINDBGX_PATH" -lsrcpath $WIN_SOURCE_PATH -c "$<$WIN_EXECUTABLE_DIR\\script" "$WIN_EXECUTABLE"
239+
else
240+
echo "Launching WinDbgX with recording..."
241+
"$WINDBGX_PATH" -z "$WIN_OUTPUT_FILE" -lsrcpath $WIN_SOURCE_PATH -c "$<$WIN_EXECUTABLE_DIR\\script"
242+
fi
243+
fi

0 commit comments

Comments
 (0)