← Design Verification Interviews
Interview Question · Debug
A Simulation That Died in the C Model
The Question
The interviewer asks
A test dies with this output. The log file is empty, so even the scoreboard message printed before the call is missing. Read the backtrace: what is the cause, and what do you do next?
$ ./obj/Vtb > sim.log
Segmentation fault
$ wc -l sim.log
0 sim.log
$ gdb -batch -ex run -ex bt ./obj/Vtb
Program received signal SIGSEGV, Segmentation fault.
model_predict (h=0x0, data=7) at ../model.cpp:6
6 m->count++;
#0 model_predict (h=0x0, data=7) at ../model.cpp:6
#1 Vtb_tb____Vdpiimwrap_model_predict_TOP__tb (h=<optimized out>, data=7, ...) at Vtb_tb__0.cpp:17
#2 Vtb_tb__03a__03ascoreboard::__VnoInFunc_write (this=0x555555593d30, ..., data=7)
at Vtb_tb__03a__03ascoreboard__Vclpkg__0.cpp:16
#3 Vtb_tb___eval_initial__TOP__tb__Vtiming__0 (frame_ptr=0x555555593d70) ...
#4 VlCoroutineHandle::resume (...) at verilated_timing.cpp:45
#5 VlDelayScheduler::resume (...) at verilated_timing.cpp:75
...
#12 main (...) at Vtb__main.cpp:22You have two and a half minutes. Speak or type, then press Get Feedback under your answer. No credits needed.
Speech-to-text runs in your browser. Chrome and Edge may send audio to their own speech service.
You can edit your answer before you send it. Feedback uses AI and checks your answer only against our written answer. No credits are used and your answer is not saved.
Reveal the Model Answer
Frame #0 is the C model, model_predict, with h=0x0. Frame #2 shows the scoreboard's write made the call through the DPI wrapper. So the scoreboard's chandle was never set: nothing called model_new before the first prediction. The empty log is stdout buffering, because the process died before it flushed. Fix the build order, and make the C return a status for a null handle.
Self-Check
Tick each key point you covered in your answer.
What Interviewers Listen For (Mid-Level)
Reads frame #0 first, spots h=0x0, and follows the frames down to the scoreboard call.
What Interviewers Listen For (Senior)
Explains the empty log as buffering, and adds a null check that turns the next crash into a reported error.
Cross-Questions
Where the interviewer goes next. Open a node to practise that follow-up.
WhyProve ItCompareScale It
- A Simulation That Died in the C Model
-
WhyWhy the Log Lost Its Last LinesL2 Mid-Level
Why did the
$displaythat ran just before the crash never reach the log?2:30You have two and a half minutes. Speak or type, then press Get Feedback under your answer. No credits needed.
Speech-to-text runs in your browser. Chrome and Edge may send audio to their own speech service.
You can edit your answer before you send it. Feedback uses AI and checks your answer only against our written answer. No credits are used and your answer is not saved.
Reveal the Model Answer
When output goes to a file or a pipe, the C library collects it in a buffer. It writes the buffer in large blocks. A segmentation fault kills the process before that buffer is flushed. Our probe showed the line once
$fflush()ran before the risky call. Running under gdb also avoids guessing, because it stops at the crash.Self-Check
Tick each key point you covered in your answer.
Half-Truth
"Add more
$displaylines to find where it dies."Those lines sit in the same buffer and are lost the same way. More prints can even move the point where the buffer happens to flush.
-
Prove ItGetting a Backtrace from a Crashed RunL2 Mid-Level
Prove it: how do you get that backtrace from a failing regression run?
2:30You have two and a half minutes. Speak or type, then press Get Feedback under your answer. No credits needed.
Speech-to-text runs in your browser. Chrome and Edge may send audio to their own speech service.
You can edit your answer before you send it. Feedback uses AI and checks your answer only against our written answer. No credits are used and your answer is not saved.
Reveal the Model Answer
Build the C model with
-g, so frames show file and line. Rerun the failing seed under gdb withrunthenbt. Or allow core files withulimit -c unlimited, and open the core withgdb ./obj/Vtb core. Read frame #0 first, then walk down to the first frame in your own code.Self-Check
Tick each key point you covered in your answer.
Half-Truth
"Without debug symbols, the backtrace is useless."
It still names the function in frame #0, which often finds the bug. Symbols add the file, the line and the argument values.
-
Scale ItA DPI Crash That Only Happens on the FarmL3 Senior
What if the crash happens on the compute farm but never on your machine?
2:30You have two and a half minutes. Speak or type, then press Get Feedback under your answer. No credits needed.
Speech-to-text runs in your browser. Chrome and Edge may send audio to their own speech service.
You can edit your answer before you send it. Feedback uses AI and checks your answer only against our written answer. No credits are used and your answer is not saved.
Reveal the Model Answer
Suspect undefined behaviour in the C: an uninitialised variable, a stale pointer or a read past an array. It shows up only with certain compilers, flags or memory layouts. Reproduce with the farm's exact build flags and seed, then run an AddressSanitizer build. It reports the bad access where it happens, not where it later crashes.
Self-Check
Tick each key point you covered in your answer.
What Interviewers Listen For (Senior)
Looks for undefined behaviour first and copies the farm build exactly before debugging.
Tool as Truth
"It works on my machine, so the farm is broken."
Undefined behaviour can look correct on one build and crash on another. Your machine passing is not evidence that the C is right.
Source Measured on a local Verilator 5.052 build with g++, 2026-11-08 (AddressSanitizer build of the crashing model reported the faulting line and caller chain)
-
CompareStatus Codes Compared with Aborting in CL2 Mid-Level
Compare a C model that returns a status code on bad input with one that calls
abort()orexit().2:30You have two and a half minutes. Speak or type, then press Get Feedback under your answer. No credits needed.
Speech-to-text runs in your browser. Chrome and Edge may send audio to their own speech service.
You can edit your answer before you send it. Feedback uses AI and checks your answer only against our written answer. No credits are used and your answer is not saved.
Reveal the Model Answer
A status lets SystemVerilog report the error through the normal error path, with the time, the transaction and the test name. The run then ends cleanly, and its final blocks and end-of-test reports still run. An abort kills the process at once and skips all of that. So C returns a status, and SystemVerilog decides how bad it is.
Self-Check
Tick each key point you covered in your answer.
Misconception
"Throw a C++ exception; the simulator will report it."
An exception must not cross the DPI boundary. The behaviour is undefined, and in practice the process usually ends with no report.
Source IEEE 1800-2017 §35.5.1 (semantic constraints on imported routines); lesson D1.2 review claims
What People Get Wrong
Common wrong answers and why they fail. Run It shows the wrong belief failing on a real simulator.
Misconception
"SystemVerilog stops a null chandle before the call."
A null chandle is a legal value to pass. The simulator hands it to C as a null pointer, and C must check it.
Run It
The scoreboard's build() lost its model_new() call. The C checks for null and reports a status.
FAIL: the null chandle went straight to C; only the C null check prevented a crashSee the Fix
module tb;
import "DPI-C" function chandle model_new();
import "DPI-C" function int model_predict(input chandle h, input int data, output int status);
class scoreboard;
chandle model;
function void build();
model = model_new(); // the fix: create the model before any prediction
endfunction
function int write(int data);
int st, e;
e = model_predict(model, data, st);
return st;
endfunction
endclass
scoreboard sb = new;
initial begin
sb.build();
// The belief: SystemVerilog stops a null chandle before it reaches C.
if (sb.write(7) != 0) $display("FAIL: the null chandle went straight to C; only the C null check prevented a crash");
else $display("PASS: the model was created in build, so C received a real handle");
$finish;
end
endmodule
Prints: PASS: the model was created in build, so C received a real handle
Missed Corner
"The last line in the log shows how far the test got."
Output to a file or pipe sits in a buffer. A crash throws the buffer away, so the last lines before it are missing.
Source Measured on a local Verilator 5.052 build with g++, 2026-11-08 (a $display just before the crash was lost when output went to a file; $fflush() before the call kept it)
Half-Truth
"Most frames are inside Verilator, so it is a simulator bug."
Frame #0 is where the crash happened, and it is model.cpp. The Verilator frames below it are only the chain of callers.